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
@@ -44,6 +44,32 @@ class SaleController extends Controller
|
||||
return view('pos.sales.show', compact('sale', 'invoiceUrl'));
|
||||
}
|
||||
|
||||
public function cancel(Request $request, PosSale $sale): RedirectResponse
|
||||
{
|
||||
$this->authorizeOwner($request, $sale);
|
||||
|
||||
try {
|
||||
$this->sales->cancelSale($sale);
|
||||
} catch (RuntimeException $e) {
|
||||
return back()->with('error', $e->getMessage());
|
||||
}
|
||||
|
||||
return redirect()->route('pos.sales.show', $sale)->with('success', 'Sale cancelled.');
|
||||
}
|
||||
|
||||
public function destroy(Request $request, PosSale $sale): RedirectResponse
|
||||
{
|
||||
$this->authorizeOwner($request, $sale);
|
||||
|
||||
try {
|
||||
$this->sales->deleteSale($sale);
|
||||
} catch (RuntimeException $e) {
|
||||
return back()->with('error', $e->getMessage());
|
||||
}
|
||||
|
||||
return redirect()->route('pos.sales.index')->with('success', 'Sale deleted.');
|
||||
}
|
||||
|
||||
public function callback(Request $request, PosSale $sale): RedirectResponse
|
||||
{
|
||||
$reference = trim((string) $request->query('reference', $sale->payment_reference ?? ''));
|
||||
|
||||
Reference in New Issue
Block a user