pos changes

This commit is contained in:
2026-08-06 19:26:53 +05:30
parent cb065a0f69
commit eebd10da6d
42 changed files with 3451 additions and 2531 deletions

View File

@@ -10,6 +10,7 @@ import '../../../core/widgets/primary_button.dart';
import '../../auth/providers/auth_controller.dart';
import '../../pos/providers/cart_controller.dart';
import '../../pos/providers/catalog_providers.dart';
import '../../pos/providers/navigation_provider.dart';
import '../../../domain/repositories/sync_repository.dart';
import '../providers/sync_controller.dart';
@@ -38,21 +39,52 @@ class _SignOutDialogState extends ConsumerState<_SignOutDialog> {
Future<void> _finish() async {
ref.read(cartControllerProvider.notifier).reset();
// Read before signing out — the session that decides this is gone by the
// time signOut returns.
final cleared =
ref.read(authControllerProvider.notifier).clearsCatalogueOnSignOut;
await ref.read(authControllerProvider.notifier).signOut();
// Mirrors what a successful import does on the way in: bump the version
// so catalogueReadyProvider re-reads hasCatalogue as false, and drop the
// cached product lists so the next session's grid doesn't flash this
// session's now-cleared data before it re-fetches.
// Mirrors what a successful import does on the way in: bump the version so
// catalogueReadyProvider re-reads hasCatalogue, and drop the cached product
// lists so the next session's grid doesn't flash this session's data before
// it re-fetches.
//
// Run either way. After an admin sign-out the catalogue is still there and
// these simply re-read it — which is the point: the next session must see
// what is on disk now, not what this one had in memory.
ref.read(catalogueVersionProvider.notifier).state++;
ref.invalidate(allProductsProvider);
ref.invalidate(visibleProductsProvider);
ref.invalidate(categoryCountsProvider);
ref.invalidate(lowStockProductsProvider);
// The next session starts on the till, never wherever this one left off.
ref.read(activeModuleProvider.notifier).state = PosModule.pos;
ref.read(searchQueryProvider.notifier).state = '';
ref.read(selectedCategoryProvider.notifier).state = null;
if (!mounted) return;
// Resolved while this context is still mounted. The messenger itself lives
// above the router, so the bar survives the route change below.
final messenger = ScaffoldMessenger.of(context);
Navigator.of(context).pop();
context.go(AppRoutes.login);
if (cleared) {
messenger
..hideCurrentSnackBar()
..showSnackBar(const SnackBar(
content: Text(
'Signed out. The product catalogue has been removed from this '
'terminal.',
),
),);
}
}
Future<void> _pushThenFinish() async {
@@ -76,8 +108,10 @@ class _SignOutDialogState extends ConsumerState<_SignOutDialog> {
final pushing = ref.watch(orderSyncProvider) is SyncRunning;
final failed = _result != null && !_result!.isSuccess;
final cashier = ref.watch(isCashierModeProvider);
return AlertDialog(
title: const Text('End shift'),
title: Text(cashier ? 'End shift' : 'Sign out'),
contentPadding: const EdgeInsets.fromLTRB(
AppSpacing.xxl,
AppSpacing.lg,
@@ -92,6 +126,26 @@ class _SignOutDialogState extends ConsumerState<_SignOutDialog> {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// What happens to the products is the difference between the two
// sign-outs, so it is said plainly rather than left to be
// discovered at the next login.
_Banner(
icon: cashier
? Icons.delete_sweep_outlined
: Icons.inventory_2_outlined,
color: cashier ? AppColors.warning : AppColors.info,
background: cashier
? AppColors.warningSurface
: AppColors.infoSurface,
message: cashier
? 'The product catalogue will be removed from this '
'terminal. An admin imports it again for the next '
'shift.'
: 'The imported products stay on this terminal, so a '
'cashier can sign in and start billing without a '
'connection.',
),
if (cart.isNotEmpty)
_Banner(
icon: Icons.warning_amber_rounded,