feat: order response model

This commit is contained in:
efrilm 2025-08-07 23:59:01 +07:00
parent b1a1303a40
commit 2c8b1333d8
3 changed files with 360 additions and 289 deletions

View File

@ -1,35 +1,5 @@
import 'dart:convert';
class OrderResponseModel {
final bool? success;
final OrderData? data;
final dynamic errors;
OrderResponseModel({
this.success,
this.data,
this.errors,
});
factory OrderResponseModel.fromJson(String str) =>
OrderResponseModel.fromMap(json.decode(str));
String toJson() => json.encode(toMap());
factory OrderResponseModel.fromMap(Map<String, dynamic> json) =>
OrderResponseModel(
success: json["success"],
data: json["data"] == null ? null : OrderData.fromMap(json["data"]),
errors: json["errors"],
);
Map<String, dynamic> toMap() => {
"success": success,
"data": data?.toMap(),
"errors": errors,
};
}
class OrderDetailResponseModel {
final bool? success;
final Order? data;
@ -60,40 +30,77 @@ class OrderDetailResponseModel {
};
}
class OrderResponseModel {
final bool? success;
final OrderData? data;
OrderResponseModel({
this.success,
this.data,
});
factory OrderResponseModel.fromJson(String str) =>
OrderResponseModel.fromMap(json.decode(str));
String toJson() => json.encode(toMap());
factory OrderResponseModel.fromMap(Map<String, dynamic> map) {
return OrderResponseModel(
success: map['success'] ?? false,
data: OrderData.fromMap(map['data']),
);
}
Map<String, dynamic> toMap() {
return {
'success': success,
'data': data?.toMap(),
};
}
}
class OrderData {
final List<Order>? orders;
final List<Payment>? payments;
final int? totalCount;
final int? page;
final int? limit;
final int? totalPages;
OrderData({
this.orders,
this.totalCount,
this.page,
this.limit,
this.totalPages,
required this.orders,
required this.payments,
required this.totalCount,
required this.page,
required this.limit,
required this.totalPages,
});
factory OrderData.fromMap(Map<String, dynamic> json) => OrderData(
orders: json["orders"] == null
? []
: List<Order>.from(json["orders"].map((x) => Order.fromMap(x))),
totalCount: json["total_count"],
page: json["page"],
limit: json["limit"],
totalPages: json["total_pages"],
);
factory OrderData.fromMap(Map<String, dynamic> map) {
return OrderData(
orders: map["orders"] == null
? []
: List<Order>.from(map['orders']?.map((x) => Order.fromMap(x))),
payments: map["orders"] == null
? []
: List<Payment>.from(map['payments']?.map((x) => Payment.fromMap(x))),
totalCount: map['total_count'],
page: map['page'],
limit: map['limit'],
totalPages: map['total_pages'],
);
}
Map<String, dynamic> toMap() => {
"orders": orders == null
? []
: List<dynamic>.from(orders!.map((x) => x.toMap())),
"total_count": totalCount,
"page": page,
"limit": limit,
"total_pages": totalPages,
};
Map<String, dynamic> toMap() {
return {
'orders': orders?.map((x) => x.toMap()).toList(),
'payments': payments?.map((x) => x.toMap()).toList(),
'total_count': totalCount,
'page': page,
'limit': limit,
'total_pages': totalPages,
};
}
}
class Order {
@ -108,12 +115,20 @@ class Order {
final int? taxAmount;
final int? discountAmount;
final int? totalAmount;
final int? totalCost;
final int? remainingAmount;
final String? paymentStatus;
final int? refundAmount;
final bool? isVoid;
final bool? isRefund;
final String? notes;
final Map<String, dynamic>? metadata;
final DateTime? createdAt;
final DateTime? updatedAt;
final List<OrderItem>? orderItems;
final bool? isRefund;
final List<Payment>? payments;
final int? totalPaid;
final int? paymentCount;
Order({
this.id,
@ -127,79 +142,104 @@ class Order {
this.taxAmount,
this.discountAmount,
this.totalAmount,
this.totalCost,
this.remainingAmount,
this.paymentStatus,
this.refundAmount,
this.isVoid,
this.isRefund,
this.notes,
this.metadata,
this.createdAt,
this.updatedAt,
this.orderItems,
this.isRefund,
this.payments,
this.totalPaid,
this.paymentCount,
});
factory Order.fromMap(Map<String, dynamic> json) => Order(
id: json["id"],
orderNumber: json["order_number"],
outletId: json["outlet_id"],
userId: json["user_id"],
tableNumber: json["table_number"],
orderType: json["order_type"],
status: json["status"],
subtotal: json["subtotal"],
taxAmount: json["tax_amount"],
discountAmount: json["discount_amount"],
totalAmount: json["total_amount"],
notes: json["notes"],
metadata: json["metadata"] ?? {},
isRefund: json["is_refund"],
createdAt: json["created_at"] == null
? null
: DateTime.parse(json["created_at"]),
updatedAt: json["updated_at"] == null
? null
: DateTime.parse(json["updated_at"]),
orderItems: json["order_items"] == null
? []
: List<OrderItem>.from(
json["order_items"].map((x) => OrderItem.fromMap(x))),
);
factory Order.fromMap(Map<String, dynamic> map) {
return Order(
id: map['id'],
orderNumber: map['order_number'],
outletId: map['outlet_id'],
userId: map['user_id'],
tableNumber: map['table_number'],
orderType: map['order_type'],
status: map['status'],
subtotal: map['subtotal'],
taxAmount: map['tax_amount'],
discountAmount: map['discount_amount'],
totalAmount: map['total_amount'],
totalCost: map['total_cost'],
remainingAmount: map['remaining_amount'],
paymentStatus: map['payment_status'],
refundAmount: map['refund_amount'],
isVoid: map['is_void'],
isRefund: map['is_refund'],
notes: map['notes'],
metadata: map['metadata'] ?? {},
createdAt: DateTime.parse(map['created_at']),
updatedAt: DateTime.parse(map['updated_at']),
orderItems: map["order_items"] == null
? []
: List<OrderItem>.from(
map['order_items'].map((x) => OrderItem.fromMap(x))),
payments: map["payments"] == null
? []
: List<Payment>.from(map['payments'].map((x) => Payment.fromMap(x))),
totalPaid: map['total_paid'],
paymentCount: map['payment_count'],
);
}
Map<String, dynamic> toMap() => {
"id": id,
"order_number": orderNumber,
"outlet_id": outletId,
"user_id": userId,
"table_number": tableNumber,
"order_type": orderType,
"status": status,
"subtotal": subtotal,
"tax_amount": taxAmount,
"discount_amount": discountAmount,
"total_amount": totalAmount,
"notes": notes,
"metadata": metadata,
"created_at": createdAt?.toIso8601String(),
"updated_at": updatedAt?.toIso8601String(),
"is_refund": isRefund,
"order_items": orderItems == null
? []
: List<dynamic>.from(orderItems!.map((x) => x.toMap())),
};
Map<String, dynamic> toMap() {
return {
'id': id,
'order_number': orderNumber,
'outlet_id': outletId,
'user_id': userId,
'table_number': tableNumber,
'order_type': orderType,
'status': status,
'subtotal': subtotal,
'tax_amount': taxAmount,
'discount_amount': discountAmount,
'total_amount': totalAmount,
'total_cost': totalCost,
'remaining_amount': remainingAmount,
'payment_status': paymentStatus,
'refund_amount': refundAmount,
'is_void': isVoid,
'is_refund': isRefund,
'notes': notes,
'metadata': metadata,
'created_at': createdAt?.toIso8601String(),
'updated_at': updatedAt?.toIso8601String(),
'order_items': orderItems?.map((x) => x.toMap()).toList(),
'payments': payments?.map((x) => x.toMap()).toList(),
'total_paid': totalPaid,
'payment_count': paymentCount,
};
}
}
class OrderItem {
final String? id;
final String? orderId;
final String? productId;
final String? productName;
final String? productVariantId;
final String? productVariantName;
final int? quantity;
final int? unitPrice;
final int? totalPrice;
final List<dynamic>? modifiers;
final String? notes;
final String? status;
final DateTime? createdAt;
final DateTime? updatedAt;
String? id;
String? orderId;
String? productId;
String? productName;
String? productVariantId;
String? productVariantName;
int? quantity;
int? unitPrice;
int? totalPrice;
List<dynamic>? modifiers;
String? notes;
String? status;
DateTime? createdAt;
DateTime? updatedAt;
String? printerType;
OrderItem({
this.id,
@ -216,43 +256,119 @@ class OrderItem {
this.status,
this.createdAt,
this.updatedAt,
this.printerType,
});
factory OrderItem.fromMap(Map<String, dynamic> json) => OrderItem(
id: json["id"],
orderId: json["order_id"],
productId: json["product_id"],
productName: json["product_name"],
productVariantId: json["product_variant_id"],
productVariantName: json["product_variant_name"],
quantity: json["quantity"],
unitPrice: json["unit_price"],
totalPrice: json["total_price"],
modifiers: json["modifiers"] ?? [],
notes: json["notes"],
status: json["status"],
createdAt: json["created_at"] == null
? null
: DateTime.parse(json["created_at"]),
updatedAt: json["updated_at"] == null
? null
: DateTime.parse(json["updated_at"]),
);
factory OrderItem.fromMap(Map<String, dynamic> map) {
return OrderItem(
id: map['id'],
orderId: map['order_id'],
productId: map['product_id'],
productName: map['product_name'],
productVariantId: map['product_variant_id'],
productVariantName: map['product_variant_name'],
quantity: map['quantity'],
unitPrice: map['unit_price'],
totalPrice: map['total_price'],
modifiers:
map['modifiers'] == null ? [] : List<dynamic>.from(map['modifiers']),
notes: map['notes'],
status: map['status'],
createdAt: DateTime.parse(map['created_at']),
updatedAt: DateTime.parse(map['updated_at']),
printerType: map['printer_type'],
);
}
Map<String, dynamic> toMap() => {
"id": id,
"order_id": orderId,
"product_id": productId,
"product_name": productName,
"product_variant_id": productVariantId,
"product_variant_name": productVariantName,
"quantity": quantity,
"unit_price": unitPrice,
"total_price": totalPrice,
"modifiers": modifiers,
"notes": notes,
"status": status,
"created_at": createdAt?.toIso8601String(),
"updated_at": updatedAt?.toIso8601String(),
};
Map<String, dynamic> toMap() {
return {
'id': id,
'order_id': orderId,
'product_id': productId,
'product_name': productName,
'product_variant_id': productVariantId,
'product_variant_name': productVariantName,
'quantity': quantity,
'unit_price': unitPrice,
'total_price': totalPrice,
'modifiers': modifiers,
'notes': notes,
'status': status,
'created_at': createdAt?.toIso8601String(),
'updated_at': updatedAt?.toIso8601String(),
'printer_type': printerType,
};
}
}
class Payment {
final String? id;
final String? orderId;
final String? paymentMethodId;
final String? paymentMethodName;
final String? paymentMethodType;
final int? amount;
final String? status;
final int? splitNumber;
final int? splitTotal;
final String? splitDescription;
final int? refundAmount;
final Map<String, dynamic>? metadata;
final DateTime? createdAt;
final DateTime? updatedAt;
Payment({
this.id,
this.orderId,
this.paymentMethodId,
this.paymentMethodName,
this.paymentMethodType,
this.amount,
this.status,
this.splitNumber,
this.splitTotal,
this.splitDescription,
this.refundAmount,
this.metadata,
this.createdAt,
this.updatedAt,
});
factory Payment.fromMap(Map<String, dynamic> map) {
return Payment(
id: map['id'],
orderId: map['order_id'],
paymentMethodId: map['payment_method_id'],
paymentMethodName: map['payment_method_name'],
paymentMethodType: map['payment_method_type'],
amount: map['amount'],
status: map['status'],
splitNumber: map['split_number'],
splitTotal: map['split_total'],
splitDescription: map['split_description'],
refundAmount: map['refund_amount'],
metadata: map['metadata'] ?? {},
createdAt: DateTime.parse(map['created_at']),
updatedAt: DateTime.parse(map['updated_at']),
);
}
Map<String, dynamic> toMap() {
return {
'id': id,
'order_id': orderId,
'payment_method_id': paymentMethodId,
'payment_method_name': paymentMethodName,
'payment_method_type': paymentMethodType,
'amount': amount,
'status': status,
'split_number': splitNumber,
'split_total': splitTotal,
'split_description': splitDescription,
'refund_amount': refundAmount,
'metadata': metadata,
'created_at': createdAt?.toIso8601String(),
'updated_at': updatedAt?.toIso8601String(),
};
}
}

View File

@ -63,27 +63,6 @@ class SalesListOrder extends StatelessWidget {
),
child: Row(
children: [
Container(
decoration: BoxDecoration(
color: AppColors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: isAllSelected ? AppColors.primary : Colors.grey.shade300,
width: 2,
),
),
child: Checkbox(
value: isAllSelected,
activeColor: AppColors.primary,
checkColor: AppColors.white,
onChanged: (val) {
context
.read<OrderFormBloc>()
.add(OrderFormEvent.toggleSelectAll(val ?? false));
},
),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -179,28 +158,6 @@ class SalesListOrder extends StatelessWidget {
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
color: AppColors.white,
borderRadius: BorderRadius.circular(6),
border: Border.all(
color:
isSelected ? AppColors.primary : Colors.grey.shade300,
width: 1.5,
),
),
child: Checkbox(
value: isSelected,
activeColor: AppColors.primary,
checkColor: AppColors.white,
onChanged: (_) {
context
.read<OrderFormBloc>()
.add(OrderFormEvent.toggleItem(product));
},
),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,

View File

@ -587,114 +587,112 @@ class _SplitBillPageState extends State<SplitBillPage> {
),
),
SizedBox(height: 16),
Expanded(
child: Column(
children: [
Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: AppColorSplitBill.cardBackground,
border: Border.all(color: AppColorSplitBill.border),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Split Bill',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: AppColorSplitBill.primary,
),
Column(
children: [
Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: AppColorSplitBill.cardBackground,
border: Border.all(color: AppColorSplitBill.border),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Split Bill',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: AppColorSplitBill.primary,
),
SizedBox(height: 16),
Text(
'Jumlah yang akan dibayar:',
style: TextStyle(
fontSize: 14,
color: AppColorSplitBill.textSecondary,
),
),
SizedBox(height: 16),
Text(
'Jumlah yang akan dibayar:',
style: TextStyle(
fontSize: 14,
color: AppColorSplitBill.textSecondary,
),
SizedBox(height: 8),
Container(
decoration: BoxDecoration(
border: Border.all(color: AppColorSplitBill.border),
borderRadius: BorderRadius.circular(8),
),
SizedBox(height: 8),
Container(
decoration: BoxDecoration(
border: Border.all(color: AppColorSplitBill.border),
borderRadius: BorderRadius.circular(8),
),
child: TextField(
controller: amountController,
keyboardType: TextInputType.number,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: AppColorSplitBill.textPrimary,
),
child: TextField(
controller: amountController,
keyboardType: TextInputType.number,
style: TextStyle(
onChanged: (value) {
setState(() {
splitAmount = int.tryParse(value) ?? 0;
});
},
decoration: InputDecoration(
hintText: '0',
prefixText: 'Rp ',
prefixStyle: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: AppColorSplitBill.textPrimary,
),
onChanged: (value) {
setState(() {
splitAmount = int.tryParse(value) ?? 0;
});
},
decoration: InputDecoration(
hintText: '0',
prefixText: 'Rp ',
prefixStyle: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: AppColorSplitBill.textPrimary,
),
border: InputBorder.none,
contentPadding: EdgeInsets.all(16),
),
border: InputBorder.none,
contentPadding: EdgeInsets.all(16),
),
),
SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Total yang dibayar:',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: AppColorSplitBill.textPrimary,
),
),
SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Total yang dibayar:',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: AppColorSplitBill.textPrimary,
),
Text(
'Rp ${_formatCurrency(splitAmount)}',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: AppColorSplitBill.primary,
),
),
Text(
'Rp ${_formatCurrency(splitAmount)}',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: AppColorSplitBill.primary,
),
],
),
SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Sisa bill:',
style: TextStyle(
fontSize: 14,
color: AppColorSplitBill.textSecondary,
),
),
],
),
SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Sisa bill:',
style: TextStyle(
fontSize: 14,
color: AppColorSplitBill.textSecondary,
),
Text(
'Rp ${_formatCurrency((widget.order.totalAmount ?? 0) - splitAmount)}',
style: TextStyle(
fontSize: 14,
color: AppColorSplitBill.textSecondary,
),
),
Text(
'Rp ${_formatCurrency((widget.order.totalAmount ?? 0) - splitAmount)}',
style: TextStyle(
fontSize: 14,
color: AppColorSplitBill.textSecondary,
),
],
),
],
),
),
],
),
],
),
],
),
),
],
),
],
);