feat: Implement explicit synchronization and validation

Refactors the reception process to provide clearer control over data synchronization and validation.

- Replaces the `isDraft` property with `synchronized` in `StockPickingRecordEntity` to accurately represent the local data's sync status with the backend.
- Introduces a new API endpoint and corresponding logic for `validateStockPicking`, allowing finalization of receptions.
- Splits the "Save" action into "Synchronize data" and "Validate reception" on the details page. "Validate" now implicitly performs a synchronization first.
- Updates UI elements (cards, quick actions) to reflect the new synchronization state and expose the new actions.
- Corrects a typo in the `updateAllMoveLineOnStockPicking` API method name.
- Improves local data update logic for scanned items, marking them as unsynchronized.
This commit is contained in:
your-name 2025-07-31 02:34:50 +03:00
parent 288b57d4cf
commit 18f74daae4
11 changed files with 181 additions and 74 deletions

View File

@ -324,7 +324,7 @@ class ApiCalls {
} }
} }
static Future<bool> updateAllMoveLineOnStockPiking({ static Future<bool> updateAllMoveLineOnStockPicking({
required int stockPickingId, required int stockPickingId,
required List<UpdateMoveLineDto> moveLineDto, required List<UpdateMoveLineDto> moveLineDto,
}) async { }) async {
@ -352,12 +352,43 @@ class ApiCalls {
if (response.statusCode == 200) { if (response.statusCode == 200) {
final data = response.data as Map<String, dynamic>; final data = response.data as Map<String, dynamic>;
if (data.containsKey('result')) { if (data.containsKey('result')) {
final datas = data['result'] as List; return true;
if (datas.isNotEmpty) { } else {
return true; return false;
} else { }
return false; } else {
} debugPrint('Erreur réseau: ${response.statusCode}');
return false;
}
} catch (e) {
debugPrint('Erreur lors de la requête: $e');
return false;
}
}
static Future<bool> validateStockPicking({
required int stockPickingId,
}) async {
try {
final response = await dioService.post(
path: '/web/dataset/call_kw/stock.picking/button_validate',
data: {
"jsonrpc": "2.0",
"method": "call",
"params": {
"model": "stock.picking",
"method": "button_validate",
"args": [
[stockPickingId],
],
"kwargs": {"context": {}},
},
},
);
if (response.statusCode == 200) {
final data = response.data as Map<String, dynamic>;
if (data.containsKey('result')) {
return true;
} else { } else {
return false; return false;
} }

View File

@ -5,7 +5,7 @@ import 'package:objectbox/objectbox.dart';
class StockPickingRecordEntity { class StockPickingRecordEntity {
StockPickingRecordEntity({ StockPickingRecordEntity({
this.id = 0, this.id = 0,
this.isDraft = false, this.synchronized = true,
this.priority, this.priority,
this.name, this.name,
this.pickingTypeCode, this.pickingTypeCode,
@ -29,7 +29,7 @@ class StockPickingRecordEntity {
}); });
@Id(assignable: true) @Id(assignable: true)
int id; int id;
bool isDraft; bool synchronized;
String? priority; String? priority;
String? name; String? name;
String? pickingTypeCode; String? pickingTypeCode;

View File

@ -156,7 +156,7 @@
}, },
{ {
"id": "7:7263194599189060077", "id": "7:7263194599189060077",
"lastPropertyId": "27:7762235054004255701", "lastPropertyId": "28:1976672364117660903",
"name": "StockPickingRecordEntity", "name": "StockPickingRecordEntity",
"properties": [ "properties": [
{ {
@ -241,8 +241,8 @@
"relationTarget": "StockPickingTypeEntity" "relationTarget": "StockPickingTypeEntity"
}, },
{ {
"id": "27:7762235054004255701", "id": "28:1976672364117660903",
"name": "isDraft", "name": "synchronized",
"type": 1 "type": 1
} }
], ],
@ -295,7 +295,8 @@
2889425908429352139, 2889425908429352139,
934877054574553245, 934877054574553245,
7012525525648469072, 7012525525648469072,
4739641817802949530 4739641817802949530,
7762235054004255701
], ],
"retiredRelationUids": [], "retiredRelationUids": [],
"version": 1 "version": 1

View File

@ -193,7 +193,7 @@ final _entities = <obx_int.ModelEntity>[
obx_int.ModelEntity( obx_int.ModelEntity(
id: const obx_int.IdUid(7, 7263194599189060077), id: const obx_int.IdUid(7, 7263194599189060077),
name: 'StockPickingRecordEntity', name: 'StockPickingRecordEntity',
lastPropertyId: const obx_int.IdUid(27, 7762235054004255701), lastPropertyId: const obx_int.IdUid(28, 1976672364117660903),
flags: 0, flags: 0,
properties: <obx_int.ModelProperty>[ properties: <obx_int.ModelProperty>[
obx_int.ModelProperty( obx_int.ModelProperty(
@ -285,8 +285,8 @@ final _entities = <obx_int.ModelEntity>[
relationTarget: 'StockPickingTypeEntity', relationTarget: 'StockPickingTypeEntity',
), ),
obx_int.ModelProperty( obx_int.ModelProperty(
id: const obx_int.IdUid(27, 7762235054004255701), id: const obx_int.IdUid(28, 1976672364117660903),
name: 'isDraft', name: 'synchronized',
type: 1, type: 1,
flags: 0, flags: 0,
), ),
@ -393,6 +393,7 @@ obx_int.ModelDefinition getObjectBoxModel() {
934877054574553245, 934877054574553245,
7012525525648469072, 7012525525648469072,
4739641817802949530, 4739641817802949530,
7762235054004255701,
], ],
retiredRelationUids: const [], retiredRelationUids: const [],
modelVersion: 5, modelVersion: 5,
@ -713,7 +714,7 @@ obx_int.ModelDefinition getObjectBoxModel() {
final originOffset = object.origin == null final originOffset = object.origin == null
? null ? null
: fbb.writeString(object.origin!); : fbb.writeString(object.origin!);
fbb.startTable(28); fbb.startTable(29);
fbb.addInt64(0, object.id); fbb.addInt64(0, object.id);
fbb.addOffset(1, priorityOffset); fbb.addOffset(1, priorityOffset);
fbb.addOffset(2, nameOffset); fbb.addOffset(2, nameOffset);
@ -727,7 +728,7 @@ obx_int.ModelDefinition getObjectBoxModel() {
fbb.addInt64(23, object.locationId.targetId); fbb.addInt64(23, object.locationId.targetId);
fbb.addInt64(24, object.locationDestId.targetId); fbb.addInt64(24, object.locationDestId.targetId);
fbb.addInt64(25, object.pickingTypeId.targetId); fbb.addInt64(25, object.pickingTypeId.targetId);
fbb.addBool(26, object.isDraft); fbb.addBool(27, object.synchronized);
fbb.finish(fbb.endTable()); fbb.finish(fbb.endTable());
return object.id; return object.id;
}, },
@ -740,10 +741,10 @@ obx_int.ModelDefinition getObjectBoxModel() {
4, 4,
0, 0,
); );
final isDraftParam = const fb.BoolReader().vTableGet( final synchronizedParam = const fb.BoolReader().vTableGet(
buffer, buffer,
rootOffset, rootOffset,
56, 58,
false, false,
); );
final priorityParam = const fb.StringReader( final priorityParam = const fb.StringReader(
@ -773,7 +774,7 @@ obx_int.ModelDefinition getObjectBoxModel() {
); );
final object = StockPickingRecordEntity( final object = StockPickingRecordEntity(
id: idParam, id: idParam,
isDraft: isDraftParam, synchronized: synchronizedParam,
priority: priorityParam, priority: priorityParam,
name: nameParam, name: nameParam,
pickingTypeCode: pickingTypeCodeParam, pickingTypeCode: pickingTypeCodeParam,
@ -1071,10 +1072,11 @@ class StockPickingRecordEntity_ {
_entities[6].properties[12], _entities[6].properties[12],
); );
/// See [StockPickingRecordEntity.isDraft]. /// See [StockPickingRecordEntity.synchronized].
static final isDraft = obx.QueryBooleanProperty<StockPickingRecordEntity>( static final synchronized =
_entities[6].properties[13], obx.QueryBooleanProperty<StockPickingRecordEntity>(
); _entities[6].properties[13],
);
/// see [StockPickingRecordEntity.moveLineIdsWithoutPackage] /// see [StockPickingRecordEntity.moveLineIdsWithoutPackage]
static final moveLineIdsWithoutPackage = static final moveLineIdsWithoutPackage =

View File

@ -9,11 +9,17 @@ class QuickActionComponent extends StatelessWidget {
this.onTapScan, this.onTapScan,
this.onTapSearch, this.onTapSearch,
this.onTapValidateReception, this.onTapValidateReception,
this.onTapSyncReception,
this.syncReceptionLoading = false,
this.validateReceptionLoading = false,
}); });
final VoidCallback? onTapAdd; final VoidCallback? onTapAdd;
final VoidCallback? onTapScan; final VoidCallback? onTapScan;
final VoidCallback? onTapSearch; final VoidCallback? onTapSearch;
final VoidCallback? onTapValidateReception; final VoidCallback? onTapValidateReception;
final VoidCallback? onTapSyncReception;
final bool syncReceptionLoading;
final bool validateReceptionLoading;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -59,6 +65,7 @@ class QuickActionComponent extends StatelessWidget {
SizedBox( SizedBox(
width: double.maxFinite, width: double.maxFinite,
child: PrimaryButtonComponent( child: PrimaryButtonComponent(
loading: validateReceptionLoading,
centered: true, centered: true,
leading: Icon(Icons.save, color: AppTheme.of(context).white), leading: Icon(Icons.save, color: AppTheme.of(context).white),
text: 'Valider la réception', text: 'Valider la réception',
@ -66,6 +73,22 @@ class QuickActionComponent extends StatelessWidget {
), ),
), ),
], ],
if (onTapSyncReception != null) ...[
const SizedBox(height: 16),
SizedBox(
width: double.maxFinite,
child: PrimaryButtonComponent(
loading: syncReceptionLoading,
centered: true,
leading: Icon(
Icons.cloud_upload_outlined,
color: AppTheme.of(context).white,
),
text: 'Synchroniser les données',
onPressed: onTapSyncReception,
),
),
],
if (onTapAdd != null) ...[ if (onTapAdd != null) ...[
const SizedBox(height: 16), const SizedBox(height: 16),
SizedBox( SizedBox(

View File

@ -11,11 +11,11 @@ class StockPickingCard extends StatelessWidget {
required this.origin, required this.origin,
required this.status, required this.status,
required this.isDone, required this.isDone,
this.isDraft = false, this.synchronized = true,
this.margin, this.margin,
}); });
final bool isDone; final bool isDone;
final bool isDraft; final bool synchronized;
final String? reference; final String? reference;
final String? from; final String? from;
final String? to; final String? to;
@ -56,7 +56,7 @@ class StockPickingCard extends StatelessWidget {
], ],
), ),
), ),
if (isDraft) if (!synchronized)
Chip( Chip(
backgroundColor: Colors.red, backgroundColor: Colors.red,
label: Row( label: Row(
@ -64,7 +64,7 @@ class StockPickingCard extends StatelessWidget {
children: [ children: [
Icon(Icons.cloud_off_outlined, color: Colors.white), Icon(Icons.cloud_off_outlined, color: Colors.white),
Text( Text(
'Brouillon', 'Non synchronisé',
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,

View File

@ -55,7 +55,31 @@ class _ReceptionDetailsPageState extends ConsumerState<ReceptionDetailsPage> {
const SizedBox(height: 16), const SizedBox(height: 16),
if (reception?.isDone == false) ...[ if (reception?.isDone == false) ...[
QuickActionComponent( QuickActionComponent(
onTapValidateReception: reception?.isDraft == true onTapValidateReception: reception?.synchronized == false
? () {
ref
.read(
receptionDetailsPageModelProvider
.notifier,
)
.validate(
receptionId: widget.receptionId,
onSuccess: () {
Toast.showSuccess(
'Réception validée avec succès.',
);
},
onError: () {
Toast.showError(
'Connexion impossible. Les données seront synchronisées plus tard.',
);
},
);
}
: null,
validateReceptionLoading: state.validateLoading,
syncReceptionLoading: state.saveLoading,
onTapSyncReception: reception?.synchronized == false
? () { ? () {
ref ref
.read( .read(
@ -66,7 +90,7 @@ class _ReceptionDetailsPageState extends ConsumerState<ReceptionDetailsPage> {
receptionId: widget.receptionId, receptionId: widget.receptionId,
onSuccess: () { onSuccess: () {
Toast.showSuccess( Toast.showSuccess(
'Réception validée avec succès.', 'Les données sont synchronisées.',
); );
}, },
onError: () { onError: () {
@ -102,7 +126,7 @@ class _ReceptionDetailsPageState extends ConsumerState<ReceptionDetailsPage> {
), ),
SizedBox(height: 10), SizedBox(height: 10),
StockPickingCard( StockPickingCard(
isDraft: reception?.isDraft == true, synchronized: reception?.synchronized == true,
isDone: reception?.isDone == true, isDone: reception?.isDone == true,
margin: EdgeInsets.symmetric(horizontal: 5), margin: EdgeInsets.symmetric(horizontal: 5),
reference: reception?.name ?? '', reference: reception?.name ?? '',

View File

@ -38,7 +38,7 @@ class ReceptionDetailsPageModel
VoidCallback? onError, VoidCallback? onError,
}) async { }) async {
try { try {
state = state.copyWith(validateLoading: true); state = state.copyWith(saveLoading: true);
final stockPickingRecords = objectboxManager.store final stockPickingRecords = objectboxManager.store
.box<StockPickingRecordEntity>(); .box<StockPickingRecordEntity>();
final stockPikingEntity = stockPickingRecords.get(receptionId); final stockPikingEntity = stockPickingRecords.get(receptionId);
@ -53,15 +53,48 @@ class ReceptionDetailsPageModel
) )
.toList() ?? .toList() ??
[]; [];
final res = await ApiCalls.updateAllMoveLineOnStockPiking( final res = await ApiCalls.updateAllMoveLineOnStockPicking(
stockPickingId: receptionId, stockPickingId: receptionId,
moveLineDto: moveLinesDto, moveLineDto: moveLinesDto,
); );
if (res) { if (res) {
stockPikingEntity?.synchronized = true;
stockPickingRecords.put(stockPikingEntity!);
getReceptionById(id: receptionId);
onSuccess?.call(); onSuccess?.call();
} else { } else {
onError?.call(); onError?.call();
} }
state = state.copyWith(saveLoading: false);
} catch (e) {
onError?.call();
state = state.copyWith(saveLoading: false);
}
}
Future validate({
required int receptionId,
VoidCallback? onSuccess,
VoidCallback? onError,
}) async {
await save(receptionId: receptionId);
try {
final stockPickingRecords = objectboxManager.store
.box<StockPickingRecordEntity>();
final stockPikingEntity = stockPickingRecords.get(receptionId);
state = state.copyWith(validateLoading: true);
final res = await ApiCalls.validateStockPicking(
stockPickingId: receptionId,
);
if (res) {
onSuccess?.call();
stockPikingEntity?.synchronized = true;
stockPikingEntity?.state = 'done';
stockPickingRecords.put(stockPikingEntity!);
getReceptionById(id: receptionId);
} else {
onError?.call();
}
state = state.copyWith(validateLoading: false); state = state.copyWith(validateLoading: false);
} catch (e) { } catch (e) {
onError?.call(); onError?.call();
@ -76,5 +109,6 @@ abstract class ReceptionDetailsPageState with _$ReceptionDetailsPageState {
StockPickingRecordEntity? reception, StockPickingRecordEntity? reception,
@Default(false) bool loading, @Default(false) bool loading,
@Default(false) bool validateLoading, @Default(false) bool validateLoading,
@Default(false) bool saveLoading,
}) = _ReceptionDetailsPageState; }) = _ReceptionDetailsPageState;
} }

View File

@ -15,7 +15,7 @@ T _$identity<T>(T value) => value;
/// @nodoc /// @nodoc
mixin _$ReceptionDetailsPageState implements DiagnosticableTreeMixin { mixin _$ReceptionDetailsPageState implements DiagnosticableTreeMixin {
StockPickingRecordEntity? get reception; bool get loading; bool get validateLoading; StockPickingRecordEntity? get reception; bool get loading; bool get validateLoading; bool get saveLoading;
/// Create a copy of ReceptionDetailsPageState /// Create a copy of ReceptionDetailsPageState
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false) @JsonKey(includeFromJson: false, includeToJson: false)
@ -27,21 +27,21 @@ $ReceptionDetailsPageStateCopyWith<ReceptionDetailsPageState> get copyWith => _$
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
properties properties
..add(DiagnosticsProperty('type', 'ReceptionDetailsPageState')) ..add(DiagnosticsProperty('type', 'ReceptionDetailsPageState'))
..add(DiagnosticsProperty('reception', reception))..add(DiagnosticsProperty('loading', loading))..add(DiagnosticsProperty('validateLoading', validateLoading)); ..add(DiagnosticsProperty('reception', reception))..add(DiagnosticsProperty('loading', loading))..add(DiagnosticsProperty('validateLoading', validateLoading))..add(DiagnosticsProperty('saveLoading', saveLoading));
} }
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is ReceptionDetailsPageState&&(identical(other.reception, reception) || other.reception == reception)&&(identical(other.loading, loading) || other.loading == loading)&&(identical(other.validateLoading, validateLoading) || other.validateLoading == validateLoading)); return identical(this, other) || (other.runtimeType == runtimeType&&other is ReceptionDetailsPageState&&(identical(other.reception, reception) || other.reception == reception)&&(identical(other.loading, loading) || other.loading == loading)&&(identical(other.validateLoading, validateLoading) || other.validateLoading == validateLoading)&&(identical(other.saveLoading, saveLoading) || other.saveLoading == saveLoading));
} }
@override @override
int get hashCode => Object.hash(runtimeType,reception,loading,validateLoading); int get hashCode => Object.hash(runtimeType,reception,loading,validateLoading,saveLoading);
@override @override
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) { String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
return 'ReceptionDetailsPageState(reception: $reception, loading: $loading, validateLoading: $validateLoading)'; return 'ReceptionDetailsPageState(reception: $reception, loading: $loading, validateLoading: $validateLoading, saveLoading: $saveLoading)';
} }
@ -52,7 +52,7 @@ abstract mixin class $ReceptionDetailsPageStateCopyWith<$Res> {
factory $ReceptionDetailsPageStateCopyWith(ReceptionDetailsPageState value, $Res Function(ReceptionDetailsPageState) _then) = _$ReceptionDetailsPageStateCopyWithImpl; factory $ReceptionDetailsPageStateCopyWith(ReceptionDetailsPageState value, $Res Function(ReceptionDetailsPageState) _then) = _$ReceptionDetailsPageStateCopyWithImpl;
@useResult @useResult
$Res call({ $Res call({
StockPickingRecordEntity? reception, bool loading, bool validateLoading StockPickingRecordEntity? reception, bool loading, bool validateLoading, bool saveLoading
}); });
@ -69,11 +69,12 @@ class _$ReceptionDetailsPageStateCopyWithImpl<$Res>
/// Create a copy of ReceptionDetailsPageState /// Create a copy of ReceptionDetailsPageState
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? reception = freezed,Object? loading = null,Object? validateLoading = null,}) { @pragma('vm:prefer-inline') @override $Res call({Object? reception = freezed,Object? loading = null,Object? validateLoading = null,Object? saveLoading = null,}) {
return _then(_self.copyWith( return _then(_self.copyWith(
reception: freezed == reception ? _self.reception : reception // ignore: cast_nullable_to_non_nullable reception: freezed == reception ? _self.reception : reception // ignore: cast_nullable_to_non_nullable
as StockPickingRecordEntity?,loading: null == loading ? _self.loading : loading // ignore: cast_nullable_to_non_nullable as StockPickingRecordEntity?,loading: null == loading ? _self.loading : loading // ignore: cast_nullable_to_non_nullable
as bool,validateLoading: null == validateLoading ? _self.validateLoading : validateLoading // ignore: cast_nullable_to_non_nullable as bool,validateLoading: null == validateLoading ? _self.validateLoading : validateLoading // ignore: cast_nullable_to_non_nullable
as bool,saveLoading: null == saveLoading ? _self.saveLoading : saveLoading // ignore: cast_nullable_to_non_nullable
as bool, as bool,
)); ));
} }
@ -85,12 +86,13 @@ as bool,
class _ReceptionDetailsPageState with DiagnosticableTreeMixin implements ReceptionDetailsPageState { class _ReceptionDetailsPageState with DiagnosticableTreeMixin implements ReceptionDetailsPageState {
const _ReceptionDetailsPageState({this.reception, this.loading = false, this.validateLoading = false}); const _ReceptionDetailsPageState({this.reception, this.loading = false, this.validateLoading = false, this.saveLoading = false});
@override final StockPickingRecordEntity? reception; @override final StockPickingRecordEntity? reception;
@override@JsonKey() final bool loading; @override@JsonKey() final bool loading;
@override@JsonKey() final bool validateLoading; @override@JsonKey() final bool validateLoading;
@override@JsonKey() final bool saveLoading;
/// Create a copy of ReceptionDetailsPageState /// Create a copy of ReceptionDetailsPageState
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@ -103,21 +105,21 @@ _$ReceptionDetailsPageStateCopyWith<_ReceptionDetailsPageState> get copyWith =>
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
properties properties
..add(DiagnosticsProperty('type', 'ReceptionDetailsPageState')) ..add(DiagnosticsProperty('type', 'ReceptionDetailsPageState'))
..add(DiagnosticsProperty('reception', reception))..add(DiagnosticsProperty('loading', loading))..add(DiagnosticsProperty('validateLoading', validateLoading)); ..add(DiagnosticsProperty('reception', reception))..add(DiagnosticsProperty('loading', loading))..add(DiagnosticsProperty('validateLoading', validateLoading))..add(DiagnosticsProperty('saveLoading', saveLoading));
} }
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ReceptionDetailsPageState&&(identical(other.reception, reception) || other.reception == reception)&&(identical(other.loading, loading) || other.loading == loading)&&(identical(other.validateLoading, validateLoading) || other.validateLoading == validateLoading)); return identical(this, other) || (other.runtimeType == runtimeType&&other is _ReceptionDetailsPageState&&(identical(other.reception, reception) || other.reception == reception)&&(identical(other.loading, loading) || other.loading == loading)&&(identical(other.validateLoading, validateLoading) || other.validateLoading == validateLoading)&&(identical(other.saveLoading, saveLoading) || other.saveLoading == saveLoading));
} }
@override @override
int get hashCode => Object.hash(runtimeType,reception,loading,validateLoading); int get hashCode => Object.hash(runtimeType,reception,loading,validateLoading,saveLoading);
@override @override
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) { String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
return 'ReceptionDetailsPageState(reception: $reception, loading: $loading, validateLoading: $validateLoading)'; return 'ReceptionDetailsPageState(reception: $reception, loading: $loading, validateLoading: $validateLoading, saveLoading: $saveLoading)';
} }
@ -128,7 +130,7 @@ abstract mixin class _$ReceptionDetailsPageStateCopyWith<$Res> implements $Recep
factory _$ReceptionDetailsPageStateCopyWith(_ReceptionDetailsPageState value, $Res Function(_ReceptionDetailsPageState) _then) = __$ReceptionDetailsPageStateCopyWithImpl; factory _$ReceptionDetailsPageStateCopyWith(_ReceptionDetailsPageState value, $Res Function(_ReceptionDetailsPageState) _then) = __$ReceptionDetailsPageStateCopyWithImpl;
@override @useResult @override @useResult
$Res call({ $Res call({
StockPickingRecordEntity? reception, bool loading, bool validateLoading StockPickingRecordEntity? reception, bool loading, bool validateLoading, bool saveLoading
}); });
@ -145,11 +147,12 @@ class __$ReceptionDetailsPageStateCopyWithImpl<$Res>
/// Create a copy of ReceptionDetailsPageState /// Create a copy of ReceptionDetailsPageState
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? reception = freezed,Object? loading = null,Object? validateLoading = null,}) { @override @pragma('vm:prefer-inline') $Res call({Object? reception = freezed,Object? loading = null,Object? validateLoading = null,Object? saveLoading = null,}) {
return _then(_ReceptionDetailsPageState( return _then(_ReceptionDetailsPageState(
reception: freezed == reception ? _self.reception : reception // ignore: cast_nullable_to_non_nullable reception: freezed == reception ? _self.reception : reception // ignore: cast_nullable_to_non_nullable
as StockPickingRecordEntity?,loading: null == loading ? _self.loading : loading // ignore: cast_nullable_to_non_nullable as StockPickingRecordEntity?,loading: null == loading ? _self.loading : loading // ignore: cast_nullable_to_non_nullable
as bool,validateLoading: null == validateLoading ? _self.validateLoading : validateLoading // ignore: cast_nullable_to_non_nullable as bool,validateLoading: null == validateLoading ? _self.validateLoading : validateLoading // ignore: cast_nullable_to_non_nullable
as bool,saveLoading: null == saveLoading ? _self.saveLoading : saveLoading // ignore: cast_nullable_to_non_nullable
as bool, as bool,
)); ));
} }

View File

@ -79,7 +79,7 @@ class _ReceptionPageState extends ConsumerState<ReceptionPage> {
).push(context); ).push(context);
}, },
child: StockPickingCard( child: StockPickingCard(
isDraft: reception.isDraft == true, synchronized: reception.synchronized == true,
margin: EdgeInsets.symmetric( margin: EdgeInsets.symmetric(
horizontal: 5, horizontal: 5,
vertical: 5, vertical: 5,

View File

@ -57,32 +57,21 @@ class ReceptionScanPageModel
final stockPickingRecordBox = objectboxManager.store final stockPickingRecordBox = objectboxManager.store
.box<StockPickingRecordEntity>(); .box<StockPickingRecordEntity>();
final moveBox = objectboxManager.store.box<MoveWithoutPackageEntity>(); 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); final stockPickingRecord = stockPickingRecordBox.get(receptionId);
if (productId != null) { final moveLineEntity = stockPickingRecord?.moveLineIdsWithoutPackage
final moveLineEntity = moveLineBox .firstWhere((e) => e.productId.target?.barcode == barcode);
.query(MoveLineWithoutPackageEntity_.productId.equals(productId)) final moveEntity = stockPickingRecord?.moveIdsWithoutPackage.firstWhere(
.build() (e) => e.productId.target?.barcode == barcode,
.findFirst(); );
final moveEntity = moveBox if (moveLineEntity != null &&
.query(MoveWithoutPackageEntity_.productId.equals(productId)) moveEntity != null &&
.build() stockPickingRecord != null) {
.findFirst(); moveLineEntity.quantity = (moveLineEntity.quantity ?? 0) + 1;
if (moveLineEntity != null && moveEntity.quantity = (moveEntity.quantity ?? 0) + 1;
moveEntity != null && stockPickingRecord.synchronized = false;
stockPickingRecord != null) { moveLineBox.put(moveLineEntity);
moveLineEntity.quantity = (moveLineEntity.quantity ?? 0) + 1; moveBox.put(moveEntity);
moveEntity.quantity = (moveEntity.quantity ?? 0) + 1; stockPickingRecordBox.put(stockPickingRecord);
stockPickingRecord.isDraft = true;
moveLineBox.put(moveLineEntity);
moveBox.put(moveEntity);
stockPickingRecordBox.put(stockPickingRecord);
}
} }
} }
} }