feat: add alot
This commit is contained in:
@@ -1,80 +1,60 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
import '../models/app_error.dart';
|
||||
import '../models/product.dart';
|
||||
import '../services/product_service.dart';
|
||||
|
||||
/// The app-wide product list, kept in sync with the database. Stock changes
|
||||
/// from tabs show up here automatically.
|
||||
class InventoryViewModel extends ChangeNotifier {
|
||||
final ProductService productService;
|
||||
|
||||
InventoryViewModel({required this.productService});
|
||||
|
||||
StreamSubscription<List<Product>>? _subscription;
|
||||
List<Product> _products = [];
|
||||
bool _hasLoaded = false;
|
||||
AppError? _loadError;
|
||||
|
||||
List<Product> get products => _products;
|
||||
|
||||
Future<void> load() async {
|
||||
try {
|
||||
_products = await productService.getProducts();
|
||||
notifyListeners();
|
||||
} catch (e, stack) {
|
||||
debugPrint('InventoryViewModel: load error: $e');
|
||||
Sentry.captureException(e, stackTrace: stack);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
bool get hasLoaded => _hasLoaded;
|
||||
|
||||
Future<void> decreaseStock(String productId, int amount) async {
|
||||
try {
|
||||
await productService.decreaseStock(productId, amount);
|
||||
bool get isLoading => !_hasLoaded;
|
||||
|
||||
final index = _products.indexWhere((product) => product.id == productId);
|
||||
AppError? get loadError => _loadError;
|
||||
|
||||
if (index != -1) {
|
||||
_products[index] = _products[index].copyWith(
|
||||
stockQuantity: _products[index].stockQuantity - amount,
|
||||
);
|
||||
}
|
||||
void ensureLoaded() {
|
||||
if (_subscription != null) return;
|
||||
|
||||
notifyListeners();
|
||||
} catch (e, stack) {
|
||||
if (e is InsufficientStockException) rethrow;
|
||||
|
||||
debugPrint('InventoryViewModel: decreaseStock error: $e');
|
||||
Sentry.captureException(e, stackTrace: stack);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> increaseStock(String productId, int amount) async {
|
||||
try {
|
||||
await productService.increaseStock(productId, amount);
|
||||
|
||||
final index = _products.indexWhere((product) => product.id == productId);
|
||||
|
||||
if (index != -1) {
|
||||
_products[index] = _products[index].copyWith(
|
||||
stockQuantity: _products[index].stockQuantity + amount,
|
||||
);
|
||||
}
|
||||
|
||||
notifyListeners();
|
||||
} catch (e, stack) {
|
||||
debugPrint('InventoryViewModel: increaseStock error: $e');
|
||||
Sentry.captureException(e, stackTrace: stack);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
void applyStockDelta(String productId, int delta) {
|
||||
if (delta == 0) return;
|
||||
|
||||
final index = _products.indexWhere((product) => product.id == productId);
|
||||
if (index == -1) return;
|
||||
|
||||
_products[index] = _products[index].copyWith(
|
||||
stockQuantity: _products[index].stockQuantity + delta,
|
||||
_subscription = productService.watchProducts().listen(
|
||||
_onProducts,
|
||||
onError: _onLoadError,
|
||||
);
|
||||
}
|
||||
|
||||
void _onProducts(List<Product> products) {
|
||||
_products = products;
|
||||
_hasLoaded = true;
|
||||
_loadError = null;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void _onLoadError(Object error, StackTrace stack) {
|
||||
debugPrint('InventoryViewModel: load error: $error');
|
||||
unawaited(Sentry.captureException(error, stackTrace: stack));
|
||||
|
||||
_hasLoaded = true;
|
||||
_loadError = AppError.loadProducts;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_subscription?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user