Fix type casting in order history and order detail models
Handle string/int/null values safely in JSON parsing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
28e41a445e
commit
b47c68b63a
4 changed files with 53 additions and 36 deletions
|
|
@ -43,22 +43,23 @@ class OrderDetail {
|
||||||
});
|
});
|
||||||
|
|
||||||
factory OrderDetail.fromJson(Map<String, dynamic> json) {
|
factory OrderDetail.fromJson(Map<String, dynamic> json) {
|
||||||
|
String safeStr(dynamic v) => v?.toString() ?? '';
|
||||||
final lineItemsJson = json['LineItems'] as List<dynamic>? ?? [];
|
final lineItemsJson = json['LineItems'] as List<dynamic>? ?? [];
|
||||||
final staffJson = json['Staff'] as List<dynamic>? ?? [];
|
final staffJson = json['Staff'] as List<dynamic>? ?? [];
|
||||||
|
|
||||||
return OrderDetail(
|
return OrderDetail(
|
||||||
orderId: _parseInt(json['OrderID']) ?? 0,
|
orderId: _parseInt(json['OrderID']) ?? 0,
|
||||||
businessId: _parseInt(json['BusinessID']) ?? 0,
|
businessId: _parseInt(json['BusinessID']) ?? 0,
|
||||||
businessName: (json['BusinessName'] as String?) ?? '',
|
businessName: safeStr(json['BusinessName']),
|
||||||
status: _parseInt(json['Status']) ?? 0,
|
status: _parseInt(json['Status']) ?? 0,
|
||||||
statusText: (json['StatusText'] as String?) ?? '',
|
statusText: safeStr(json['StatusText']),
|
||||||
orderTypeId: _parseInt(json['OrderTypeID']) ?? 0,
|
orderTypeId: _parseInt(json['OrderTypeID']) ?? 0,
|
||||||
orderTypeName: (json['OrderTypeName'] as String?) ?? '',
|
orderTypeName: safeStr(json['OrderTypeName']),
|
||||||
subtotal: _parseDouble(json['Subtotal']) ?? 0.0,
|
subtotal: _parseDouble(json['Subtotal']) ?? 0.0,
|
||||||
tax: _parseDouble(json['Tax']) ?? 0.0,
|
tax: _parseDouble(json['Tax']) ?? 0.0,
|
||||||
tip: _parseDouble(json['Tip']) ?? 0.0,
|
tip: _parseDouble(json['Tip']) ?? 0.0,
|
||||||
total: _parseDouble(json['Total']) ?? 0.0,
|
total: _parseDouble(json['Total']) ?? 0.0,
|
||||||
notes: (json['Notes'] as String?) ?? '',
|
notes: safeStr(json['Notes']),
|
||||||
createdOn: _parseDateTime(json['CreatedOn']),
|
createdOn: _parseDateTime(json['CreatedOn']),
|
||||||
submittedOn: _parseDateTimeNullable(json['SubmittedOn']),
|
submittedOn: _parseDateTimeNullable(json['SubmittedOn']),
|
||||||
updatedOn: _parseDateTimeNullable(json['UpdatedOn']),
|
updatedOn: _parseDateTimeNullable(json['UpdatedOn']),
|
||||||
|
|
@ -135,14 +136,17 @@ class OrderCustomer {
|
||||||
|
|
||||||
factory OrderCustomer.fromJson(Map<String, dynamic> json) {
|
factory OrderCustomer.fromJson(Map<String, dynamic> json) {
|
||||||
return OrderCustomer(
|
return OrderCustomer(
|
||||||
userId: (json['UserID'] as num?)?.toInt() ?? 0,
|
userId: _safeInt(json['UserID']),
|
||||||
firstName: (json['FirstName'] as String?) ?? '',
|
firstName: _safeStr(json['FirstName']),
|
||||||
lastName: (json['LastName'] as String?) ?? '',
|
lastName: _safeStr(json['LastName']),
|
||||||
phone: (json['Phone'] as String?) ?? '',
|
phone: _safeStr(json['Phone']),
|
||||||
email: (json['Email'] as String?) ?? '',
|
email: _safeStr(json['Email']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _safeInt(dynamic v) => v is int ? v : int.tryParse(v?.toString() ?? '') ?? 0;
|
||||||
|
static String _safeStr(dynamic v) => v?.toString() ?? '';
|
||||||
|
|
||||||
String get fullName {
|
String get fullName {
|
||||||
final parts = [firstName, lastName].where((s) => s.isNotEmpty);
|
final parts = [firstName, lastName].where((s) => s.isNotEmpty);
|
||||||
return parts.isEmpty ? 'Guest' : parts.join(' ');
|
return parts.isEmpty ? 'Guest' : parts.join(' ');
|
||||||
|
|
@ -161,10 +165,12 @@ class OrderServicePoint {
|
||||||
});
|
});
|
||||||
|
|
||||||
factory OrderServicePoint.fromJson(Map<String, dynamic> json) {
|
factory OrderServicePoint.fromJson(Map<String, dynamic> json) {
|
||||||
|
int safeInt(dynamic v) => v is int ? v : int.tryParse(v?.toString() ?? '') ?? 0;
|
||||||
|
String safeStr(dynamic v) => v?.toString() ?? '';
|
||||||
return OrderServicePoint(
|
return OrderServicePoint(
|
||||||
servicePointId: (json['ServicePointID'] as num?)?.toInt() ?? 0,
|
servicePointId: safeInt(json['ServicePointID']),
|
||||||
name: (json['Name'] as String?) ?? '',
|
name: safeStr(json['Name']),
|
||||||
typeId: (json['TypeID'] as num?)?.toInt() ?? 0,
|
typeId: safeInt(json['TypeID']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -181,10 +187,12 @@ class OrderStaff {
|
||||||
});
|
});
|
||||||
|
|
||||||
factory OrderStaff.fromJson(Map<String, dynamic> json) {
|
factory OrderStaff.fromJson(Map<String, dynamic> json) {
|
||||||
|
int safeInt(dynamic v) => v is int ? v : int.tryParse(v?.toString() ?? '') ?? 0;
|
||||||
|
String safeStr(dynamic v) => v?.toString() ?? '';
|
||||||
return OrderStaff(
|
return OrderStaff(
|
||||||
userId: (json['UserID'] as num?)?.toInt() ?? 0,
|
userId: safeInt(json['UserID']),
|
||||||
firstName: (json['FirstName'] as String?) ?? '',
|
firstName: safeStr(json['FirstName']),
|
||||||
avatarUrl: (json['AvatarUrl'] as String?) ?? '',
|
avatarUrl: safeStr(json['AvatarUrl']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -213,16 +221,19 @@ class OrderLineItemDetail {
|
||||||
});
|
});
|
||||||
|
|
||||||
factory OrderLineItemDetail.fromJson(Map<String, dynamic> json) {
|
factory OrderLineItemDetail.fromJson(Map<String, dynamic> json) {
|
||||||
|
int safeInt(dynamic v) => v is int ? v : int.tryParse(v?.toString() ?? '') ?? 0;
|
||||||
|
double safeDouble(dynamic v) => v is num ? v.toDouble() : double.tryParse(v?.toString() ?? '') ?? 0.0;
|
||||||
|
String safeStr(dynamic v) => v?.toString() ?? '';
|
||||||
final modifiersJson = json['Modifiers'] as List<dynamic>? ?? [];
|
final modifiersJson = json['Modifiers'] as List<dynamic>? ?? [];
|
||||||
|
|
||||||
return OrderLineItemDetail(
|
return OrderLineItemDetail(
|
||||||
lineItemId: (json['LineItemID'] as num?)?.toInt() ?? 0,
|
lineItemId: safeInt(json['LineItemID']),
|
||||||
itemId: (json['ItemID'] as num?)?.toInt() ?? 0,
|
itemId: safeInt(json['ItemID']),
|
||||||
parentLineItemId: (json['ParentLineItemID'] as num?)?.toInt() ?? 0,
|
parentLineItemId: safeInt(json['ParentLineItemID']),
|
||||||
itemName: (json['ItemName'] as String?) ?? '',
|
itemName: safeStr(json['ItemName']),
|
||||||
quantity: (json['Quantity'] as num?)?.toInt() ?? 1,
|
quantity: safeInt(json['Quantity']),
|
||||||
unitPrice: (json['UnitPrice'] as num?)?.toDouble() ?? 0.0,
|
unitPrice: safeDouble(json['UnitPrice']),
|
||||||
remarks: (json['Remarks'] as String?) ?? '',
|
remarks: safeStr(json['Remarks']),
|
||||||
isDefault: json['IsDefault'] == true,
|
isDefault: json['IsDefault'] == true,
|
||||||
modifiers: modifiersJson
|
modifiers: modifiersJson
|
||||||
.map((e) => OrderLineItemDetail.fromJson(e as Map<String, dynamic>))
|
.map((e) => OrderLineItemDetail.fromJson(e as Map<String, dynamic>))
|
||||||
|
|
|
||||||
|
|
@ -28,20 +28,24 @@ class OrderHistoryItem {
|
||||||
});
|
});
|
||||||
|
|
||||||
factory OrderHistoryItem.fromJson(Map<String, dynamic> json) {
|
factory OrderHistoryItem.fromJson(Map<String, dynamic> json) {
|
||||||
|
int parseId(dynamic val) => val is int ? val : int.tryParse(val.toString()) ?? 0;
|
||||||
|
double parseDouble(dynamic val) => val is num ? val.toDouble() : double.tryParse(val.toString()) ?? 0.0;
|
||||||
|
String parseStr(dynamic val) => val?.toString() ?? "";
|
||||||
|
|
||||||
return OrderHistoryItem(
|
return OrderHistoryItem(
|
||||||
orderId: (json["OrderID"] as num).toInt(),
|
orderId: parseId(json["OrderID"]),
|
||||||
orderUuid: json["OrderUUID"] as String? ?? "",
|
orderUuid: parseStr(json["OrderUUID"]),
|
||||||
businessId: (json["BusinessID"] as num).toInt(),
|
businessId: parseId(json["BusinessID"]),
|
||||||
businessName: json["BusinessName"] as String? ?? "Unknown",
|
businessName: parseStr(json["BusinessName"]).isEmpty ? "Unknown" : parseStr(json["BusinessName"]),
|
||||||
total: (json["OrderTotal"] as num?)?.toDouble() ?? 0.0,
|
total: parseDouble(json["OrderTotal"]),
|
||||||
statusId: (json["OrderStatusID"] as num).toInt(),
|
statusId: parseId(json["OrderStatusID"]),
|
||||||
statusName: json["StatusName"] as String? ?? "Unknown",
|
statusName: parseStr(json["StatusName"]).isEmpty ? "Unknown" : parseStr(json["StatusName"]),
|
||||||
orderTypeId: (json["OrderTypeID"] as num?)?.toInt() ?? 0,
|
orderTypeId: parseId(json["OrderTypeID"]),
|
||||||
typeName: json["TypeName"] as String? ?? "Unknown",
|
typeName: parseStr(json["TypeName"]).isEmpty ? "Unknown" : parseStr(json["TypeName"]),
|
||||||
itemCount: (json["ItemCount"] as num?)?.toInt() ?? 0,
|
itemCount: parseId(json["ItemCount"]),
|
||||||
createdAt: DateTime.tryParse(json["CreatedAt"] as String? ?? "") ?? DateTime.now(),
|
createdAt: DateTime.tryParse(parseStr(json["CreatedAt"])) ?? DateTime.now(),
|
||||||
completedAt: json["CompletedAt"] != null && (json["CompletedAt"] as String).isNotEmpty
|
completedAt: parseStr(json["CompletedAt"]).isNotEmpty
|
||||||
? DateTime.tryParse(json["CompletedAt"] as String)
|
? DateTime.tryParse(parseStr(json["CompletedAt"]))
|
||||||
: null,
|
: null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,8 @@ class _AddressListScreenState extends State<AddressListScreen> {
|
||||||
_error!,
|
_error!,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: Theme.of(context).textTheme.bodySmall,
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
|
maxLines: 3,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
FilledButton.icon(
|
FilledButton.icon(
|
||||||
|
|
|
||||||
|
|
@ -561,7 +561,7 @@ class _CartViewScreenState extends State<CartViewScreen> {
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text(_error!, textAlign: TextAlign.center),
|
Text(_error!, textAlign: TextAlign.center, maxLines: 3, overflow: TextOverflow.ellipsis),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: _loadCart,
|
onPressed: _loadCart,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue