fix product

This commit is contained in:
Phuoc Nguyen
2025-11-17 15:07:53 +07:00
parent 0828ff1355
commit ff3629d6d1
14 changed files with 1087 additions and 110 deletions

View File

@@ -30,6 +30,7 @@ class ProductModel extends HiveObject {
this.brand,
this.unit,
this.conversionOfSm,
this.introAttributes,
required this.isActive,
required this.isFeatured,
this.erpnextItemCode,
@@ -91,6 +92,12 @@ class ProductModel extends HiveObject {
@HiveField(17)
final double? conversionOfSm;
/// Intro attributes (JSON encoded list)
/// Quick reference attributes from API: Size, Colour, UOM
/// Example: [{"code": "Size", "value": "120x120"}, {"code": "UOM", "value": "2 viên/hộp"}]
@HiveField(18)
final String? introAttributes;
/// Whether product is active
@HiveField(12)
final bool isActive;
@@ -137,6 +144,9 @@ class ProductModel extends HiveObject {
conversionOfSm: json['conversion_of_sm'] != null
? (json['conversion_of_sm'] as num).toDouble()
: null,
introAttributes: json['intro_attributes'] != null
? jsonEncode(json['intro_attributes'])
: null,
isActive: json['is_active'] as bool? ?? true,
isFeatured: json['is_featured'] as bool? ?? false,
erpnextItemCode: json['erpnext_item_code'] as String?,
@@ -223,6 +233,22 @@ class ProductModel extends HiveObject {
}
}
// Parse intro_attributes array for quick reference
final List<Map<String, String>> introAttributesList = [];
if (json['intro_attributes'] != null && json['intro_attributes'] is List) {
final introAttrsData = json['intro_attributes'] as List;
for (final attr in introAttrsData) {
if (attr is Map<String, dynamic> &&
attr['code'] != null &&
attr['value'] != null) {
introAttributesList.add({
'code': attr['code'] as String,
'value': attr['value'] as String,
});
}
}
}
final now = DateTime.now();
// Handle price from both product detail (price) and product list (standard_rate)
@@ -251,6 +277,9 @@ class ProductModel extends HiveObject {
conversionOfSm: json['conversion_of_sm'] != null
? (json['conversion_of_sm'] as num).toDouble()
: null,
introAttributes: introAttributesList.isNotEmpty
? jsonEncode(introAttributesList)
: null,
isActive: (json['disabled'] as int?) == 0, // Frappe uses 'disabled' field
isFeatured: false, // Not provided by API, default to false
erpnextItemCode: json['name'] as String, // Store item code for reference
@@ -283,6 +312,9 @@ class ProductModel extends HiveObject {
'brand': brand,
'unit': unit,
'conversion_of_sm': conversionOfSm,
'intro_attributes': introAttributes != null
? jsonDecode(introAttributes!)
: null,
'is_active': isActive,
'is_featured': isFeatured,
'erpnext_item_code': erpnextItemCode,
@@ -336,6 +368,38 @@ class ProductModel extends HiveObject {
}
}
/// Get intro attributes as List
List<Map<String, String>>? get introAttributesList {
if (introAttributes == null) return null;
try {
final decoded = jsonDecode(introAttributes!) as List;
return decoded.map((e) {
final map = e as Map<String, dynamic>;
return {
'code': map['code'].toString(),
'value': map['value'].toString(),
};
}).toList();
} catch (e) {
return null;
}
}
/// Get specific intro attribute value by code
String? getIntroAttribute(String code) {
final attrs = introAttributesList;
if (attrs == null) return null;
try {
final attr = attrs.firstWhere(
(attr) => attr['code']?.toLowerCase() == code.toLowerCase(),
);
return attr['value'];
} catch (e) {
return null;
}
}
/// Get formatted price with currency
String get formattedPrice {
return '${basePrice.toStringAsFixed(0)}đ';
@@ -363,6 +427,7 @@ class ProductModel extends HiveObject {
String? brand,
String? unit,
double? conversionOfSm,
String? introAttributes,
bool? isActive,
bool? isFeatured,
String? erpnextItemCode,
@@ -383,6 +448,7 @@ class ProductModel extends HiveObject {
brand: brand ?? this.brand,
unit: unit ?? this.unit,
conversionOfSm: conversionOfSm ?? this.conversionOfSm,
introAttributes: introAttributes ?? this.introAttributes,
isActive: isActive ?? this.isActive,
isFeatured: isFeatured ?? this.isFeatured,
erpnextItemCode: erpnextItemCode ?? this.erpnextItemCode,
@@ -426,6 +492,7 @@ class ProductModel extends HiveObject {
brand: brand,
unit: unit,
conversionOfSm: conversionOfSm,
introAttributes: introAttributesList,
isActive: isActive,
isFeatured: isFeatured,
erpnextItemCode: erpnextItemCode,

View File

@@ -30,6 +30,7 @@ class ProductModelAdapter extends TypeAdapter<ProductModel> {
brand: fields[10] as String?,
unit: fields[11] as String?,
conversionOfSm: (fields[17] as num?)?.toDouble(),
introAttributes: fields[18] as String?,
isActive: fields[12] as bool,
isFeatured: fields[13] as bool,
erpnextItemCode: fields[14] as String?,
@@ -41,7 +42,7 @@ class ProductModelAdapter extends TypeAdapter<ProductModel> {
@override
void write(BinaryWriter writer, ProductModel obj) {
writer
..writeByte(18)
..writeByte(19)
..writeByte(0)
..write(obj.productId)
..writeByte(1)
@@ -77,7 +78,9 @@ class ProductModelAdapter extends TypeAdapter<ProductModel> {
..writeByte(16)
..write(obj.updatedAt)
..writeByte(17)
..write(obj.conversionOfSm);
..write(obj.conversionOfSm)
..writeByte(18)
..write(obj.introAttributes);
}
@override