On a sale's detail page, unpaid sales (retail or restaurant) can now be cancelled or deleted: - Cancel (pending only) marks it cancelled and frees its table / clears it from the kitchen (PosSaleService::cancelSale). - Delete removes the sale and cascades its lines, modifiers and payments, freeing the table first (deleteSale). Paid sales are protected — they can't be deleted. Status badge now distinguishes cancelled/failed. Covered by PosRestaurantTest. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
5d8e185223
commit
f64a28cb21
@@ -268,6 +268,38 @@ class PosRestaurantTest extends TestCase
|
||||
$this->assertSame('retail', PosLocation::owned($user->public_id)->first()->service_style);
|
||||
}
|
||||
|
||||
public function test_pending_ticket_can_be_cancelled_then_deleted(): void
|
||||
{
|
||||
$user = $this->user();
|
||||
[, $table, $product] = $this->restaurant($user);
|
||||
|
||||
$this->actingAs($user)->post(route('pos.tickets.open'), ['order_type' => 'dine_in', 'table_id' => $table->id])->assertRedirect();
|
||||
$sale = PosSale::where('owner_ref', $user->public_id)->firstOrFail();
|
||||
$this->actingAs($user)->postJson(route('pos.tickets.lines.add', $sale), ['product_id' => $product->id, 'quantity' => 1])->assertOk();
|
||||
|
||||
// Cancel — frees the table.
|
||||
$this->actingAs($user)->post(route('pos.sales.cancel', $sale))->assertRedirect(route('pos.sales.show', $sale));
|
||||
$this->assertSame(PosSale::STATUS_CANCELLED, $sale->fresh()->status);
|
||||
$this->assertSame(PosTable::STATUS_FREE, $table->fresh()->status);
|
||||
|
||||
// Delete — gone (cascades lines).
|
||||
$this->actingAs($user)->delete(route('pos.sales.destroy', $sale))->assertRedirect(route('pos.sales.index'));
|
||||
$this->assertNull(PosSale::find($sale->id));
|
||||
$this->assertSame(0, $sale->lines()->count());
|
||||
}
|
||||
|
||||
public function test_paid_sale_cannot_be_deleted(): void
|
||||
{
|
||||
$user = $this->user();
|
||||
$sale = PosSale::create([
|
||||
'owner_ref' => $user->public_id, 'reference' => 'POS-PAID1', 'status' => PosSale::STATUS_PAID,
|
||||
'payment_method' => 'cash', 'subtotal_minor' => 1000, 'total_minor' => 1000, 'currency' => 'GHS', 'paid_at' => now(),
|
||||
]);
|
||||
|
||||
$this->actingAs($user)->delete(route('pos.sales.destroy', $sale));
|
||||
$this->assertNotNull(PosSale::find($sale->id));
|
||||
}
|
||||
|
||||
public function test_cannot_open_two_tabs_on_one_table(): void
|
||||
{
|
||||
$user = $this->user();
|
||||
|
||||
Reference in New Issue
Block a user