feat: order

This commit is contained in:
efrilm
2025-08-18 14:24:15 +07:00
parent 62eb15b27f
commit d3f2cb300c
19 changed files with 6669 additions and 277 deletions
@@ -0,0 +1,57 @@
import 'dart:developer';
import 'package:data_channel/data_channel.dart';
import 'package:injectable/injectable.dart';
import '../../../common/api/api_client.dart';
import '../../../common/api/api_failure.dart';
import '../../../common/function/app_function.dart';
import '../../../common/url/api_path.dart';
import '../../../domain/order/order.dart';
import '../order_dtos.dart';
@injectable
class OrderRemoteDataProvider {
final ApiClient _apiClient;
final String _logName = 'OrderRemoteDataProvider';
OrderRemoteDataProvider(this._apiClient);
Future<DC<OrderFailure, List<OrderDto>>> fetch({
int page = 1,
int limit = 10,
String? status,
String? search,
}) async {
try {
Map<String, dynamic> params = {'page': page, 'limit': limit};
if (status != null && status.isNotEmpty) {
params['status'] = status;
}
if (search != null && search.isNotEmpty) {
params['search'] = search;
}
final response = await _apiClient.get(
ApiPath.order,
params: params,
headers: getAuthorizationHeader(),
);
if (response.data['data'] == null) {
return DC.error(OrderFailure.empty());
}
final dto = (response.data['data']['orders'] as List)
.map((item) => OrderDto.fromJson(item))
.toList();
return DC.data(dto);
} on ApiFailure catch (e, s) {
log('fetchOrderError', name: _logName, error: e, stackTrace: s);
return DC.error(OrderFailure.serverError(e));
}
}
}
+183
View File
@@ -0,0 +1,183 @@
part of '../order_dtos.dart';
@freezed
class OrderDto with _$OrderDto {
const OrderDto._();
const factory OrderDto({
@JsonKey(name: 'id') String? id,
@JsonKey(name: 'order_number') String? orderNumber,
@JsonKey(name: 'outlet_id') String? outletId,
@JsonKey(name: 'user_id') String? userId,
@JsonKey(name: 'table_number') String? tableNumber,
@JsonKey(name: 'order_type') String? orderType,
@JsonKey(name: 'status') String? status,
@JsonKey(name: 'subtotal') int? subtotal,
@JsonKey(name: 'tax_amount') int? taxAmount,
@JsonKey(name: 'discount_amount') int? discountAmount,
@JsonKey(name: 'total_amount') int? totalAmount,
@JsonKey(name: 'total_cost') int? totalCost,
@JsonKey(name: 'remaining_amount') int? remainingAmount,
@JsonKey(name: 'payment_status') String? paymentStatus,
@JsonKey(name: 'refund_amount') int? refundAmount,
@JsonKey(name: 'is_void') bool? isVoid,
@JsonKey(name: 'is_refund') bool? isRefund,
@JsonKey(name: 'notes') String? notes,
@JsonKey(name: 'metadata') Map<String, dynamic>? metadata,
@JsonKey(name: 'created_at') String? createdAt,
@JsonKey(name: 'updated_at') String? updatedAt,
@JsonKey(name: 'order_items') List<OrderItemDto>? orderItems,
@JsonKey(name: 'payments') List<OrderPaymentDto>? payments,
@JsonKey(name: 'total_paid') int? totalPaid,
@JsonKey(name: 'payment_count') int? paymentCount,
@JsonKey(name: 'split_type') String? splitType,
}) = _OrderDto;
factory OrderDto.fromJson(Map<String, dynamic> json) =>
_$OrderDtoFromJson(json);
Order toDomain() => Order(
id: id ?? '',
orderNumber: orderNumber ?? '',
outletId: outletId ?? '',
userId: userId ?? '',
tableNumber: tableNumber ?? '',
orderType: orderType ?? '',
status: status ?? '',
subtotal: subtotal ?? 0,
taxAmount: taxAmount ?? 0,
discountAmount: discountAmount ?? 0,
totalAmount: totalAmount ?? 0,
totalCost: totalCost ?? 0,
remainingAmount: remainingAmount ?? 0,
paymentStatus: paymentStatus ?? '',
refundAmount: refundAmount ?? 0,
isVoid: isVoid ?? false,
isRefund: isRefund ?? false,
notes: notes ?? '',
metadata: metadata ?? {},
createdAt: createdAt ?? '',
updatedAt: updatedAt ?? '',
orderItems: orderItems?.map((e) => e.toDomain()).toList() ?? [],
payments: payments?.map((e) => e.toDomain()).toList() ?? [],
totalPaid: totalPaid ?? 0,
paymentCount: paymentCount ?? 0,
splitType: splitType ?? '',
);
}
@freezed
class OrderItemDto with _$OrderItemDto {
const OrderItemDto._();
const factory OrderItemDto({
@JsonKey(name: 'id') String? id,
@JsonKey(name: 'order_id') String? orderId,
@JsonKey(name: 'product_id') String? productId,
@JsonKey(name: 'product_name') String? productName,
@JsonKey(name: 'quantity') int? quantity,
@JsonKey(name: 'price') int? price,
@JsonKey(name: 'subtotal') int? subtotal,
@JsonKey(name: 'discount_amount') int? discountAmount,
@JsonKey(name: 'total') int? total,
@JsonKey(name: 'cost') int? cost,
@JsonKey(name: 'metadata') Map<String, dynamic>? metadata,
@JsonKey(name: 'created_at') String? createdAt,
@JsonKey(name: 'updated_at') String? updatedAt,
}) = _OrderItemDto;
factory OrderItemDto.fromJson(Map<String, dynamic> json) =>
_$OrderItemDtoFromJson(json);
OrderItem toDomain() => OrderItem(
id: id ?? '',
orderId: orderId ?? '',
productId: productId ?? '',
productName: productName ?? '',
quantity: quantity ?? 0,
price: price ?? 0,
subtotal: subtotal ?? 0,
discountAmount: discountAmount ?? 0,
total: total ?? 0,
cost: cost ?? 0,
metadata: metadata ?? {},
createdAt: createdAt ?? '',
updatedAt: updatedAt ?? '',
);
}
@freezed
class OrderPaymentDto with _$OrderPaymentDto {
const OrderPaymentDto._();
const factory OrderPaymentDto({
@JsonKey(name: 'id') String? id,
@JsonKey(name: 'order_id') String? orderId,
@JsonKey(name: 'payment_method_id') String? paymentMethodId,
@JsonKey(name: 'payment_method_name') String? paymentMethodName,
@JsonKey(name: 'payment_method_type') String? paymentMethodType,
@JsonKey(name: 'amount') int? amount,
@JsonKey(name: 'status') String? status,
@JsonKey(name: 'split_number') int? splitNumber,
@JsonKey(name: 'split_total') int? splitTotal,
@JsonKey(name: 'split_type') String? splitType,
@JsonKey(name: 'split_description') String? splitDescription,
@JsonKey(name: 'refund_amount') int? refundAmount,
@JsonKey(name: 'metadata') Map<String, dynamic>? metadata,
@JsonKey(name: 'created_at') String? createdAt,
@JsonKey(name: 'updated_at') String? updatedAt,
@JsonKey(name: 'payment_order_items')
List<PaymentOrderItemDto>? paymentOrderItems,
}) = _OrderPaymentDto;
factory OrderPaymentDto.fromJson(Map<String, dynamic> json) =>
_$OrderPaymentDtoFromJson(json);
OrderPayment toDomain() => OrderPayment(
id: id ?? '',
orderId: orderId ?? '',
paymentMethodId: paymentMethodId ?? '',
paymentMethodName: paymentMethodName ?? '',
paymentMethodType: paymentMethodType ?? '',
amount: amount ?? 0,
status: status ?? '',
splitNumber: splitNumber ?? 0,
splitTotal: splitTotal ?? 0,
splitType: splitType ?? '',
splitDescription: splitDescription ?? '',
refundAmount: refundAmount ?? 0,
metadata: metadata ?? {},
createdAt: createdAt ?? '',
updatedAt: updatedAt ?? '',
paymentOrderItems:
paymentOrderItems?.map((e) => e.toDomain()).toList() ?? [],
);
}
@freezed
class PaymentOrderItemDto with _$PaymentOrderItemDto {
const PaymentOrderItemDto._();
const factory PaymentOrderItemDto({
@JsonKey(name: 'id') String? id,
@JsonKey(name: 'order_payment_id') String? orderPaymentId,
@JsonKey(name: 'order_item_id') String? orderItemId,
@JsonKey(name: 'amount') int? amount,
@JsonKey(name: 'refund_amount') int? refundAmount,
@JsonKey(name: 'created_at') String? createdAt,
@JsonKey(name: 'updated_at') String? updatedAt,
}) = _PaymentOrderItemDto;
factory PaymentOrderItemDto.fromJson(Map<String, dynamic> json) =>
_$PaymentOrderItemDtoFromJson(json);
PaymentOrderItem toDomain() => PaymentOrderItem(
id: id ?? '',
orderPaymentId: orderPaymentId ?? '',
orderItemId: orderItemId ?? '',
amount: amount ?? 0,
refundAmount: refundAmount ?? 0,
createdAt: createdAt ?? '',
updatedAt: updatedAt ?? '',
);
}
+8
View File
@@ -0,0 +1,8 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import '../../domain/order/order.dart';
part 'order_dtos.freezed.dart';
part 'order_dtos.g.dart';
part 'dto/order_dto.dart';
File diff suppressed because it is too large Load Diff
+173
View File
@@ -0,0 +1,173 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'order_dtos.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$OrderDtoImpl _$$OrderDtoImplFromJson(Map<String, dynamic> json) =>
_$OrderDtoImpl(
id: json['id'] as String?,
orderNumber: json['order_number'] as String?,
outletId: json['outlet_id'] as String?,
userId: json['user_id'] as String?,
tableNumber: json['table_number'] as String?,
orderType: json['order_type'] as String?,
status: json['status'] as String?,
subtotal: (json['subtotal'] as num?)?.toInt(),
taxAmount: (json['tax_amount'] as num?)?.toInt(),
discountAmount: (json['discount_amount'] as num?)?.toInt(),
totalAmount: (json['total_amount'] as num?)?.toInt(),
totalCost: (json['total_cost'] as num?)?.toInt(),
remainingAmount: (json['remaining_amount'] as num?)?.toInt(),
paymentStatus: json['payment_status'] as String?,
refundAmount: (json['refund_amount'] as num?)?.toInt(),
isVoid: json['is_void'] as bool?,
isRefund: json['is_refund'] as bool?,
notes: json['notes'] as String?,
metadata: json['metadata'] as Map<String, dynamic>?,
createdAt: json['created_at'] as String?,
updatedAt: json['updated_at'] as String?,
orderItems: (json['order_items'] as List<dynamic>?)
?.map((e) => OrderItemDto.fromJson(e as Map<String, dynamic>))
.toList(),
payments: (json['payments'] as List<dynamic>?)
?.map((e) => OrderPaymentDto.fromJson(e as Map<String, dynamic>))
.toList(),
totalPaid: (json['total_paid'] as num?)?.toInt(),
paymentCount: (json['payment_count'] as num?)?.toInt(),
splitType: json['split_type'] as String?,
);
Map<String, dynamic> _$$OrderDtoImplToJson(_$OrderDtoImpl instance) =>
<String, dynamic>{
'id': instance.id,
'order_number': instance.orderNumber,
'outlet_id': instance.outletId,
'user_id': instance.userId,
'table_number': instance.tableNumber,
'order_type': instance.orderType,
'status': instance.status,
'subtotal': instance.subtotal,
'tax_amount': instance.taxAmount,
'discount_amount': instance.discountAmount,
'total_amount': instance.totalAmount,
'total_cost': instance.totalCost,
'remaining_amount': instance.remainingAmount,
'payment_status': instance.paymentStatus,
'refund_amount': instance.refundAmount,
'is_void': instance.isVoid,
'is_refund': instance.isRefund,
'notes': instance.notes,
'metadata': instance.metadata,
'created_at': instance.createdAt,
'updated_at': instance.updatedAt,
'order_items': instance.orderItems,
'payments': instance.payments,
'total_paid': instance.totalPaid,
'payment_count': instance.paymentCount,
'split_type': instance.splitType,
};
_$OrderItemDtoImpl _$$OrderItemDtoImplFromJson(Map<String, dynamic> json) =>
_$OrderItemDtoImpl(
id: json['id'] as String?,
orderId: json['order_id'] as String?,
productId: json['product_id'] as String?,
productName: json['product_name'] as String?,
quantity: (json['quantity'] as num?)?.toInt(),
price: (json['price'] as num?)?.toInt(),
subtotal: (json['subtotal'] as num?)?.toInt(),
discountAmount: (json['discount_amount'] as num?)?.toInt(),
total: (json['total'] as num?)?.toInt(),
cost: (json['cost'] as num?)?.toInt(),
metadata: json['metadata'] as Map<String, dynamic>?,
createdAt: json['created_at'] as String?,
updatedAt: json['updated_at'] as String?,
);
Map<String, dynamic> _$$OrderItemDtoImplToJson(_$OrderItemDtoImpl instance) =>
<String, dynamic>{
'id': instance.id,
'order_id': instance.orderId,
'product_id': instance.productId,
'product_name': instance.productName,
'quantity': instance.quantity,
'price': instance.price,
'subtotal': instance.subtotal,
'discount_amount': instance.discountAmount,
'total': instance.total,
'cost': instance.cost,
'metadata': instance.metadata,
'created_at': instance.createdAt,
'updated_at': instance.updatedAt,
};
_$OrderPaymentDtoImpl _$$OrderPaymentDtoImplFromJson(
Map<String, dynamic> json,
) => _$OrderPaymentDtoImpl(
id: json['id'] as String?,
orderId: json['order_id'] as String?,
paymentMethodId: json['payment_method_id'] as String?,
paymentMethodName: json['payment_method_name'] as String?,
paymentMethodType: json['payment_method_type'] as String?,
amount: (json['amount'] as num?)?.toInt(),
status: json['status'] as String?,
splitNumber: (json['split_number'] as num?)?.toInt(),
splitTotal: (json['split_total'] as num?)?.toInt(),
splitType: json['split_type'] as String?,
splitDescription: json['split_description'] as String?,
refundAmount: (json['refund_amount'] as num?)?.toInt(),
metadata: json['metadata'] as Map<String, dynamic>?,
createdAt: json['created_at'] as String?,
updatedAt: json['updated_at'] as String?,
paymentOrderItems: (json['payment_order_items'] as List<dynamic>?)
?.map((e) => PaymentOrderItemDto.fromJson(e as Map<String, dynamic>))
.toList(),
);
Map<String, dynamic> _$$OrderPaymentDtoImplToJson(
_$OrderPaymentDtoImpl instance,
) => <String, dynamic>{
'id': instance.id,
'order_id': instance.orderId,
'payment_method_id': instance.paymentMethodId,
'payment_method_name': instance.paymentMethodName,
'payment_method_type': instance.paymentMethodType,
'amount': instance.amount,
'status': instance.status,
'split_number': instance.splitNumber,
'split_total': instance.splitTotal,
'split_type': instance.splitType,
'split_description': instance.splitDescription,
'refund_amount': instance.refundAmount,
'metadata': instance.metadata,
'created_at': instance.createdAt,
'updated_at': instance.updatedAt,
'payment_order_items': instance.paymentOrderItems,
};
_$PaymentOrderItemDtoImpl _$$PaymentOrderItemDtoImplFromJson(
Map<String, dynamic> json,
) => _$PaymentOrderItemDtoImpl(
id: json['id'] as String?,
orderPaymentId: json['order_payment_id'] as String?,
orderItemId: json['order_item_id'] as String?,
amount: (json['amount'] as num?)?.toInt(),
refundAmount: (json['refund_amount'] as num?)?.toInt(),
createdAt: json['created_at'] as String?,
updatedAt: json['updated_at'] as String?,
);
Map<String, dynamic> _$$PaymentOrderItemDtoImplToJson(
_$PaymentOrderItemDtoImpl instance,
) => <String, dynamic>{
'id': instance.id,
'order_payment_id': instance.orderPaymentId,
'order_item_id': instance.orderItemId,
'amount': instance.amount,
'refund_amount': instance.refundAmount,
'created_at': instance.createdAt,
'updated_at': instance.updatedAt,
};
@@ -0,0 +1,43 @@
import 'dart:developer';
import 'package:dartz/dartz.dart' hide Order;
import 'package:injectable/injectable.dart' hide Order;
import '../../../domain/order/order.dart';
import '../datasource/remote_data_provider.dart';
@Injectable(as: IOrderRepository)
class OrderRepository implements IOrderRepository {
final OrderRemoteDataProvider _dataProvider;
final String _logName = 'OrderRepository';
OrderRepository(this._dataProvider);
@override
Future<Either<OrderFailure, List<Order>>> get({
int page = 1,
int limit = 20,
String? status,
String? search,
}) async {
try {
final result = await _dataProvider.fetch(
page: page,
limit: limit,
status: status,
search: search,
);
if (result.hasError) {
return left(result.error!);
}
final auth = result.data!.map((e) => e.toDomain()).toList();
return right(auth);
} catch (e, s) {
log('getOrderError', name: _logName, error: e, stackTrace: s);
return left(const OrderFailure.unexpectedError());
}
}
}