
Introduces an `isDraft` property to `StockPickingRecordEntity` to mark receptions with local modifications. Automatically sets a reception to draft status when a product's quantity is incremented via scanning. Displays a 'Brouillon' chip on reception cards to provide visual feedback for draft operations. Ensures reception details are refreshed after scanning to reflect the updated draft status and provides immediate error feedback when no product is found during a scan.
97 lines
3.3 KiB
Dart
97 lines
3.3 KiB
Dart
import 'package:e_scan/backend/objectbox/entities/product/product_entity.dart';
|
|
import 'package:e_scan/backend/objectbox/entities/stock_picking/stock_picking_record_entity.dart';
|
|
import 'package:e_scan/backend/objectbox/objectbox_manager.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
|
|
part 'reception_scan_page_model.freezed.dart';
|
|
|
|
final receptionScanPageModelProvider =
|
|
StateNotifierProvider.autoDispose<
|
|
ReceptionScanPageModel,
|
|
ReceptionScanPageModelState
|
|
>((ref) {
|
|
return ReceptionScanPageModel();
|
|
});
|
|
|
|
class ReceptionScanPageModel
|
|
extends StateNotifier<ReceptionScanPageModelState> {
|
|
ReceptionScanPageModel() : super(const ReceptionScanPageModelState());
|
|
|
|
Future getReceptionById({required int id}) async {
|
|
try {
|
|
final stockPickingRecords = objectboxManager.store
|
|
.box<StockPickingRecordEntity>();
|
|
state = state.copyWith(loading: true);
|
|
final entity = stockPickingRecords.get(id);
|
|
state = state.copyWith(loading: false, reception: entity);
|
|
} catch (e) {
|
|
state = state.copyWith(loading: false);
|
|
}
|
|
}
|
|
|
|
bool isProductExist({required String barcode}) {
|
|
final productBox = objectboxManager.store.box<ProductEntity>();
|
|
return productBox
|
|
.query(ProductEntity_.barcode.equals(barcode))
|
|
.build()
|
|
.findFirst() !=
|
|
null;
|
|
}
|
|
|
|
ProductEntity? getProduct({required String barcode}) {
|
|
final productBox = objectboxManager.store.box<ProductEntity>();
|
|
return productBox
|
|
.query(ProductEntity_.barcode.equals(barcode))
|
|
.build()
|
|
.findFirst();
|
|
}
|
|
|
|
void incrementMoveLineQuantity({
|
|
required String barcode,
|
|
required int receptionId,
|
|
}) {
|
|
final moveLineBox = objectboxManager.store
|
|
.box<MoveLineWithoutPackageEntity>();
|
|
final stockPickingRecordBox = objectboxManager.store
|
|
.box<StockPickingRecordEntity>();
|
|
final moveBox = objectboxManager.store.box<MoveWithoutPackageEntity>();
|
|
final productBox = objectboxManager.store.box<ProductEntity>();
|
|
final productEntity = productBox
|
|
.query(ProductEntity_.barcode.equals(barcode))
|
|
.build()
|
|
.findFirst();
|
|
final productId = productEntity?.id;
|
|
final stockPickingRecord = stockPickingRecordBox.get(receptionId);
|
|
if (productId != null) {
|
|
final moveLineEntity = moveLineBox
|
|
.query(MoveLineWithoutPackageEntity_.productId.equals(productId))
|
|
.build()
|
|
.findFirst();
|
|
final moveEntity = moveBox
|
|
.query(MoveWithoutPackageEntity_.productId.equals(productId))
|
|
.build()
|
|
.findFirst();
|
|
if (moveLineEntity != null &&
|
|
moveEntity != null &&
|
|
stockPickingRecord != null) {
|
|
moveLineEntity.quantity = (moveLineEntity.quantity ?? 0) + 1;
|
|
moveEntity.quantity = (moveEntity.quantity ?? 0) + 1;
|
|
stockPickingRecord.isDraft = true;
|
|
moveLineBox.put(moveLineEntity);
|
|
moveBox.put(moveEntity);
|
|
stockPickingRecordBox.put(stockPickingRecord);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@freezed
|
|
abstract class ReceptionScanPageModelState with _$ReceptionScanPageModelState {
|
|
const factory ReceptionScanPageModelState({
|
|
StockPickingRecordEntity? reception,
|
|
@Default(false) bool loading,
|
|
}) = _ReceptionScanPageModelState;
|
|
}
|