create order with payment

This commit is contained in:
efrilm
2025-10-28 00:58:39 +07:00
parent 37f0008ec8
commit 137f3d9636
20 changed files with 2815 additions and 1086 deletions
@@ -83,4 +83,72 @@ class OrderRemoteDataProvider {
return DC.error(OrderFailure.serverError(e));
}
}
Future<DC<OrderFailure, OrderDto>> storeWithPaymentOrder({
required OrderRequestDto request,
required String paymentMethodId,
}) async {
try {
final response = await _apiClient.post(
ApiPath.orders,
data: request.toRequest(),
headers: getAuthorizationHeader(),
);
if (response.data['success'] == false) {
return DC.error(OrderFailure.unexpectedError());
} else {
final order = OrderDto.fromJson(
response.data['data'] as Map<String, dynamic>,
);
final paymentRequest = PaymentRequestDto(
orderId: order.id,
amount: order.totalAmount,
paymentMethodId: paymentMethodId,
splitNumber: 1,
splitTotal: 1,
splitDescription: '',
paymentOrderItems: order.orderItems
?.map(
(item) => PaymentItemRequestDto(
amount: item.totalPrice,
orderItemId: item.id,
),
)
.toList(),
);
storePayment(paymentRequest);
return DC.data(order);
}
} on ApiFailure catch (e, s) {
log('storeOrderError', name: _logName, error: e, stackTrace: s);
return DC.error(OrderFailure.serverError(e));
}
}
Future<DC<OrderFailure, PaymentDto>> storePayment(
PaymentRequestDto request,
) async {
try {
final response = await _apiClient.post(
ApiPath.payments,
data: request.toJson(),
headers: getAuthorizationHeader(),
);
if (response.data['success'] == false) {
return DC.error(OrderFailure.unexpectedError());
}
final payment = PaymentDto.fromJson(
response.data['data'] as Map<String, dynamic>,
);
return DC.data(payment);
} on ApiFailure catch (e, s) {
log('storePaymentError', name: _logName, error: e, stackTrace: s);
return DC.error(OrderFailure.serverError(e));
}
}
}
+1 -44
View File
@@ -51,7 +51,7 @@ class OrderDto with _$OrderDto {
@JsonKey(name: "created_at") String? createdAt,
@JsonKey(name: "updated_at") String? updatedAt,
@JsonKey(name: "order_items") List<OrderItemDto>? orderItems,
@JsonKey(name: "payments") List<PaymentOrderDto>? payments,
@JsonKey(name: "payments") List<PaymentDto>? payments,
@JsonKey(name: "total_paid") int? totalPaid,
@JsonKey(name: "payment_count") int? paymentCount,
@JsonKey(name: "split_type") String? splitType,
@@ -137,46 +137,3 @@ class OrderItemDto with _$OrderItemDto {
paidQuantity: paidQuantity ?? 0,
);
}
@freezed
class PaymentOrderDto with _$PaymentOrderDto {
const PaymentOrderDto._();
const factory PaymentOrderDto({
@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_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,
}) = _PaymentOrderDto;
factory PaymentOrderDto.fromJson(Map<String, dynamic> json) =>
_$PaymentOrderDtoFromJson(json);
// Optional mapper ke domain entity
PaymentOrder toDomain() => PaymentOrder(
id: id ?? '',
orderId: orderId ?? '',
paymentMethodId: paymentMethodId ?? '',
paymentMethodName: paymentMethodName ?? '',
paymentMethodType: paymentMethodType ?? '',
amount: amount ?? 0,
status: status ?? '',
splitNumber: splitNumber ?? 0,
splitTotal: splitTotal ?? 0,
splitDescription: splitDescription ?? '',
refundAmount: refundAmount ?? 0,
metadata: metadata ?? const {},
createdAt: createdAt != null ? DateTime.parse(createdAt!) : DateTime(1970),
updatedAt: updatedAt != null ? DateTime.parse(updatedAt!) : DateTime(1970),
);
}
@@ -0,0 +1,44 @@
part of '../order_dtos.dart';
@freezed
class PaymentDto with _$PaymentDto {
const PaymentDto._();
const factory PaymentDto({
@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_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,
}) = _PaymentOrderDto;
factory PaymentDto.fromJson(Map<String, dynamic> json) =>
_$PaymentDtoFromJson(json);
// Optional mapper ke domain entity
Payment toDomain() => Payment(
id: id ?? '',
orderId: orderId ?? '',
paymentMethodId: paymentMethodId ?? '',
paymentMethodName: paymentMethodName ?? '',
paymentMethodType: paymentMethodType ?? '',
amount: amount ?? 0,
status: status ?? '',
splitNumber: splitNumber ?? 0,
splitTotal: splitTotal ?? 0,
splitDescription: splitDescription ?? '',
refundAmount: refundAmount ?? 0,
metadata: metadata ?? const {},
createdAt: createdAt != null ? DateTime.parse(createdAt!) : DateTime(1970),
updatedAt: updatedAt != null ? DateTime.parse(updatedAt!) : DateTime(1970),
);
}
@@ -0,0 +1,51 @@
part of '../order_dtos.dart';
@freezed
class PaymentRequestDto with _$PaymentRequestDto {
const PaymentRequestDto._();
const factory PaymentRequestDto({
@JsonKey(name: "order_id") String? orderId,
@JsonKey(name: "payment_method_id") String? paymentMethodId,
@JsonKey(name: "amount") int? amount,
@JsonKey(name: "transaction_id") String? transactionId,
@JsonKey(name: "split_number") int? splitNumber,
@JsonKey(name: "split_total") int? splitTotal,
@JsonKey(name: "split_description") String? splitDescription,
@JsonKey(name: "payment_order_items")
List<PaymentItemRequestDto>? paymentOrderItems,
}) = _PaymentRequestDto;
factory PaymentRequestDto.fromJson(Map<String, dynamic> json) =>
_$PaymentRequestDtoFromJson(json);
// Optional mapper ke domain
PaymentRequest toDomain() => PaymentRequest(
orderId: orderId ?? '',
paymentMethodId: paymentMethodId ?? '',
amount: amount ?? 0,
transactionId: transactionId ?? '',
splitNumber: splitNumber ?? 0,
splitTotal: splitTotal ?? 0,
splitDescription: splitDescription ?? '',
paymentOrderItems:
paymentOrderItems?.map((e) => e.toDomain()).toList() ?? const [],
);
}
@freezed
class PaymentItemRequestDto with _$PaymentItemRequestDto {
const PaymentItemRequestDto._();
const factory PaymentItemRequestDto({
@JsonKey(name: "order_item_id") String? orderItemId,
@JsonKey(name: "amount") int? amount,
}) = _PaymentItemRequestDto;
factory PaymentItemRequestDto.fromJson(Map<String, dynamic> json) =>
_$PaymentItemRequestDtoFromJson(json);
// Optional: mapper ke domain entity
PaymentItemRequest toDomain() =>
PaymentItemRequest(orderItemId: orderItemId ?? '', amount: amount ?? 0);
}
+2
View File
@@ -7,3 +7,5 @@ part 'order_dtos.g.dart';
part 'dtos/order_dto.dart';
part 'dtos/order_request_dto.dart';
part 'dtos/payment_request_dto.dart';
part 'dtos/payment_dto.dart';
File diff suppressed because it is too large Load Diff
+81 -39
View File
@@ -53,7 +53,7 @@ _$OrderDtoImpl _$$OrderDtoImplFromJson(Map<String, dynamic> json) =>
?.map((e) => OrderItemDto.fromJson(e as Map<String, dynamic>))
.toList(),
payments: (json['payments'] as List<dynamic>?)
?.map((e) => PaymentOrderDto.fromJson(e as Map<String, dynamic>))
?.map((e) => PaymentDto.fromJson(e as Map<String, dynamic>))
.toList(),
totalPaid: (json['total_paid'] as num?)?.toInt(),
paymentCount: (json['payment_count'] as num?)?.toInt(),
@@ -130,44 +130,6 @@ Map<String, dynamic> _$$OrderItemDtoImplToJson(_$OrderItemDtoImpl instance) =>
'paid_quantity': instance.paidQuantity,
};
_$PaymentOrderDtoImpl _$$PaymentOrderDtoImplFromJson(
Map<String, dynamic> json,
) => _$PaymentOrderDtoImpl(
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(),
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?,
);
Map<String, dynamic> _$$PaymentOrderDtoImplToJson(
_$PaymentOrderDtoImpl 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_description': instance.splitDescription,
'refund_amount': instance.refundAmount,
'metadata': instance.metadata,
'created_at': instance.createdAt,
'updated_at': instance.updatedAt,
};
_$OrderRequestDtoImpl _$$OrderRequestDtoImplFromJson(
Map<String, dynamic> json,
) => _$OrderRequestDtoImpl(
@@ -215,3 +177,83 @@ Map<String, dynamic> _$$OrderItemRequestDtoImplToJson(
'unit_price': instance.unitPrice,
'notes': instance.notes,
};
_$PaymentRequestDtoImpl _$$PaymentRequestDtoImplFromJson(
Map<String, dynamic> json,
) => _$PaymentRequestDtoImpl(
orderId: json['order_id'] as String?,
paymentMethodId: json['payment_method_id'] as String?,
amount: (json['amount'] as num?)?.toInt(),
transactionId: json['transaction_id'] as String?,
splitNumber: (json['split_number'] as num?)?.toInt(),
splitTotal: (json['split_total'] as num?)?.toInt(),
splitDescription: json['split_description'] as String?,
paymentOrderItems: (json['payment_order_items'] as List<dynamic>?)
?.map((e) => PaymentItemRequestDto.fromJson(e as Map<String, dynamic>))
.toList(),
);
Map<String, dynamic> _$$PaymentRequestDtoImplToJson(
_$PaymentRequestDtoImpl instance,
) => <String, dynamic>{
'order_id': instance.orderId,
'payment_method_id': instance.paymentMethodId,
'amount': instance.amount,
'transaction_id': instance.transactionId,
'split_number': instance.splitNumber,
'split_total': instance.splitTotal,
'split_description': instance.splitDescription,
'payment_order_items': instance.paymentOrderItems,
};
_$PaymentItemRequestDtoImpl _$$PaymentItemRequestDtoImplFromJson(
Map<String, dynamic> json,
) => _$PaymentItemRequestDtoImpl(
orderItemId: json['order_item_id'] as String?,
amount: (json['amount'] as num?)?.toInt(),
);
Map<String, dynamic> _$$PaymentItemRequestDtoImplToJson(
_$PaymentItemRequestDtoImpl instance,
) => <String, dynamic>{
'order_item_id': instance.orderItemId,
'amount': instance.amount,
};
_$PaymentOrderDtoImpl _$$PaymentOrderDtoImplFromJson(
Map<String, dynamic> json,
) => _$PaymentOrderDtoImpl(
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(),
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?,
);
Map<String, dynamic> _$$PaymentOrderDtoImplToJson(
_$PaymentOrderDtoImpl 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_description': instance.splitDescription,
'refund_amount': instance.refundAmount,
'metadata': instance.metadata,
'created_at': instance.createdAt,
'updated_at': instance.updatedAt,
};
@@ -65,4 +65,27 @@ class OrderRepository implements IOrderRepository {
return left(const OrderFailure.unexpectedError());
}
}
@override
Future<Either<OrderFailure, Order>> createOrderWithPayment({
required OrderRequest request,
required String paymentMethodId,
}) async {
try {
final result = await _dataProvider.storeWithPaymentOrder(
request: OrderRequestDto.fromDomain(request),
paymentMethodId: paymentMethodId,
);
if (result.hasError) {
return left(result.error!);
}
final order = result.data!.toDomain();
return right(order);
} catch (e) {
log('createOrderError', name: _logName, error: e);
return left(const OrderFailure.unexpectedError());
}
}
}