From 2c8b1333d8bf81d4527f815964ed4cfaa520896d Mon Sep 17 00:00:00 2001 From: efrilm Date: Thu, 7 Aug 2025 23:59:01 +0700 Subject: [PATCH] feat: order response model --- .../models/response/order_response_model.dart | 420 +++++++++++------- .../sales/widgets/sales_list_order.dart | 43 -- .../split_bill/pages/split_bill_page.dart | 186 ++++---- 3 files changed, 360 insertions(+), 289 deletions(-) diff --git a/lib/data/models/response/order_response_model.dart b/lib/data/models/response/order_response_model.dart index 8fbffca..e768f1b 100644 --- a/lib/data/models/response/order_response_model.dart +++ b/lib/data/models/response/order_response_model.dart @@ -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 json) => - OrderResponseModel( - success: json["success"], - data: json["data"] == null ? null : OrderData.fromMap(json["data"]), - errors: json["errors"], - ); - - Map 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 map) { + return OrderResponseModel( + success: map['success'] ?? false, + data: OrderData.fromMap(map['data']), + ); + } + + Map toMap() { + return { + 'success': success, + 'data': data?.toMap(), + }; + } +} + class OrderData { final List? orders; + final List? 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 json) => OrderData( - orders: json["orders"] == null - ? [] - : List.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 map) { + return OrderData( + orders: map["orders"] == null + ? [] + : List.from(map['orders']?.map((x) => Order.fromMap(x))), + payments: map["orders"] == null + ? [] + : List.from(map['payments']?.map((x) => Payment.fromMap(x))), + totalCount: map['total_count'], + page: map['page'], + limit: map['limit'], + totalPages: map['total_pages'], + ); + } - Map toMap() => { - "orders": orders == null - ? [] - : List.from(orders!.map((x) => x.toMap())), - "total_count": totalCount, - "page": page, - "limit": limit, - "total_pages": totalPages, - }; + Map 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? metadata; final DateTime? createdAt; final DateTime? updatedAt; final List? orderItems; - final bool? isRefund; + final List? 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 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.from( - json["order_items"].map((x) => OrderItem.fromMap(x))), - ); + factory Order.fromMap(Map 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.from( + map['order_items'].map((x) => OrderItem.fromMap(x))), + payments: map["payments"] == null + ? [] + : List.from(map['payments'].map((x) => Payment.fromMap(x))), + totalPaid: map['total_paid'], + paymentCount: map['payment_count'], + ); + } - Map 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.from(orderItems!.map((x) => x.toMap())), - }; + Map 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? 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? 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 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 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.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 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 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? 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 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 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(), + }; + } } diff --git a/lib/presentation/sales/widgets/sales_list_order.dart b/lib/presentation/sales/widgets/sales_list_order.dart index 30098f1..e21fefe 100644 --- a/lib/presentation/sales/widgets/sales_list_order.dart +++ b/lib/presentation/sales/widgets/sales_list_order.dart @@ -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() - .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() - .add(OrderFormEvent.toggleItem(product)); - }, - ), - ), - const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/presentation/split_bill/pages/split_bill_page.dart b/lib/presentation/split_bill/pages/split_bill_page.dart index c10c57f..e194559 100644 --- a/lib/presentation/split_bill/pages/split_bill_page.dart +++ b/lib/presentation/split_bill/pages/split_bill_page.dart @@ -587,114 +587,112 @@ class _SplitBillPageState extends State { ), ), 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, ), - ], - ), - ], - ), + ), + ], + ), + ], ), - ], - ), + ), + ], ), ], );