third commit

This commit is contained in:
2026-07-31 17:06:52 +05:30
parent d9886880cc
commit 9891a69a5f
32 changed files with 2083 additions and 557 deletions

View File

@@ -74,11 +74,31 @@ class PaymentController extends StateNotifier<PaymentState> {
return diff > 0 ? diff.asMoney : 0;
}
/// Whether Complete Sale should be enabled.
///
/// Cash is the strict case: the drawer cannot be reconciled and no change can
/// be calculated unless the cashier states what was handed over. Card, UPI
/// and wallet settle on the external terminal, so they need no amount here.
bool get canConfirm {
if (_billTotal <= 0) return false;
// Staged splits already cover the bill.
if (balanceDue <= 0.01) return true;
if (state.activeMethod.needsChange) {
return state.cashTendered >= balanceDue && balanceDue > 0;
return state.cashTendered >= balanceDue;
}
return balanceDue > 0;
return true;
}
/// Why the button is disabled, for display next to it.
String? get blockedReason {
if (_billTotal <= 0) return 'Add at least one item before charging.';
if (canConfirm) return null;
if (state.activeMethod.needsChange) {
return 'Enter the cash received, or tap Exact.';
}
return null;
}
void selectMethod(PaymentMethod method) {
@@ -156,10 +176,10 @@ class PaymentController extends StateNotifier<PaymentState> {
state = state.copyWith(isProcessing: false, result: result);
// Fire and forget — printing must never block the next sale.
final receipts = _ref.read(receiptServiceProvider);
unawaited(receipts.printDirect(result.transaction));
unawaited(receipts.openCashDrawer());
// No auto-print: with no roll printer attached this silently failed and
// looked like a bug. The receipt screen shows the bill on the terminal
// and offers Print, WhatsApp and Share explicitly.
unawaited(_ref.read(receiptServiceProvider).openCashDrawer());
unawaited(_ref.read(soundServiceProvider).saleComplete());
// Stock changed, so the grid must refresh; the new order changes the