enhance: Enhances data models and reception details
Improves JSON deserialization for product and stock picking models by using custom `fromJson` methods and explicit `JsonKey` mappings. This ensures robust parsing of fields like barcode, display name, and product IDs. Adds a new `ecart` getter to calculate the difference between requested and received quantities for stock moves. Updates the reception details page to display a list of products with their requested, received, and calculated difference quantities. Removes redundant JSON-RPC fields from the `stock.picking/web_read` API call.
This commit is contained in:
parent
6af1bfc4ab
commit
6e49971883
@ -181,8 +181,6 @@ class ApiCalls {
|
||||
final response = await dioService.post(
|
||||
path: '/web/dataset/call_kw/stock.picking/web_read',
|
||||
data: {
|
||||
"jsonrpc": "2.0",
|
||||
"method": "call",
|
||||
"params": {
|
||||
"model": "stock.picking",
|
||||
"method": "web_read",
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:e_scan/backend/objectbox/entities/product/product_entity.dart';
|
||||
import 'package:e_scan/utils/utils.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'product_model.freezed.dart';
|
||||
@ -6,8 +7,12 @@ part 'product_model.g.dart';
|
||||
|
||||
@Freezed(toJson: true)
|
||||
abstract class ProductModel with _$ProductModel {
|
||||
factory ProductModel({int? id, String? barcode, String? displayName}) =
|
||||
_ProductModel;
|
||||
factory ProductModel({
|
||||
int? id,
|
||||
@JsonKey(fromJson: stringFromJson) String? barcode,
|
||||
@JsonKey(name: 'display_name', fromJson: stringFromJson)
|
||||
String? displayName,
|
||||
}) = _ProductModel;
|
||||
|
||||
factory ProductModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$ProductModelFromJson(json);
|
||||
|
@ -16,7 +16,7 @@ T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$ProductModel {
|
||||
|
||||
int? get id; String? get barcode; String? get displayName;
|
||||
int? get id;@JsonKey(fromJson: stringFromJson) String? get barcode;@JsonKey(name: 'display_name', fromJson: stringFromJson) String? get displayName;
|
||||
/// Create a copy of ProductModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@ -49,7 +49,7 @@ abstract mixin class $ProductModelCopyWith<$Res> {
|
||||
factory $ProductModelCopyWith(ProductModel value, $Res Function(ProductModel) _then) = _$ProductModelCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
int? id, String? barcode, String? displayName
|
||||
int? id,@JsonKey(fromJson: stringFromJson) String? barcode,@JsonKey(name: 'display_name', fromJson: stringFromJson) String? displayName
|
||||
});
|
||||
|
||||
|
||||
@ -82,12 +82,12 @@ as String?,
|
||||
@JsonSerializable()
|
||||
|
||||
class _ProductModel implements ProductModel {
|
||||
_ProductModel({this.id, this.barcode, this.displayName});
|
||||
_ProductModel({this.id, @JsonKey(fromJson: stringFromJson) this.barcode, @JsonKey(name: 'display_name', fromJson: stringFromJson) this.displayName});
|
||||
factory _ProductModel.fromJson(Map<String, dynamic> json) => _$ProductModelFromJson(json);
|
||||
|
||||
@override final int? id;
|
||||
@override final String? barcode;
|
||||
@override final String? displayName;
|
||||
@override@JsonKey(fromJson: stringFromJson) final String? barcode;
|
||||
@override@JsonKey(name: 'display_name', fromJson: stringFromJson) final String? displayName;
|
||||
|
||||
/// Create a copy of ProductModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@ -122,7 +122,7 @@ abstract mixin class _$ProductModelCopyWith<$Res> implements $ProductModelCopyWi
|
||||
factory _$ProductModelCopyWith(_ProductModel value, $Res Function(_ProductModel) _then) = __$ProductModelCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
int? id, String? barcode, String? displayName
|
||||
int? id,@JsonKey(fromJson: stringFromJson) String? barcode,@JsonKey(name: 'display_name', fromJson: stringFromJson) String? displayName
|
||||
});
|
||||
|
||||
|
||||
|
@ -9,13 +9,13 @@ part of 'product_model.dart';
|
||||
_ProductModel _$ProductModelFromJson(Map<String, dynamic> json) =>
|
||||
_ProductModel(
|
||||
id: (json['id'] as num?)?.toInt(),
|
||||
barcode: json['barcode'] as String?,
|
||||
displayName: json['displayName'] as String?,
|
||||
barcode: stringFromJson(json['barcode']),
|
||||
displayName: stringFromJson(json['display_name']),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ProductModelToJson(_ProductModel instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'barcode': instance.barcode,
|
||||
'displayName': instance.displayName,
|
||||
'display_name': instance.displayName,
|
||||
};
|
||||
|
@ -72,6 +72,7 @@ List<MoveWithoutPackageModel>? _moveIdsWithoutPackageFromJson(dynamic json) =>
|
||||
abstract class MoveLineWithoutPackageModel with _$MoveLineWithoutPackageModel {
|
||||
const factory MoveLineWithoutPackageModel({
|
||||
int? id,
|
||||
@JsonKey(name: 'product_id', fromJson: _productFromJson)
|
||||
ProductModel? productId,
|
||||
double? quantity,
|
||||
}) = _MoveLineWithoutPackageModel;
|
||||
@ -84,15 +85,23 @@ abstract class MoveLineWithoutPackageModel with _$MoveLineWithoutPackageModel {
|
||||
abstract class MoveWithoutPackageModel with _$MoveWithoutPackageModel {
|
||||
const factory MoveWithoutPackageModel({
|
||||
int? id,
|
||||
@JsonKey(name: 'product_id', fromJson: _productFromJson)
|
||||
ProductModel? productId,
|
||||
double? quantity,
|
||||
double? productUomQty,
|
||||
@JsonKey(name: 'product_uom_qty') double? productUomQty,
|
||||
}) = _MoveWithoutPackageModel;
|
||||
|
||||
factory MoveWithoutPackageModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$MoveWithoutPackageModelFromJson(json);
|
||||
}
|
||||
|
||||
ProductModel? _productFromJson(dynamic json) =>
|
||||
objectFromJson(json, ProductModel.fromJson);
|
||||
|
||||
extension StockPickingRecordModelExt on StockPickingRecordModel {
|
||||
bool get isDone => state == "done";
|
||||
}
|
||||
|
||||
extension MoveWithoutPackageModelExt on MoveWithoutPackageModel {
|
||||
double get ecart => ((quantity ?? 0) - (productUomQty ?? 0));
|
||||
}
|
||||
|
@ -350,7 +350,7 @@ $StockPickingTypeModelCopyWith<$Res>? get pickingTypeId {
|
||||
/// @nodoc
|
||||
mixin _$MoveLineWithoutPackageModel {
|
||||
|
||||
int? get id; ProductModel? get productId; double? get quantity;
|
||||
int? get id;@JsonKey(name: 'product_id', fromJson: _productFromJson) ProductModel? get productId; double? get quantity;
|
||||
/// Create a copy of MoveLineWithoutPackageModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@ -383,7 +383,7 @@ abstract mixin class $MoveLineWithoutPackageModelCopyWith<$Res> {
|
||||
factory $MoveLineWithoutPackageModelCopyWith(MoveLineWithoutPackageModel value, $Res Function(MoveLineWithoutPackageModel) _then) = _$MoveLineWithoutPackageModelCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
int? id, ProductModel? productId, double? quantity
|
||||
int? id,@JsonKey(name: 'product_id', fromJson: _productFromJson) ProductModel? productId, double? quantity
|
||||
});
|
||||
|
||||
|
||||
@ -428,11 +428,11 @@ $ProductModelCopyWith<$Res>? get productId {
|
||||
@JsonSerializable()
|
||||
|
||||
class _MoveLineWithoutPackageModel implements MoveLineWithoutPackageModel {
|
||||
const _MoveLineWithoutPackageModel({this.id, this.productId, this.quantity});
|
||||
const _MoveLineWithoutPackageModel({this.id, @JsonKey(name: 'product_id', fromJson: _productFromJson) this.productId, this.quantity});
|
||||
factory _MoveLineWithoutPackageModel.fromJson(Map<String, dynamic> json) => _$MoveLineWithoutPackageModelFromJson(json);
|
||||
|
||||
@override final int? id;
|
||||
@override final ProductModel? productId;
|
||||
@override@JsonKey(name: 'product_id', fromJson: _productFromJson) final ProductModel? productId;
|
||||
@override final double? quantity;
|
||||
|
||||
/// Create a copy of MoveLineWithoutPackageModel
|
||||
@ -468,7 +468,7 @@ abstract mixin class _$MoveLineWithoutPackageModelCopyWith<$Res> implements $Mov
|
||||
factory _$MoveLineWithoutPackageModelCopyWith(_MoveLineWithoutPackageModel value, $Res Function(_MoveLineWithoutPackageModel) _then) = __$MoveLineWithoutPackageModelCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
int? id, ProductModel? productId, double? quantity
|
||||
int? id,@JsonKey(name: 'product_id', fromJson: _productFromJson) ProductModel? productId, double? quantity
|
||||
});
|
||||
|
||||
|
||||
@ -513,7 +513,7 @@ $ProductModelCopyWith<$Res>? get productId {
|
||||
/// @nodoc
|
||||
mixin _$MoveWithoutPackageModel {
|
||||
|
||||
int? get id; ProductModel? get productId; double? get quantity; double? get productUomQty;
|
||||
int? get id;@JsonKey(name: 'product_id', fromJson: _productFromJson) ProductModel? get productId; double? get quantity;@JsonKey(name: 'product_uom_qty') double? get productUomQty;
|
||||
/// Create a copy of MoveWithoutPackageModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@ -546,7 +546,7 @@ abstract mixin class $MoveWithoutPackageModelCopyWith<$Res> {
|
||||
factory $MoveWithoutPackageModelCopyWith(MoveWithoutPackageModel value, $Res Function(MoveWithoutPackageModel) _then) = _$MoveWithoutPackageModelCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
int? id, ProductModel? productId, double? quantity, double? productUomQty
|
||||
int? id,@JsonKey(name: 'product_id', fromJson: _productFromJson) ProductModel? productId, double? quantity,@JsonKey(name: 'product_uom_qty') double? productUomQty
|
||||
});
|
||||
|
||||
|
||||
@ -592,13 +592,13 @@ $ProductModelCopyWith<$Res>? get productId {
|
||||
@JsonSerializable()
|
||||
|
||||
class _MoveWithoutPackageModel implements MoveWithoutPackageModel {
|
||||
const _MoveWithoutPackageModel({this.id, this.productId, this.quantity, this.productUomQty});
|
||||
const _MoveWithoutPackageModel({this.id, @JsonKey(name: 'product_id', fromJson: _productFromJson) this.productId, this.quantity, @JsonKey(name: 'product_uom_qty') this.productUomQty});
|
||||
factory _MoveWithoutPackageModel.fromJson(Map<String, dynamic> json) => _$MoveWithoutPackageModelFromJson(json);
|
||||
|
||||
@override final int? id;
|
||||
@override final ProductModel? productId;
|
||||
@override@JsonKey(name: 'product_id', fromJson: _productFromJson) final ProductModel? productId;
|
||||
@override final double? quantity;
|
||||
@override final double? productUomQty;
|
||||
@override@JsonKey(name: 'product_uom_qty') final double? productUomQty;
|
||||
|
||||
/// Create a copy of MoveWithoutPackageModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@ -633,7 +633,7 @@ abstract mixin class _$MoveWithoutPackageModelCopyWith<$Res> implements $MoveWit
|
||||
factory _$MoveWithoutPackageModelCopyWith(_MoveWithoutPackageModel value, $Res Function(_MoveWithoutPackageModel) _then) = __$MoveWithoutPackageModelCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
int? id, ProductModel? productId, double? quantity, double? productUomQty
|
||||
int? id,@JsonKey(name: 'product_id', fromJson: _productFromJson) ProductModel? productId, double? quantity,@JsonKey(name: 'product_uom_qty') double? productUomQty
|
||||
});
|
||||
|
||||
|
||||
|
@ -76,9 +76,7 @@ _MoveLineWithoutPackageModel _$MoveLineWithoutPackageModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _MoveLineWithoutPackageModel(
|
||||
id: (json['id'] as num?)?.toInt(),
|
||||
productId: json['productId'] == null
|
||||
? null
|
||||
: ProductModel.fromJson(json['productId'] as Map<String, dynamic>),
|
||||
productId: _productFromJson(json['product_id']),
|
||||
quantity: (json['quantity'] as num?)?.toDouble(),
|
||||
);
|
||||
|
||||
@ -86,7 +84,7 @@ Map<String, dynamic> _$MoveLineWithoutPackageModelToJson(
|
||||
_MoveLineWithoutPackageModel instance,
|
||||
) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'productId': instance.productId,
|
||||
'product_id': instance.productId,
|
||||
'quantity': instance.quantity,
|
||||
};
|
||||
|
||||
@ -94,18 +92,16 @@ _MoveWithoutPackageModel _$MoveWithoutPackageModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _MoveWithoutPackageModel(
|
||||
id: (json['id'] as num?)?.toInt(),
|
||||
productId: json['productId'] == null
|
||||
? null
|
||||
: ProductModel.fromJson(json['productId'] as Map<String, dynamic>),
|
||||
productId: _productFromJson(json['product_id']),
|
||||
quantity: (json['quantity'] as num?)?.toDouble(),
|
||||
productUomQty: (json['productUomQty'] as num?)?.toDouble(),
|
||||
productUomQty: (json['product_uom_qty'] as num?)?.toDouble(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$MoveWithoutPackageModelToJson(
|
||||
_MoveWithoutPackageModel instance,
|
||||
) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'productId': instance.productId,
|
||||
'product_id': instance.productId,
|
||||
'quantity': instance.quantity,
|
||||
'productUomQty': instance.productUomQty,
|
||||
'product_uom_qty': instance.productUomQty,
|
||||
};
|
||||
|
@ -52,6 +52,13 @@ class _ReceptionDetailsPageState extends ConsumerState<ReceptionDetailsPage> {
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
Text(
|
||||
'Détails réception',
|
||||
style: AppTheme.of(
|
||||
context,
|
||||
).bodyMedium.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
StockPickingCard(
|
||||
isDone: reception?.isDone == true,
|
||||
margin: EdgeInsets.symmetric(horizontal: 5),
|
||||
@ -62,6 +69,68 @@ class _ReceptionDetailsPageState extends ConsumerState<ReceptionDetailsPage> {
|
||||
origin: reception?.origin,
|
||||
status: reception?.state,
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
ListView(
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
primary: true,
|
||||
children: [
|
||||
Text(
|
||||
'Produits',
|
||||
style: AppTheme.of(
|
||||
context,
|
||||
).bodyMedium.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
...reception?.moveIdsWithoutPackage
|
||||
?.map(
|
||||
(move) => Card(
|
||||
color: AppTheme.of(context).primaryBackground,
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
move.productId?.displayName ?? '',
|
||||
style: TextStyle(color: Colors.black),
|
||||
),
|
||||
subtitle: Wrap(
|
||||
spacing: 5,
|
||||
children: [
|
||||
Chip(
|
||||
backgroundColor: AppTheme.of(
|
||||
context,
|
||||
).secondaryBackground,
|
||||
label: Text(
|
||||
"Qté demandée: ${move.productUomQty}",
|
||||
),
|
||||
),
|
||||
Chip(
|
||||
backgroundColor: AppTheme.of(
|
||||
context,
|
||||
).secondaryBackground,
|
||||
label: Text(
|
||||
"Qté reçue: ${move.quantity}",
|
||||
),
|
||||
),
|
||||
Chip(
|
||||
backgroundColor: AppTheme.of(
|
||||
context,
|
||||
).secondaryBackground,
|
||||
label: Text(
|
||||
"Ecart: ${move.ecart}",
|
||||
style: TextStyle(
|
||||
color: Colors.green,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList() ??
|
||||
[],
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -16,6 +16,16 @@ String? stringFromJson(dynamic json) {
|
||||
return null;
|
||||
}
|
||||
|
||||
double? doubleFromJson(dynamic json) {
|
||||
if (json is double) return json;
|
||||
return null;
|
||||
}
|
||||
|
||||
int? intFromJson(dynamic json) {
|
||||
if (json is int) return json;
|
||||
return null;
|
||||
}
|
||||
|
||||
T? objectFromJson<T>(dynamic json, T Function(Map<String, dynamic>) fromJson) {
|
||||
if (json is Map<String, dynamic>) return fromJson(json);
|
||||
return null;
|
||||
|
Loading…
x
Reference in New Issue
Block a user