From 35f02e6b76e9e97876c57a9a105f568d93d15734 Mon Sep 17 00:00:00 2001 From: efrilm Date: Fri, 31 Oct 2025 20:43:37 +0700 Subject: [PATCH] split bill --- .../payment_form/payment_form_bloc.dart | 34 ++ .../payment_form_bloc.freezed.dart | 317 +++++++++- .../payment_form/payment_form_event.dart | 5 + .../payment_form/payment_form_state.dart | 2 + .../entities/payment_request_entity.dart | 34 ++ lib/domain/order/order.dart | 1 + lib/domain/order/order.freezed.dart | 464 +++++++++++++++ .../repositories/i_order_repository.dart | 4 + .../datasources/remote_data_provider.dart | 25 + .../order/dtos/payment_request_dto.dart | 99 ++++ lib/infrastructure/order/order_dtos.dart | 2 + .../order/order_dtos.freezed.dart | 553 ++++++++++++++++++ lib/infrastructure/order/order_dtos.g.dart | 43 ++ .../order/repositories/order_repository.dart | 21 + .../pages/payment/payment_page.dart | 103 +++- .../payment/widgets/payment_right_panel.dart | 29 +- .../widgets/split_bill_right_panel.dart | 12 + lib/presentation/router/app_router.gr.dart | 42 +- 18 files changed, 1763 insertions(+), 27 deletions(-) diff --git a/lib/application/payment/payment_form/payment_form_bloc.dart b/lib/application/payment/payment_form/payment_form_bloc.dart index 027dd7b..7eafbd1 100644 --- a/lib/application/payment/payment_form/payment_form_bloc.dart +++ b/lib/application/payment/payment_form/payment_form_bloc.dart @@ -3,6 +3,7 @@ import 'package:dartz/dartz.dart' hide Order; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:injectable/injectable.dart' hide Order; +import '../../../common/types/split_type.dart'; import '../../../domain/order/order.dart'; import '../../../domain/payment_method/payment_method.dart'; @@ -64,6 +65,39 @@ class PaymentFormBloc extends Bloc { ), ); }, + submittedSplitBill: (e) async { + Either failureOrPayment; + + emit( + state.copyWith(isSubmitting: true, failureOrPaymentSplitBill: none()), + ); + + final request = PaymentSplitBillRequest( + orderId: state.order.id, + paymentMethodId: state.paymentMethod?.id ?? '', + amount: state.order.totalAmount, + customerId: e.customerId ?? '', + type: e.splitType ?? SplitType.unknown, + customerName: e.customerName ?? '', + items: state.pendingItems + .map( + (item) => PaymentItemSplitBillRequest( + orderItemId: item.id, + quantity: item.quantity, + ), + ) + .toList(), + ); + + failureOrPayment = await _repository.createSplitBill(request); + + emit( + state.copyWith( + isSubmitting: false, + failureOrPaymentSplitBill: optionOf(failureOrPayment), + ), + ); + }, ); } } diff --git a/lib/application/payment/payment_form/payment_form_bloc.freezed.dart b/lib/application/payment/payment_form/payment_form_bloc.freezed.dart index b78200f..1ae147f 100644 --- a/lib/application/payment/payment_form/payment_form_bloc.freezed.dart +++ b/lib/application/payment/payment_form/payment_form_bloc.freezed.dart @@ -22,18 +22,36 @@ mixin _$PaymentFormEvent { required TResult Function(Order order) setOrder, required TResult Function(PaymentMethod paymentMethod) setPaymentMethod, required TResult Function() submitted, + required TResult Function( + SplitType? splitType, + String? customerId, + String? customerName, + ) + submittedSplitBill, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult? whenOrNull({ TResult? Function(Order order)? setOrder, TResult? Function(PaymentMethod paymentMethod)? setPaymentMethod, TResult? Function()? submitted, + TResult? Function( + SplitType? splitType, + String? customerId, + String? customerName, + )? + submittedSplitBill, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult maybeWhen({ TResult Function(Order order)? setOrder, TResult Function(PaymentMethod paymentMethod)? setPaymentMethod, TResult Function()? submitted, + TResult Function( + SplitType? splitType, + String? customerId, + String? customerName, + )? + submittedSplitBill, required TResult orElse(), }) => throw _privateConstructorUsedError; @optionalTypeArgs @@ -41,18 +59,21 @@ mixin _$PaymentFormEvent { required TResult Function(_SetOrder value) setOrder, required TResult Function(_SetPayment value) setPaymentMethod, required TResult Function(_Submitted value) submitted, + required TResult Function(_SubmittedSplitBill value) submittedSplitBill, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult? mapOrNull({ TResult? Function(_SetOrder value)? setOrder, TResult? Function(_SetPayment value)? setPaymentMethod, TResult? Function(_Submitted value)? submitted, + TResult? Function(_SubmittedSplitBill value)? submittedSplitBill, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult maybeMap({ TResult Function(_SetOrder value)? setOrder, TResult Function(_SetPayment value)? setPaymentMethod, TResult Function(_Submitted value)? submitted, + TResult Function(_SubmittedSplitBill value)? submittedSplitBill, required TResult orElse(), }) => throw _privateConstructorUsedError; } @@ -164,6 +185,12 @@ class _$SetOrderImpl implements _SetOrder { required TResult Function(Order order) setOrder, required TResult Function(PaymentMethod paymentMethod) setPaymentMethod, required TResult Function() submitted, + required TResult Function( + SplitType? splitType, + String? customerId, + String? customerName, + ) + submittedSplitBill, }) { return setOrder(order); } @@ -174,6 +201,12 @@ class _$SetOrderImpl implements _SetOrder { TResult? Function(Order order)? setOrder, TResult? Function(PaymentMethod paymentMethod)? setPaymentMethod, TResult? Function()? submitted, + TResult? Function( + SplitType? splitType, + String? customerId, + String? customerName, + )? + submittedSplitBill, }) { return setOrder?.call(order); } @@ -184,6 +217,12 @@ class _$SetOrderImpl implements _SetOrder { TResult Function(Order order)? setOrder, TResult Function(PaymentMethod paymentMethod)? setPaymentMethod, TResult Function()? submitted, + TResult Function( + SplitType? splitType, + String? customerId, + String? customerName, + )? + submittedSplitBill, required TResult orElse(), }) { if (setOrder != null) { @@ -198,6 +237,7 @@ class _$SetOrderImpl implements _SetOrder { required TResult Function(_SetOrder value) setOrder, required TResult Function(_SetPayment value) setPaymentMethod, required TResult Function(_Submitted value) submitted, + required TResult Function(_SubmittedSplitBill value) submittedSplitBill, }) { return setOrder(this); } @@ -208,6 +248,7 @@ class _$SetOrderImpl implements _SetOrder { TResult? Function(_SetOrder value)? setOrder, TResult? Function(_SetPayment value)? setPaymentMethod, TResult? Function(_Submitted value)? submitted, + TResult? Function(_SubmittedSplitBill value)? submittedSplitBill, }) { return setOrder?.call(this); } @@ -218,6 +259,7 @@ class _$SetOrderImpl implements _SetOrder { TResult Function(_SetOrder value)? setOrder, TResult Function(_SetPayment value)? setPaymentMethod, TResult Function(_Submitted value)? submitted, + TResult Function(_SubmittedSplitBill value)? submittedSplitBill, required TResult orElse(), }) { if (setOrder != null) { @@ -325,6 +367,12 @@ class _$SetPaymentImpl implements _SetPayment { required TResult Function(Order order) setOrder, required TResult Function(PaymentMethod paymentMethod) setPaymentMethod, required TResult Function() submitted, + required TResult Function( + SplitType? splitType, + String? customerId, + String? customerName, + ) + submittedSplitBill, }) { return setPaymentMethod(paymentMethod); } @@ -335,6 +383,12 @@ class _$SetPaymentImpl implements _SetPayment { TResult? Function(Order order)? setOrder, TResult? Function(PaymentMethod paymentMethod)? setPaymentMethod, TResult? Function()? submitted, + TResult? Function( + SplitType? splitType, + String? customerId, + String? customerName, + )? + submittedSplitBill, }) { return setPaymentMethod?.call(paymentMethod); } @@ -345,6 +399,12 @@ class _$SetPaymentImpl implements _SetPayment { TResult Function(Order order)? setOrder, TResult Function(PaymentMethod paymentMethod)? setPaymentMethod, TResult Function()? submitted, + TResult Function( + SplitType? splitType, + String? customerId, + String? customerName, + )? + submittedSplitBill, required TResult orElse(), }) { if (setPaymentMethod != null) { @@ -359,6 +419,7 @@ class _$SetPaymentImpl implements _SetPayment { required TResult Function(_SetOrder value) setOrder, required TResult Function(_SetPayment value) setPaymentMethod, required TResult Function(_Submitted value) submitted, + required TResult Function(_SubmittedSplitBill value) submittedSplitBill, }) { return setPaymentMethod(this); } @@ -369,6 +430,7 @@ class _$SetPaymentImpl implements _SetPayment { TResult? Function(_SetOrder value)? setOrder, TResult? Function(_SetPayment value)? setPaymentMethod, TResult? Function(_Submitted value)? submitted, + TResult? Function(_SubmittedSplitBill value)? submittedSplitBill, }) { return setPaymentMethod?.call(this); } @@ -379,6 +441,7 @@ class _$SetPaymentImpl implements _SetPayment { TResult Function(_SetOrder value)? setOrder, TResult Function(_SetPayment value)? setPaymentMethod, TResult Function(_Submitted value)? submitted, + TResult Function(_SubmittedSplitBill value)? submittedSplitBill, required TResult orElse(), }) { if (setPaymentMethod != null) { @@ -447,6 +510,12 @@ class _$SubmittedImpl implements _Submitted { required TResult Function(Order order) setOrder, required TResult Function(PaymentMethod paymentMethod) setPaymentMethod, required TResult Function() submitted, + required TResult Function( + SplitType? splitType, + String? customerId, + String? customerName, + ) + submittedSplitBill, }) { return submitted(); } @@ -457,6 +526,12 @@ class _$SubmittedImpl implements _Submitted { TResult? Function(Order order)? setOrder, TResult? Function(PaymentMethod paymentMethod)? setPaymentMethod, TResult? Function()? submitted, + TResult? Function( + SplitType? splitType, + String? customerId, + String? customerName, + )? + submittedSplitBill, }) { return submitted?.call(); } @@ -467,6 +542,12 @@ class _$SubmittedImpl implements _Submitted { TResult Function(Order order)? setOrder, TResult Function(PaymentMethod paymentMethod)? setPaymentMethod, TResult Function()? submitted, + TResult Function( + SplitType? splitType, + String? customerId, + String? customerName, + )? + submittedSplitBill, required TResult orElse(), }) { if (submitted != null) { @@ -481,6 +562,7 @@ class _$SubmittedImpl implements _Submitted { required TResult Function(_SetOrder value) setOrder, required TResult Function(_SetPayment value) setPaymentMethod, required TResult Function(_Submitted value) submitted, + required TResult Function(_SubmittedSplitBill value) submittedSplitBill, }) { return submitted(this); } @@ -491,6 +573,7 @@ class _$SubmittedImpl implements _Submitted { TResult? Function(_SetOrder value)? setOrder, TResult? Function(_SetPayment value)? setPaymentMethod, TResult? Function(_Submitted value)? submitted, + TResult? Function(_SubmittedSplitBill value)? submittedSplitBill, }) { return submitted?.call(this); } @@ -501,6 +584,7 @@ class _$SubmittedImpl implements _Submitted { TResult Function(_SetOrder value)? setOrder, TResult Function(_SetPayment value)? setPaymentMethod, TResult Function(_Submitted value)? submitted, + TResult Function(_SubmittedSplitBill value)? submittedSplitBill, required TResult orElse(), }) { if (submitted != null) { @@ -514,12 +598,218 @@ abstract class _Submitted implements PaymentFormEvent { const factory _Submitted() = _$SubmittedImpl; } +/// @nodoc +abstract class _$$SubmittedSplitBillImplCopyWith<$Res> { + factory _$$SubmittedSplitBillImplCopyWith( + _$SubmittedSplitBillImpl value, + $Res Function(_$SubmittedSplitBillImpl) then, + ) = __$$SubmittedSplitBillImplCopyWithImpl<$Res>; + @useResult + $Res call({SplitType? splitType, String? customerId, String? customerName}); +} + +/// @nodoc +class __$$SubmittedSplitBillImplCopyWithImpl<$Res> + extends _$PaymentFormEventCopyWithImpl<$Res, _$SubmittedSplitBillImpl> + implements _$$SubmittedSplitBillImplCopyWith<$Res> { + __$$SubmittedSplitBillImplCopyWithImpl( + _$SubmittedSplitBillImpl _value, + $Res Function(_$SubmittedSplitBillImpl) _then, + ) : super(_value, _then); + + /// Create a copy of PaymentFormEvent + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? splitType = freezed, + Object? customerId = freezed, + Object? customerName = freezed, + }) { + return _then( + _$SubmittedSplitBillImpl( + splitType: freezed == splitType + ? _value.splitType + : splitType // ignore: cast_nullable_to_non_nullable + as SplitType?, + customerId: freezed == customerId + ? _value.customerId + : customerId // ignore: cast_nullable_to_non_nullable + as String?, + customerName: freezed == customerName + ? _value.customerName + : customerName // ignore: cast_nullable_to_non_nullable + as String?, + ), + ); + } +} + +/// @nodoc + +class _$SubmittedSplitBillImpl implements _SubmittedSplitBill { + const _$SubmittedSplitBillImpl({ + this.splitType, + this.customerId, + this.customerName, + }); + + @override + final SplitType? splitType; + @override + final String? customerId; + @override + final String? customerName; + + @override + String toString() { + return 'PaymentFormEvent.submittedSplitBill(splitType: $splitType, customerId: $customerId, customerName: $customerName)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$SubmittedSplitBillImpl && + (identical(other.splitType, splitType) || + other.splitType == splitType) && + (identical(other.customerId, customerId) || + other.customerId == customerId) && + (identical(other.customerName, customerName) || + other.customerName == customerName)); + } + + @override + int get hashCode => + Object.hash(runtimeType, splitType, customerId, customerName); + + /// Create a copy of PaymentFormEvent + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$SubmittedSplitBillImplCopyWith<_$SubmittedSplitBillImpl> get copyWith => + __$$SubmittedSplitBillImplCopyWithImpl<_$SubmittedSplitBillImpl>( + this, + _$identity, + ); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function(Order order) setOrder, + required TResult Function(PaymentMethod paymentMethod) setPaymentMethod, + required TResult Function() submitted, + required TResult Function( + SplitType? splitType, + String? customerId, + String? customerName, + ) + submittedSplitBill, + }) { + return submittedSplitBill(splitType, customerId, customerName); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function(Order order)? setOrder, + TResult? Function(PaymentMethod paymentMethod)? setPaymentMethod, + TResult? Function()? submitted, + TResult? Function( + SplitType? splitType, + String? customerId, + String? customerName, + )? + submittedSplitBill, + }) { + return submittedSplitBill?.call(splitType, customerId, customerName); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function(Order order)? setOrder, + TResult Function(PaymentMethod paymentMethod)? setPaymentMethod, + TResult Function()? submitted, + TResult Function( + SplitType? splitType, + String? customerId, + String? customerName, + )? + submittedSplitBill, + required TResult orElse(), + }) { + if (submittedSplitBill != null) { + return submittedSplitBill(splitType, customerId, customerName); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_SetOrder value) setOrder, + required TResult Function(_SetPayment value) setPaymentMethod, + required TResult Function(_Submitted value) submitted, + required TResult Function(_SubmittedSplitBill value) submittedSplitBill, + }) { + return submittedSplitBill(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_SetOrder value)? setOrder, + TResult? Function(_SetPayment value)? setPaymentMethod, + TResult? Function(_Submitted value)? submitted, + TResult? Function(_SubmittedSplitBill value)? submittedSplitBill, + }) { + return submittedSplitBill?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_SetOrder value)? setOrder, + TResult Function(_SetPayment value)? setPaymentMethod, + TResult Function(_Submitted value)? submitted, + TResult Function(_SubmittedSplitBill value)? submittedSplitBill, + required TResult orElse(), + }) { + if (submittedSplitBill != null) { + return submittedSplitBill(this); + } + return orElse(); + } +} + +abstract class _SubmittedSplitBill implements PaymentFormEvent { + const factory _SubmittedSplitBill({ + final SplitType? splitType, + final String? customerId, + final String? customerName, + }) = _$SubmittedSplitBillImpl; + + SplitType? get splitType; + String? get customerId; + String? get customerName; + + /// Create a copy of PaymentFormEvent + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + _$$SubmittedSplitBillImplCopyWith<_$SubmittedSplitBillImpl> get copyWith => + throw _privateConstructorUsedError; +} + /// @nodoc mixin _$PaymentFormState { Order get order => throw _privateConstructorUsedError; List get pendingItems => throw _privateConstructorUsedError; Option> get failureOrPayment => throw _privateConstructorUsedError; + Option> get failureOrPaymentSplitBill => + throw _privateConstructorUsedError; PaymentMethod? get paymentMethod => throw _privateConstructorUsedError; bool get isSubmitting => throw _privateConstructorUsedError; @@ -541,6 +831,7 @@ abstract class $PaymentFormStateCopyWith<$Res> { Order order, List pendingItems, Option> failureOrPayment, + Option> failureOrPaymentSplitBill, PaymentMethod? paymentMethod, bool isSubmitting, }); @@ -567,6 +858,7 @@ class _$PaymentFormStateCopyWithImpl<$Res, $Val extends PaymentFormState> Object? order = null, Object? pendingItems = null, Object? failureOrPayment = null, + Object? failureOrPaymentSplitBill = null, Object? paymentMethod = freezed, Object? isSubmitting = null, }) { @@ -584,6 +876,10 @@ class _$PaymentFormStateCopyWithImpl<$Res, $Val extends PaymentFormState> ? _value.failureOrPayment : failureOrPayment // ignore: cast_nullable_to_non_nullable as Option>, + failureOrPaymentSplitBill: null == failureOrPaymentSplitBill + ? _value.failureOrPaymentSplitBill + : failureOrPaymentSplitBill // ignore: cast_nullable_to_non_nullable + as Option>, paymentMethod: freezed == paymentMethod ? _value.paymentMethod : paymentMethod // ignore: cast_nullable_to_non_nullable @@ -635,6 +931,7 @@ abstract class _$$PaymentFormStateImplCopyWith<$Res> Order order, List pendingItems, Option> failureOrPayment, + Option> failureOrPaymentSplitBill, PaymentMethod? paymentMethod, bool isSubmitting, }); @@ -662,6 +959,7 @@ class __$$PaymentFormStateImplCopyWithImpl<$Res> Object? order = null, Object? pendingItems = null, Object? failureOrPayment = null, + Object? failureOrPaymentSplitBill = null, Object? paymentMethod = freezed, Object? isSubmitting = null, }) { @@ -679,6 +977,10 @@ class __$$PaymentFormStateImplCopyWithImpl<$Res> ? _value.failureOrPayment : failureOrPayment // ignore: cast_nullable_to_non_nullable as Option>, + failureOrPaymentSplitBill: null == failureOrPaymentSplitBill + ? _value.failureOrPaymentSplitBill + : failureOrPaymentSplitBill // ignore: cast_nullable_to_non_nullable + as Option>, paymentMethod: freezed == paymentMethod ? _value.paymentMethod : paymentMethod // ignore: cast_nullable_to_non_nullable @@ -699,6 +1001,7 @@ class _$PaymentFormStateImpl implements _PaymentFormState { required this.order, required final List pendingItems, required this.failureOrPayment, + required this.failureOrPaymentSplitBill, this.paymentMethod, this.isSubmitting = false, }) : _pendingItems = pendingItems; @@ -716,6 +1019,8 @@ class _$PaymentFormStateImpl implements _PaymentFormState { @override final Option> failureOrPayment; @override + final Option> failureOrPaymentSplitBill; + @override final PaymentMethod? paymentMethod; @override @JsonKey() @@ -723,7 +1028,7 @@ class _$PaymentFormStateImpl implements _PaymentFormState { @override String toString() { - return 'PaymentFormState(order: $order, pendingItems: $pendingItems, failureOrPayment: $failureOrPayment, paymentMethod: $paymentMethod, isSubmitting: $isSubmitting)'; + return 'PaymentFormState(order: $order, pendingItems: $pendingItems, failureOrPayment: $failureOrPayment, failureOrPaymentSplitBill: $failureOrPaymentSplitBill, paymentMethod: $paymentMethod, isSubmitting: $isSubmitting)'; } @override @@ -738,6 +1043,11 @@ class _$PaymentFormStateImpl implements _PaymentFormState { ) && (identical(other.failureOrPayment, failureOrPayment) || other.failureOrPayment == failureOrPayment) && + (identical( + other.failureOrPaymentSplitBill, + failureOrPaymentSplitBill, + ) || + other.failureOrPaymentSplitBill == failureOrPaymentSplitBill) && (identical(other.paymentMethod, paymentMethod) || other.paymentMethod == paymentMethod) && (identical(other.isSubmitting, isSubmitting) || @@ -750,6 +1060,7 @@ class _$PaymentFormStateImpl implements _PaymentFormState { order, const DeepCollectionEquality().hash(_pendingItems), failureOrPayment, + failureOrPaymentSplitBill, paymentMethod, isSubmitting, ); @@ -771,6 +1082,8 @@ abstract class _PaymentFormState implements PaymentFormState { required final Order order, required final List pendingItems, required final Option> failureOrPayment, + required final Option> + failureOrPaymentSplitBill, final PaymentMethod? paymentMethod, final bool isSubmitting, }) = _$PaymentFormStateImpl; @@ -782,6 +1095,8 @@ abstract class _PaymentFormState implements PaymentFormState { @override Option> get failureOrPayment; @override + Option> get failureOrPaymentSplitBill; + @override PaymentMethod? get paymentMethod; @override bool get isSubmitting; diff --git a/lib/application/payment/payment_form/payment_form_event.dart b/lib/application/payment/payment_form/payment_form_event.dart index d139d30..227730d 100644 --- a/lib/application/payment/payment_form/payment_form_event.dart +++ b/lib/application/payment/payment_form/payment_form_event.dart @@ -6,4 +6,9 @@ class PaymentFormEvent with _$PaymentFormEvent { const factory PaymentFormEvent.setPaymentMethod(PaymentMethod paymentMethod) = _SetPayment; const factory PaymentFormEvent.submitted() = _Submitted; + const factory PaymentFormEvent.submittedSplitBill({ + SplitType? splitType, + String? customerId, + String? customerName, + }) = _SubmittedSplitBill; } diff --git a/lib/application/payment/payment_form/payment_form_state.dart b/lib/application/payment/payment_form/payment_form_state.dart index a10c9d3..c5fb5bb 100644 --- a/lib/application/payment/payment_form/payment_form_state.dart +++ b/lib/application/payment/payment_form/payment_form_state.dart @@ -6,6 +6,7 @@ class PaymentFormState with _$PaymentFormState { required Order order, required List pendingItems, required Option> failureOrPayment, + required Option> failureOrPaymentSplitBill, PaymentMethod? paymentMethod, @Default(false) bool isSubmitting, }) = _PaymentFormState; @@ -14,5 +15,6 @@ class PaymentFormState with _$PaymentFormState { order: Order.empty(), pendingItems: [], failureOrPayment: none(), + failureOrPaymentSplitBill: none(), ); } diff --git a/lib/domain/order/entities/payment_request_entity.dart b/lib/domain/order/entities/payment_request_entity.dart index 909f8ba..4318e8c 100644 --- a/lib/domain/order/entities/payment_request_entity.dart +++ b/lib/domain/order/entities/payment_request_entity.dart @@ -35,3 +35,37 @@ class PaymentItemRequest with _$PaymentItemRequest { factory PaymentItemRequest.empty() => const PaymentItemRequest(orderItemId: '', amount: 0); } + +@freezed +class PaymentSplitBillRequest with _$PaymentSplitBillRequest { + const factory PaymentSplitBillRequest({ + required String orderId, + required String paymentMethodId, + required String customerId, + required String customerName, + required SplitType type, // e.g., "AMOUNT" or "ITEM" + required int amount, + required List items, + }) = _PaymentSplitBillRequest; + + factory PaymentSplitBillRequest.empty() => const PaymentSplitBillRequest( + orderId: '', + paymentMethodId: '', + customerId: '', + type: SplitType.unknown, + amount: 0, + items: [], + customerName: '', + ); +} + +@freezed +class PaymentItemSplitBillRequest with _$PaymentItemSplitBillRequest { + const factory PaymentItemSplitBillRequest({ + required String orderItemId, + required int quantity, + }) = _PaymentItemSplitBillRequest; + + factory PaymentItemSplitBillRequest.empty() => + const PaymentItemSplitBillRequest(orderItemId: '', quantity: 0); +} diff --git a/lib/domain/order/order.dart b/lib/domain/order/order.dart index e3069a7..53f6d29 100644 --- a/lib/domain/order/order.dart +++ b/lib/domain/order/order.dart @@ -2,6 +2,7 @@ import 'package:dartz/dartz.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import '../../common/api/api_failure.dart'; +import '../../common/types/split_type.dart'; part 'order.freezed.dart'; diff --git a/lib/domain/order/order.freezed.dart b/lib/domain/order/order.freezed.dart index ab95aaf..5df8388 100644 --- a/lib/domain/order/order.freezed.dart +++ b/lib/domain/order/order.freezed.dart @@ -2455,6 +2455,470 @@ abstract class _PaymentItemRequest implements PaymentItemRequest { throw _privateConstructorUsedError; } +/// @nodoc +mixin _$PaymentSplitBillRequest { + String get orderId => throw _privateConstructorUsedError; + String get paymentMethodId => throw _privateConstructorUsedError; + String get customerId => throw _privateConstructorUsedError; + String get customerName => throw _privateConstructorUsedError; + SplitType get type => + throw _privateConstructorUsedError; // e.g., "AMOUNT" or "ITEM" + int get amount => throw _privateConstructorUsedError; + List get items => + throw _privateConstructorUsedError; + + /// Create a copy of PaymentSplitBillRequest + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $PaymentSplitBillRequestCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $PaymentSplitBillRequestCopyWith<$Res> { + factory $PaymentSplitBillRequestCopyWith( + PaymentSplitBillRequest value, + $Res Function(PaymentSplitBillRequest) then, + ) = _$PaymentSplitBillRequestCopyWithImpl<$Res, PaymentSplitBillRequest>; + @useResult + $Res call({ + String orderId, + String paymentMethodId, + String customerId, + String customerName, + SplitType type, + int amount, + List items, + }); +} + +/// @nodoc +class _$PaymentSplitBillRequestCopyWithImpl< + $Res, + $Val extends PaymentSplitBillRequest +> + implements $PaymentSplitBillRequestCopyWith<$Res> { + _$PaymentSplitBillRequestCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of PaymentSplitBillRequest + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? orderId = null, + Object? paymentMethodId = null, + Object? customerId = null, + Object? customerName = null, + Object? type = null, + Object? amount = null, + Object? items = null, + }) { + return _then( + _value.copyWith( + orderId: null == orderId + ? _value.orderId + : orderId // ignore: cast_nullable_to_non_nullable + as String, + paymentMethodId: null == paymentMethodId + ? _value.paymentMethodId + : paymentMethodId // ignore: cast_nullable_to_non_nullable + as String, + customerId: null == customerId + ? _value.customerId + : customerId // ignore: cast_nullable_to_non_nullable + as String, + customerName: null == customerName + ? _value.customerName + : customerName // ignore: cast_nullable_to_non_nullable + as String, + type: null == type + ? _value.type + : type // ignore: cast_nullable_to_non_nullable + as SplitType, + amount: null == amount + ? _value.amount + : amount // ignore: cast_nullable_to_non_nullable + as int, + items: null == items + ? _value.items + : items // ignore: cast_nullable_to_non_nullable + as List, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$PaymentSplitBillRequestImplCopyWith<$Res> + implements $PaymentSplitBillRequestCopyWith<$Res> { + factory _$$PaymentSplitBillRequestImplCopyWith( + _$PaymentSplitBillRequestImpl value, + $Res Function(_$PaymentSplitBillRequestImpl) then, + ) = __$$PaymentSplitBillRequestImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + String orderId, + String paymentMethodId, + String customerId, + String customerName, + SplitType type, + int amount, + List items, + }); +} + +/// @nodoc +class __$$PaymentSplitBillRequestImplCopyWithImpl<$Res> + extends + _$PaymentSplitBillRequestCopyWithImpl< + $Res, + _$PaymentSplitBillRequestImpl + > + implements _$$PaymentSplitBillRequestImplCopyWith<$Res> { + __$$PaymentSplitBillRequestImplCopyWithImpl( + _$PaymentSplitBillRequestImpl _value, + $Res Function(_$PaymentSplitBillRequestImpl) _then, + ) : super(_value, _then); + + /// Create a copy of PaymentSplitBillRequest + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? orderId = null, + Object? paymentMethodId = null, + Object? customerId = null, + Object? customerName = null, + Object? type = null, + Object? amount = null, + Object? items = null, + }) { + return _then( + _$PaymentSplitBillRequestImpl( + orderId: null == orderId + ? _value.orderId + : orderId // ignore: cast_nullable_to_non_nullable + as String, + paymentMethodId: null == paymentMethodId + ? _value.paymentMethodId + : paymentMethodId // ignore: cast_nullable_to_non_nullable + as String, + customerId: null == customerId + ? _value.customerId + : customerId // ignore: cast_nullable_to_non_nullable + as String, + customerName: null == customerName + ? _value.customerName + : customerName // ignore: cast_nullable_to_non_nullable + as String, + type: null == type + ? _value.type + : type // ignore: cast_nullable_to_non_nullable + as SplitType, + amount: null == amount + ? _value.amount + : amount // ignore: cast_nullable_to_non_nullable + as int, + items: null == items + ? _value._items + : items // ignore: cast_nullable_to_non_nullable + as List, + ), + ); + } +} + +/// @nodoc + +class _$PaymentSplitBillRequestImpl implements _PaymentSplitBillRequest { + const _$PaymentSplitBillRequestImpl({ + required this.orderId, + required this.paymentMethodId, + required this.customerId, + required this.customerName, + required this.type, + required this.amount, + required final List items, + }) : _items = items; + + @override + final String orderId; + @override + final String paymentMethodId; + @override + final String customerId; + @override + final String customerName; + @override + final SplitType type; + // e.g., "AMOUNT" or "ITEM" + @override + final int amount; + final List _items; + @override + List get items { + if (_items is EqualUnmodifiableListView) return _items; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_items); + } + + @override + String toString() { + return 'PaymentSplitBillRequest(orderId: $orderId, paymentMethodId: $paymentMethodId, customerId: $customerId, customerName: $customerName, type: $type, amount: $amount, items: $items)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$PaymentSplitBillRequestImpl && + (identical(other.orderId, orderId) || other.orderId == orderId) && + (identical(other.paymentMethodId, paymentMethodId) || + other.paymentMethodId == paymentMethodId) && + (identical(other.customerId, customerId) || + other.customerId == customerId) && + (identical(other.customerName, customerName) || + other.customerName == customerName) && + (identical(other.type, type) || other.type == type) && + (identical(other.amount, amount) || other.amount == amount) && + const DeepCollectionEquality().equals(other._items, _items)); + } + + @override + int get hashCode => Object.hash( + runtimeType, + orderId, + paymentMethodId, + customerId, + customerName, + type, + amount, + const DeepCollectionEquality().hash(_items), + ); + + /// Create a copy of PaymentSplitBillRequest + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$PaymentSplitBillRequestImplCopyWith<_$PaymentSplitBillRequestImpl> + get copyWith => + __$$PaymentSplitBillRequestImplCopyWithImpl< + _$PaymentSplitBillRequestImpl + >(this, _$identity); +} + +abstract class _PaymentSplitBillRequest implements PaymentSplitBillRequest { + const factory _PaymentSplitBillRequest({ + required final String orderId, + required final String paymentMethodId, + required final String customerId, + required final String customerName, + required final SplitType type, + required final int amount, + required final List items, + }) = _$PaymentSplitBillRequestImpl; + + @override + String get orderId; + @override + String get paymentMethodId; + @override + String get customerId; + @override + String get customerName; + @override + SplitType get type; // e.g., "AMOUNT" or "ITEM" + @override + int get amount; + @override + List get items; + + /// Create a copy of PaymentSplitBillRequest + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$PaymentSplitBillRequestImplCopyWith<_$PaymentSplitBillRequestImpl> + get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +mixin _$PaymentItemSplitBillRequest { + String get orderItemId => throw _privateConstructorUsedError; + int get quantity => throw _privateConstructorUsedError; + + /// Create a copy of PaymentItemSplitBillRequest + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $PaymentItemSplitBillRequestCopyWith + get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $PaymentItemSplitBillRequestCopyWith<$Res> { + factory $PaymentItemSplitBillRequestCopyWith( + PaymentItemSplitBillRequest value, + $Res Function(PaymentItemSplitBillRequest) then, + ) = + _$PaymentItemSplitBillRequestCopyWithImpl< + $Res, + PaymentItemSplitBillRequest + >; + @useResult + $Res call({String orderItemId, int quantity}); +} + +/// @nodoc +class _$PaymentItemSplitBillRequestCopyWithImpl< + $Res, + $Val extends PaymentItemSplitBillRequest +> + implements $PaymentItemSplitBillRequestCopyWith<$Res> { + _$PaymentItemSplitBillRequestCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of PaymentItemSplitBillRequest + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({Object? orderItemId = null, Object? quantity = null}) { + return _then( + _value.copyWith( + orderItemId: null == orderItemId + ? _value.orderItemId + : orderItemId // ignore: cast_nullable_to_non_nullable + as String, + quantity: null == quantity + ? _value.quantity + : quantity // ignore: cast_nullable_to_non_nullable + as int, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$PaymentItemSplitBillRequestImplCopyWith<$Res> + implements $PaymentItemSplitBillRequestCopyWith<$Res> { + factory _$$PaymentItemSplitBillRequestImplCopyWith( + _$PaymentItemSplitBillRequestImpl value, + $Res Function(_$PaymentItemSplitBillRequestImpl) then, + ) = __$$PaymentItemSplitBillRequestImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({String orderItemId, int quantity}); +} + +/// @nodoc +class __$$PaymentItemSplitBillRequestImplCopyWithImpl<$Res> + extends + _$PaymentItemSplitBillRequestCopyWithImpl< + $Res, + _$PaymentItemSplitBillRequestImpl + > + implements _$$PaymentItemSplitBillRequestImplCopyWith<$Res> { + __$$PaymentItemSplitBillRequestImplCopyWithImpl( + _$PaymentItemSplitBillRequestImpl _value, + $Res Function(_$PaymentItemSplitBillRequestImpl) _then, + ) : super(_value, _then); + + /// Create a copy of PaymentItemSplitBillRequest + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({Object? orderItemId = null, Object? quantity = null}) { + return _then( + _$PaymentItemSplitBillRequestImpl( + orderItemId: null == orderItemId + ? _value.orderItemId + : orderItemId // ignore: cast_nullable_to_non_nullable + as String, + quantity: null == quantity + ? _value.quantity + : quantity // ignore: cast_nullable_to_non_nullable + as int, + ), + ); + } +} + +/// @nodoc + +class _$PaymentItemSplitBillRequestImpl + implements _PaymentItemSplitBillRequest { + const _$PaymentItemSplitBillRequestImpl({ + required this.orderItemId, + required this.quantity, + }); + + @override + final String orderItemId; + @override + final int quantity; + + @override + String toString() { + return 'PaymentItemSplitBillRequest(orderItemId: $orderItemId, quantity: $quantity)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$PaymentItemSplitBillRequestImpl && + (identical(other.orderItemId, orderItemId) || + other.orderItemId == orderItemId) && + (identical(other.quantity, quantity) || + other.quantity == quantity)); + } + + @override + int get hashCode => Object.hash(runtimeType, orderItemId, quantity); + + /// Create a copy of PaymentItemSplitBillRequest + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$PaymentItemSplitBillRequestImplCopyWith<_$PaymentItemSplitBillRequestImpl> + get copyWith => + __$$PaymentItemSplitBillRequestImplCopyWithImpl< + _$PaymentItemSplitBillRequestImpl + >(this, _$identity); +} + +abstract class _PaymentItemSplitBillRequest + implements PaymentItemSplitBillRequest { + const factory _PaymentItemSplitBillRequest({ + required final String orderItemId, + required final int quantity, + }) = _$PaymentItemSplitBillRequestImpl; + + @override + String get orderItemId; + @override + int get quantity; + + /// Create a copy of PaymentItemSplitBillRequest + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$PaymentItemSplitBillRequestImplCopyWith<_$PaymentItemSplitBillRequestImpl> + get copyWith => throw _privateConstructorUsedError; +} + /// @nodoc mixin _$Payment { String get id => throw _privateConstructorUsedError; diff --git a/lib/domain/order/repositories/i_order_repository.dart b/lib/domain/order/repositories/i_order_repository.dart index e3f512a..cc54736 100644 --- a/lib/domain/order/repositories/i_order_repository.dart +++ b/lib/domain/order/repositories/i_order_repository.dart @@ -36,4 +36,8 @@ abstract class IOrderRepository { String type = "ITEM", // TYPE: ALL, ITEM required List orderItems, }); + + Future> createSplitBill( + PaymentSplitBillRequest request, + ); } diff --git a/lib/infrastructure/order/datasources/remote_data_provider.dart b/lib/infrastructure/order/datasources/remote_data_provider.dart index 42eaed4..055d318 100644 --- a/lib/infrastructure/order/datasources/remote_data_provider.dart +++ b/lib/infrastructure/order/datasources/remote_data_provider.dart @@ -236,4 +236,29 @@ class OrderRemoteDataProvider { return DC.error(OrderFailure.serverError(e)); } } + + Future> createSplitBill( + PaymentSplitBillRequestDto request, + ) async { + try { + final response = await _apiClient.post( + "${ApiPath.orders}/split-bill", + data: request.toRequest(), + headers: getAuthorizationHeader(), + ); + + if (response.data['success'] == false) { + return DC.error(OrderFailure.unexpectedError()); + } + + final payment = PaymentDto.fromJson( + response.data['data'] as Map, + ); + + return DC.data(payment); + } on ApiFailure catch (e, s) { + log('createSplitBillError', name: _logName, error: e, stackTrace: s); + return DC.error(OrderFailure.serverError(e)); + } + } } diff --git a/lib/infrastructure/order/dtos/payment_request_dto.dart b/lib/infrastructure/order/dtos/payment_request_dto.dart index 6fd953b..772b6bd 100644 --- a/lib/infrastructure/order/dtos/payment_request_dto.dart +++ b/lib/infrastructure/order/dtos/payment_request_dto.dart @@ -69,3 +69,102 @@ class PaymentItemRequestDto with _$PaymentItemRequestDto { amount: request.amount, ); } + +@freezed +class PaymentSplitBillRequestDto with _$PaymentSplitBillRequestDto { + const PaymentSplitBillRequestDto._(); + + const factory PaymentSplitBillRequestDto({ + @JsonKey(name: "order_id") String? orderId, + @JsonKey(name: "payment_method_id") String? paymentMethodId, + @JsonKey(name: "customer_id") String? customerId, + @JsonKey(name: "customer_name") String? customerName, + @JsonKey(name: "type") String? type, // e.g., "AMOUNT" or "ITEM" + @JsonKey(name: "amount") int? amount, + @JsonKey(name: "items") List? items, + }) = _PaymentSplitBillRequestDto; + + factory PaymentSplitBillRequestDto.fromJson(Map json) => + _$PaymentSplitBillRequestDtoFromJson(json); + + // Optional mapper ke domain + PaymentSplitBillRequest toDomain() => PaymentSplitBillRequest( + orderId: orderId ?? '', + paymentMethodId: paymentMethodId ?? '', + customerId: customerId ?? '', + type: type?.toSplitType() ?? SplitType.unknown, + amount: amount ?? 0, + items: items?.map((e) => e.toDomain()).toList() ?? [], + customerName: customerName ?? '', + ); + + factory PaymentSplitBillRequestDto.fromDomain( + PaymentSplitBillRequest request, + ) => PaymentSplitBillRequestDto( + orderId: request.orderId, + paymentMethodId: request.paymentMethodId, + customerId: request.customerId, + type: request.type.toStringType(), + amount: request.amount, + items: request.items + .map((e) => PaymentItemSplitBillRequestDto.fromDomain(e)) + .toList(), + ); + + Map toRequest() { + Map data = { + 'order_id': orderId, + 'payment_method_id': paymentMethodId, + 'type': type, + }; + + if (customerId != null && customerId != '') { + data['customer_id'] = customerId; + } + + if (customerName != null && customerName != '') { + data['customer_name'] = customerName; + } + + if (type == 'AMOUNT') { + data['amount'] = amount; + } + + if (type == 'ITEM') { + data['items'] = items?.map((item) => item.toRequest()).toList(); + } + + return data; + } +} + +@freezed +class PaymentItemSplitBillRequestDto with _$PaymentItemSplitBillRequestDto { + const PaymentItemSplitBillRequestDto._(); + + const factory PaymentItemSplitBillRequestDto({ + @JsonKey(name: "order_item_id") String? orderItemId, + @JsonKey(name: "quantity") int? quantity, + }) = _PaymentItemSplitBillRequestDto; + + factory PaymentItemSplitBillRequestDto.fromJson(Map json) => + _$PaymentItemSplitBillRequestDtoFromJson(json); + + // Optional mapper ke domain + PaymentItemSplitBillRequest toDomain() => PaymentItemSplitBillRequest( + orderItemId: orderItemId ?? '', + quantity: quantity ?? 0, + ); + + factory PaymentItemSplitBillRequestDto.fromDomain( + PaymentItemSplitBillRequest request, + ) => PaymentItemSplitBillRequestDto( + orderItemId: request.orderItemId, + quantity: request.quantity, + ); + + Map toRequest() => { + 'order_item_id': orderItemId, + 'quantity': quantity, + }; +} diff --git a/lib/infrastructure/order/order_dtos.dart b/lib/infrastructure/order/order_dtos.dart index ac4840d..71ff16d 100644 --- a/lib/infrastructure/order/order_dtos.dart +++ b/lib/infrastructure/order/order_dtos.dart @@ -1,5 +1,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; +import '../../common/extension/extension.dart'; +import '../../common/types/split_type.dart'; import '../../domain/order/order.dart'; part 'order_dtos.freezed.dart'; diff --git a/lib/infrastructure/order/order_dtos.freezed.dart b/lib/infrastructure/order/order_dtos.freezed.dart index 61ba067..744be1c 100644 --- a/lib/infrastructure/order/order_dtos.freezed.dart +++ b/lib/infrastructure/order/order_dtos.freezed.dart @@ -2851,6 +2851,559 @@ abstract class _PaymentItemRequestDto extends PaymentItemRequestDto { get copyWith => throw _privateConstructorUsedError; } +PaymentSplitBillRequestDto _$PaymentSplitBillRequestDtoFromJson( + Map json, +) { + return _PaymentSplitBillRequestDto.fromJson(json); +} + +/// @nodoc +mixin _$PaymentSplitBillRequestDto { + @JsonKey(name: "order_id") + String? get orderId => throw _privateConstructorUsedError; + @JsonKey(name: "payment_method_id") + String? get paymentMethodId => throw _privateConstructorUsedError; + @JsonKey(name: "customer_id") + String? get customerId => throw _privateConstructorUsedError; + @JsonKey(name: "customer_name") + String? get customerName => throw _privateConstructorUsedError; + @JsonKey(name: "type") + String? get type => throw _privateConstructorUsedError; // e.g., "AMOUNT" or "ITEM" + @JsonKey(name: "amount") + int? get amount => throw _privateConstructorUsedError; + @JsonKey(name: "items") + List? get items => + throw _privateConstructorUsedError; + + /// Serializes this PaymentSplitBillRequestDto to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of PaymentSplitBillRequestDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $PaymentSplitBillRequestDtoCopyWith + get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $PaymentSplitBillRequestDtoCopyWith<$Res> { + factory $PaymentSplitBillRequestDtoCopyWith( + PaymentSplitBillRequestDto value, + $Res Function(PaymentSplitBillRequestDto) then, + ) = + _$PaymentSplitBillRequestDtoCopyWithImpl< + $Res, + PaymentSplitBillRequestDto + >; + @useResult + $Res call({ + @JsonKey(name: "order_id") String? orderId, + @JsonKey(name: "payment_method_id") String? paymentMethodId, + @JsonKey(name: "customer_id") String? customerId, + @JsonKey(name: "customer_name") String? customerName, + @JsonKey(name: "type") String? type, + @JsonKey(name: "amount") int? amount, + @JsonKey(name: "items") List? items, + }); +} + +/// @nodoc +class _$PaymentSplitBillRequestDtoCopyWithImpl< + $Res, + $Val extends PaymentSplitBillRequestDto +> + implements $PaymentSplitBillRequestDtoCopyWith<$Res> { + _$PaymentSplitBillRequestDtoCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of PaymentSplitBillRequestDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? orderId = freezed, + Object? paymentMethodId = freezed, + Object? customerId = freezed, + Object? customerName = freezed, + Object? type = freezed, + Object? amount = freezed, + Object? items = freezed, + }) { + return _then( + _value.copyWith( + orderId: freezed == orderId + ? _value.orderId + : orderId // ignore: cast_nullable_to_non_nullable + as String?, + paymentMethodId: freezed == paymentMethodId + ? _value.paymentMethodId + : paymentMethodId // ignore: cast_nullable_to_non_nullable + as String?, + customerId: freezed == customerId + ? _value.customerId + : customerId // ignore: cast_nullable_to_non_nullable + as String?, + customerName: freezed == customerName + ? _value.customerName + : customerName // ignore: cast_nullable_to_non_nullable + as String?, + type: freezed == type + ? _value.type + : type // ignore: cast_nullable_to_non_nullable + as String?, + amount: freezed == amount + ? _value.amount + : amount // ignore: cast_nullable_to_non_nullable + as int?, + items: freezed == items + ? _value.items + : items // ignore: cast_nullable_to_non_nullable + as List?, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$PaymentSplitBillRequestDtoImplCopyWith<$Res> + implements $PaymentSplitBillRequestDtoCopyWith<$Res> { + factory _$$PaymentSplitBillRequestDtoImplCopyWith( + _$PaymentSplitBillRequestDtoImpl value, + $Res Function(_$PaymentSplitBillRequestDtoImpl) then, + ) = __$$PaymentSplitBillRequestDtoImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + @JsonKey(name: "order_id") String? orderId, + @JsonKey(name: "payment_method_id") String? paymentMethodId, + @JsonKey(name: "customer_id") String? customerId, + @JsonKey(name: "customer_name") String? customerName, + @JsonKey(name: "type") String? type, + @JsonKey(name: "amount") int? amount, + @JsonKey(name: "items") List? items, + }); +} + +/// @nodoc +class __$$PaymentSplitBillRequestDtoImplCopyWithImpl<$Res> + extends + _$PaymentSplitBillRequestDtoCopyWithImpl< + $Res, + _$PaymentSplitBillRequestDtoImpl + > + implements _$$PaymentSplitBillRequestDtoImplCopyWith<$Res> { + __$$PaymentSplitBillRequestDtoImplCopyWithImpl( + _$PaymentSplitBillRequestDtoImpl _value, + $Res Function(_$PaymentSplitBillRequestDtoImpl) _then, + ) : super(_value, _then); + + /// Create a copy of PaymentSplitBillRequestDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? orderId = freezed, + Object? paymentMethodId = freezed, + Object? customerId = freezed, + Object? customerName = freezed, + Object? type = freezed, + Object? amount = freezed, + Object? items = freezed, + }) { + return _then( + _$PaymentSplitBillRequestDtoImpl( + orderId: freezed == orderId + ? _value.orderId + : orderId // ignore: cast_nullable_to_non_nullable + as String?, + paymentMethodId: freezed == paymentMethodId + ? _value.paymentMethodId + : paymentMethodId // ignore: cast_nullable_to_non_nullable + as String?, + customerId: freezed == customerId + ? _value.customerId + : customerId // ignore: cast_nullable_to_non_nullable + as String?, + customerName: freezed == customerName + ? _value.customerName + : customerName // ignore: cast_nullable_to_non_nullable + as String?, + type: freezed == type + ? _value.type + : type // ignore: cast_nullable_to_non_nullable + as String?, + amount: freezed == amount + ? _value.amount + : amount // ignore: cast_nullable_to_non_nullable + as int?, + items: freezed == items + ? _value._items + : items // ignore: cast_nullable_to_non_nullable + as List?, + ), + ); + } +} + +/// @nodoc +@JsonSerializable() +class _$PaymentSplitBillRequestDtoImpl extends _PaymentSplitBillRequestDto { + const _$PaymentSplitBillRequestDtoImpl({ + @JsonKey(name: "order_id") this.orderId, + @JsonKey(name: "payment_method_id") this.paymentMethodId, + @JsonKey(name: "customer_id") this.customerId, + @JsonKey(name: "customer_name") this.customerName, + @JsonKey(name: "type") this.type, + @JsonKey(name: "amount") this.amount, + @JsonKey(name: "items") final List? items, + }) : _items = items, + super._(); + + factory _$PaymentSplitBillRequestDtoImpl.fromJson( + Map json, + ) => _$$PaymentSplitBillRequestDtoImplFromJson(json); + + @override + @JsonKey(name: "order_id") + final String? orderId; + @override + @JsonKey(name: "payment_method_id") + final String? paymentMethodId; + @override + @JsonKey(name: "customer_id") + final String? customerId; + @override + @JsonKey(name: "customer_name") + final String? customerName; + @override + @JsonKey(name: "type") + final String? type; + // e.g., "AMOUNT" or "ITEM" + @override + @JsonKey(name: "amount") + final int? amount; + final List? _items; + @override + @JsonKey(name: "items") + List? get items { + final value = _items; + if (value == null) return null; + if (_items is EqualUnmodifiableListView) return _items; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(value); + } + + @override + String toString() { + return 'PaymentSplitBillRequestDto(orderId: $orderId, paymentMethodId: $paymentMethodId, customerId: $customerId, customerName: $customerName, type: $type, amount: $amount, items: $items)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$PaymentSplitBillRequestDtoImpl && + (identical(other.orderId, orderId) || other.orderId == orderId) && + (identical(other.paymentMethodId, paymentMethodId) || + other.paymentMethodId == paymentMethodId) && + (identical(other.customerId, customerId) || + other.customerId == customerId) && + (identical(other.customerName, customerName) || + other.customerName == customerName) && + (identical(other.type, type) || other.type == type) && + (identical(other.amount, amount) || other.amount == amount) && + const DeepCollectionEquality().equals(other._items, _items)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + orderId, + paymentMethodId, + customerId, + customerName, + type, + amount, + const DeepCollectionEquality().hash(_items), + ); + + /// Create a copy of PaymentSplitBillRequestDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$PaymentSplitBillRequestDtoImplCopyWith<_$PaymentSplitBillRequestDtoImpl> + get copyWith => + __$$PaymentSplitBillRequestDtoImplCopyWithImpl< + _$PaymentSplitBillRequestDtoImpl + >(this, _$identity); + + @override + Map toJson() { + return _$$PaymentSplitBillRequestDtoImplToJson(this); + } +} + +abstract class _PaymentSplitBillRequestDto extends PaymentSplitBillRequestDto { + const factory _PaymentSplitBillRequestDto({ + @JsonKey(name: "order_id") final String? orderId, + @JsonKey(name: "payment_method_id") final String? paymentMethodId, + @JsonKey(name: "customer_id") final String? customerId, + @JsonKey(name: "customer_name") final String? customerName, + @JsonKey(name: "type") final String? type, + @JsonKey(name: "amount") final int? amount, + @JsonKey(name: "items") final List? items, + }) = _$PaymentSplitBillRequestDtoImpl; + const _PaymentSplitBillRequestDto._() : super._(); + + factory _PaymentSplitBillRequestDto.fromJson(Map json) = + _$PaymentSplitBillRequestDtoImpl.fromJson; + + @override + @JsonKey(name: "order_id") + String? get orderId; + @override + @JsonKey(name: "payment_method_id") + String? get paymentMethodId; + @override + @JsonKey(name: "customer_id") + String? get customerId; + @override + @JsonKey(name: "customer_name") + String? get customerName; + @override + @JsonKey(name: "type") + String? get type; // e.g., "AMOUNT" or "ITEM" + @override + @JsonKey(name: "amount") + int? get amount; + @override + @JsonKey(name: "items") + List? get items; + + /// Create a copy of PaymentSplitBillRequestDto + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$PaymentSplitBillRequestDtoImplCopyWith<_$PaymentSplitBillRequestDtoImpl> + get copyWith => throw _privateConstructorUsedError; +} + +PaymentItemSplitBillRequestDto _$PaymentItemSplitBillRequestDtoFromJson( + Map json, +) { + return _PaymentItemSplitBillRequestDto.fromJson(json); +} + +/// @nodoc +mixin _$PaymentItemSplitBillRequestDto { + @JsonKey(name: "order_item_id") + String? get orderItemId => throw _privateConstructorUsedError; + @JsonKey(name: "quantity") + int? get quantity => throw _privateConstructorUsedError; + + /// Serializes this PaymentItemSplitBillRequestDto to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of PaymentItemSplitBillRequestDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $PaymentItemSplitBillRequestDtoCopyWith + get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $PaymentItemSplitBillRequestDtoCopyWith<$Res> { + factory $PaymentItemSplitBillRequestDtoCopyWith( + PaymentItemSplitBillRequestDto value, + $Res Function(PaymentItemSplitBillRequestDto) then, + ) = + _$PaymentItemSplitBillRequestDtoCopyWithImpl< + $Res, + PaymentItemSplitBillRequestDto + >; + @useResult + $Res call({ + @JsonKey(name: "order_item_id") String? orderItemId, + @JsonKey(name: "quantity") int? quantity, + }); +} + +/// @nodoc +class _$PaymentItemSplitBillRequestDtoCopyWithImpl< + $Res, + $Val extends PaymentItemSplitBillRequestDto +> + implements $PaymentItemSplitBillRequestDtoCopyWith<$Res> { + _$PaymentItemSplitBillRequestDtoCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of PaymentItemSplitBillRequestDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({Object? orderItemId = freezed, Object? quantity = freezed}) { + return _then( + _value.copyWith( + orderItemId: freezed == orderItemId + ? _value.orderItemId + : orderItemId // ignore: cast_nullable_to_non_nullable + as String?, + quantity: freezed == quantity + ? _value.quantity + : quantity // ignore: cast_nullable_to_non_nullable + as int?, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$PaymentItemSplitBillRequestDtoImplCopyWith<$Res> + implements $PaymentItemSplitBillRequestDtoCopyWith<$Res> { + factory _$$PaymentItemSplitBillRequestDtoImplCopyWith( + _$PaymentItemSplitBillRequestDtoImpl value, + $Res Function(_$PaymentItemSplitBillRequestDtoImpl) then, + ) = __$$PaymentItemSplitBillRequestDtoImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + @JsonKey(name: "order_item_id") String? orderItemId, + @JsonKey(name: "quantity") int? quantity, + }); +} + +/// @nodoc +class __$$PaymentItemSplitBillRequestDtoImplCopyWithImpl<$Res> + extends + _$PaymentItemSplitBillRequestDtoCopyWithImpl< + $Res, + _$PaymentItemSplitBillRequestDtoImpl + > + implements _$$PaymentItemSplitBillRequestDtoImplCopyWith<$Res> { + __$$PaymentItemSplitBillRequestDtoImplCopyWithImpl( + _$PaymentItemSplitBillRequestDtoImpl _value, + $Res Function(_$PaymentItemSplitBillRequestDtoImpl) _then, + ) : super(_value, _then); + + /// Create a copy of PaymentItemSplitBillRequestDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({Object? orderItemId = freezed, Object? quantity = freezed}) { + return _then( + _$PaymentItemSplitBillRequestDtoImpl( + orderItemId: freezed == orderItemId + ? _value.orderItemId + : orderItemId // ignore: cast_nullable_to_non_nullable + as String?, + quantity: freezed == quantity + ? _value.quantity + : quantity // ignore: cast_nullable_to_non_nullable + as int?, + ), + ); + } +} + +/// @nodoc +@JsonSerializable() +class _$PaymentItemSplitBillRequestDtoImpl + extends _PaymentItemSplitBillRequestDto { + const _$PaymentItemSplitBillRequestDtoImpl({ + @JsonKey(name: "order_item_id") this.orderItemId, + @JsonKey(name: "quantity") this.quantity, + }) : super._(); + + factory _$PaymentItemSplitBillRequestDtoImpl.fromJson( + Map json, + ) => _$$PaymentItemSplitBillRequestDtoImplFromJson(json); + + @override + @JsonKey(name: "order_item_id") + final String? orderItemId; + @override + @JsonKey(name: "quantity") + final int? quantity; + + @override + String toString() { + return 'PaymentItemSplitBillRequestDto(orderItemId: $orderItemId, quantity: $quantity)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$PaymentItemSplitBillRequestDtoImpl && + (identical(other.orderItemId, orderItemId) || + other.orderItemId == orderItemId) && + (identical(other.quantity, quantity) || + other.quantity == quantity)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, orderItemId, quantity); + + /// Create a copy of PaymentItemSplitBillRequestDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$PaymentItemSplitBillRequestDtoImplCopyWith< + _$PaymentItemSplitBillRequestDtoImpl + > + get copyWith => + __$$PaymentItemSplitBillRequestDtoImplCopyWithImpl< + _$PaymentItemSplitBillRequestDtoImpl + >(this, _$identity); + + @override + Map toJson() { + return _$$PaymentItemSplitBillRequestDtoImplToJson(this); + } +} + +abstract class _PaymentItemSplitBillRequestDto + extends PaymentItemSplitBillRequestDto { + const factory _PaymentItemSplitBillRequestDto({ + @JsonKey(name: "order_item_id") final String? orderItemId, + @JsonKey(name: "quantity") final int? quantity, + }) = _$PaymentItemSplitBillRequestDtoImpl; + const _PaymentItemSplitBillRequestDto._() : super._(); + + factory _PaymentItemSplitBillRequestDto.fromJson(Map json) = + _$PaymentItemSplitBillRequestDtoImpl.fromJson; + + @override + @JsonKey(name: "order_item_id") + String? get orderItemId; + @override + @JsonKey(name: "quantity") + int? get quantity; + + /// Create a copy of PaymentItemSplitBillRequestDto + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$PaymentItemSplitBillRequestDtoImplCopyWith< + _$PaymentItemSplitBillRequestDtoImpl + > + get copyWith => throw _privateConstructorUsedError; +} + PaymentDto _$PaymentDtoFromJson(Map json) { return _PaymentOrderDto.fromJson(json); } diff --git a/lib/infrastructure/order/order_dtos.g.dart b/lib/infrastructure/order/order_dtos.g.dart index e26b2fd..7db28ac 100644 --- a/lib/infrastructure/order/order_dtos.g.dart +++ b/lib/infrastructure/order/order_dtos.g.dart @@ -220,6 +220,49 @@ Map _$$PaymentItemRequestDtoImplToJson( 'amount': instance.amount, }; +_$PaymentSplitBillRequestDtoImpl _$$PaymentSplitBillRequestDtoImplFromJson( + Map json, +) => _$PaymentSplitBillRequestDtoImpl( + orderId: json['order_id'] as String?, + paymentMethodId: json['payment_method_id'] as String?, + customerId: json['customer_id'] as String?, + customerName: json['customer_name'] as String?, + type: json['type'] as String?, + amount: (json['amount'] as num?)?.toInt(), + items: (json['items'] as List?) + ?.map( + (e) => + PaymentItemSplitBillRequestDto.fromJson(e as Map), + ) + .toList(), +); + +Map _$$PaymentSplitBillRequestDtoImplToJson( + _$PaymentSplitBillRequestDtoImpl instance, +) => { + 'order_id': instance.orderId, + 'payment_method_id': instance.paymentMethodId, + 'customer_id': instance.customerId, + 'customer_name': instance.customerName, + 'type': instance.type, + 'amount': instance.amount, + 'items': instance.items, +}; + +_$PaymentItemSplitBillRequestDtoImpl +_$$PaymentItemSplitBillRequestDtoImplFromJson(Map json) => + _$PaymentItemSplitBillRequestDtoImpl( + orderItemId: json['order_item_id'] as String?, + quantity: (json['quantity'] as num?)?.toInt(), + ); + +Map _$$PaymentItemSplitBillRequestDtoImplToJson( + _$PaymentItemSplitBillRequestDtoImpl instance, +) => { + 'order_item_id': instance.orderItemId, + 'quantity': instance.quantity, +}; + _$PaymentOrderDtoImpl _$$PaymentOrderDtoImplFromJson( Map json, ) => _$PaymentOrderDtoImpl( diff --git a/lib/infrastructure/order/repositories/order_repository.dart b/lib/infrastructure/order/repositories/order_repository.dart index 1b37b98..2e845ec 100644 --- a/lib/infrastructure/order/repositories/order_repository.dart +++ b/lib/infrastructure/order/repositories/order_repository.dart @@ -177,4 +177,25 @@ class OrderRepository implements IOrderRepository { return left(const OrderFailure.unexpectedError()); } } + + @override + Future> createSplitBill( + PaymentSplitBillRequest request, + ) async { + try { + final result = await _dataProvider.createSplitBill( + PaymentSplitBillRequestDto.fromDomain(request), + ); + + if (result.hasError) { + return left(result.error!); + } + + final payment = result.data!.toDomain(); + return right(payment); + } catch (e) { + log('createSplitBillError', name: _logName, error: e); + return left(const OrderFailure.unexpectedError()); + } + } } diff --git a/lib/presentation/pages/payment/payment_page.dart b/lib/presentation/pages/payment/payment_page.dart index 0041d0d..de7034a 100644 --- a/lib/presentation/pages/payment/payment_page.dart +++ b/lib/presentation/pages/payment/payment_page.dart @@ -5,6 +5,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../application/payment/payment_form/payment_form_bloc.dart'; import '../../../application/payment_method/payment_method_loader/payment_method_loader_bloc.dart'; import '../../../common/theme/theme.dart'; +import '../../../common/types/split_type.dart'; import '../../../domain/order/order.dart'; import '../../../injection.dart'; import '../../components/spaces/space.dart'; @@ -16,25 +17,61 @@ import 'widgets/payment_right_panel.dart'; @RoutePage() class PaymentPage extends StatelessWidget implements AutoRouteWrapper { final Order order; - const PaymentPage({super.key, required this.order}); + final bool isSplit; + final SplitType splitType; + final String? customerId; + final String? customerName; + const PaymentPage({ + super.key, + required this.order, + this.isSplit = false, + this.splitType = SplitType.unknown, + this.customerId, + this.customerName, + }); @override Widget build(BuildContext context) { - return BlocListener( - listenWhen: (p, c) => p.failureOrPayment != c.failureOrPayment, - listener: (context, state) { - state.failureOrPayment.fold( - () {}, - (either) => either.fold( - (f) => AppFlushbar.showOrderFailureToast(context, f), - (data) { - if (context.mounted) { - context.router.replace(PaymentSuccessRoute(orderId: order.id)); - } - }, - ), - ); - }, + return MultiBlocListener( + listeners: [ + BlocListener( + listenWhen: (p, c) => p.failureOrPayment != c.failureOrPayment, + listener: (context, state) { + state.failureOrPayment.fold( + () {}, + (either) => either.fold( + (f) => AppFlushbar.showOrderFailureToast(context, f), + (data) { + if (context.mounted) { + context.router.replace( + PaymentSuccessRoute(orderId: order.id), + ); + } + }, + ), + ); + }, + ), + BlocListener( + listenWhen: (p, c) => + p.failureOrPaymentSplitBill != c.failureOrPaymentSplitBill, + listener: (context, state) { + state.failureOrPaymentSplitBill.fold( + () {}, + (either) => either.fold( + (f) => AppFlushbar.showOrderFailureToast(context, f), + (data) { + if (context.mounted) { + context.router.replace( + PaymentSuccessRoute(orderId: order.id), + ); + } + }, + ), + ); + }, + ), + ], child: Scaffold( backgroundColor: AppColor.background, appBar: AppBar( @@ -48,6 +85,24 @@ class PaymentPage extends StatelessWidget implements AutoRouteWrapper { onPressed: () => context.router.maybePop(), icon: Icon(Icons.arrow_back, color: AppColor.primary), ), + actions: [ + if (isSplit) + Container( + padding: EdgeInsets.all(4), + margin: EdgeInsets.only(right: 8), + decoration: BoxDecoration( + border: Border.all(color: AppColor.primary), + borderRadius: BorderRadius.circular(8), + ), + child: Text( + "Split Bill: ${splitType.toStringType()}", + style: AppStyle.sm.copyWith( + fontWeight: FontWeight.w600, + color: AppColor.primary, + ), + ), + ), + ], ), body: LayoutBuilder( builder: (context, constraints) { @@ -68,7 +123,13 @@ class PaymentPage extends StatelessWidget implements AutoRouteWrapper { const SizedBox(width: 24), Expanded( flex: 2, - child: PaymentRightPanel(state: state), + child: PaymentRightPanel( + state: state, + isSplit: isSplit, + splitType: splitType, + customerId: customerId, + customerName: customerName, + ), ), ], ) @@ -77,7 +138,13 @@ class PaymentPage extends StatelessWidget implements AutoRouteWrapper { children: [ PaymentLeftPanel(state: state), const SpaceHeight(24), - PaymentRightPanel(state: state), + PaymentRightPanel( + state: state, + isSplit: isSplit, + splitType: splitType, + customerId: customerId, + customerName: customerName, + ), ], ), ), diff --git a/lib/presentation/pages/payment/widgets/payment_right_panel.dart b/lib/presentation/pages/payment/widgets/payment_right_panel.dart index 5c0fb12..49e2aac 100644 --- a/lib/presentation/pages/payment/widgets/payment_right_panel.dart +++ b/lib/presentation/pages/payment/widgets/payment_right_panel.dart @@ -5,6 +5,7 @@ import '../../../../application/payment/payment_form/payment_form_bloc.dart'; import '../../../../application/payment_method/payment_method_loader/payment_method_loader_bloc.dart'; import '../../../../common/extension/extension.dart'; import '../../../../common/theme/theme.dart'; +import '../../../../common/types/split_type.dart'; import '../../../components/button/button.dart'; import '../../../components/card/payment_card.dart'; import '../../../components/error/payment_method_error_state_widget.dart'; @@ -15,7 +16,18 @@ import '../../../components/toast/flushbar.dart'; class PaymentRightPanel extends StatefulWidget { final PaymentFormState state; - const PaymentRightPanel({super.key, required this.state}); + final bool isSplit; + final SplitType splitType; + final String? customerId; + final String? customerName; + const PaymentRightPanel({ + super.key, + required this.state, + required this.isSplit, + this.customerId, + required this.splitType, + this.customerName, + }); @override State createState() => _PaymentRightPanelState(); @@ -211,9 +223,18 @@ class _PaymentRightPanelState extends State { } if (!widget.state.isSubmitting) { - context.read().add( - PaymentFormEvent.submitted(), - ); + if (widget.isSplit) { + context.read().add( + PaymentFormEvent.submittedSplitBill( + customerId: widget.customerId, + splitType: widget.splitType, + ), + ); + } else { + context.read().add( + PaymentFormEvent.submitted(), + ); + } } }, label: 'Bayar', diff --git a/lib/presentation/pages/split_bill/widgets/split_bill_right_panel.dart b/lib/presentation/pages/split_bill/widgets/split_bill_right_panel.dart index 069b16b..3d0fc81 100644 --- a/lib/presentation/pages/split_bill/widgets/split_bill_right_panel.dart +++ b/lib/presentation/pages/split_bill/widgets/split_bill_right_panel.dart @@ -488,6 +488,12 @@ class _SplitBillRightPanelState extends State { } void _confirmSplit() { + if (widget.state.customerName == '' || widget.state.customer == null) { + AppFlushbar.showError(context, 'Nama Pelanggan harus diisi'); + + return; + } + if (widget.state.splitType.isItem) { int splitTotal = widget.state.totalAmount; if (splitTotal > 0) { @@ -510,6 +516,9 @@ class _SplitBillRightPanelState extends State { context.router.push( PaymentRoute( + isSplit: true, + splitType: widget.state.splitType, + customerId: widget.state.customer?.id, order: widget.state.order.copyWith( orderItems: splitItems, subtotal: splitTotal, @@ -528,6 +537,9 @@ class _SplitBillRightPanelState extends State { widget.state.totalAmount <= totalAmount) { context.router.push( PaymentRoute( + isSplit: true, + splitType: widget.state.splitType, + customerId: widget.state.customer?.id, order: widget.state.order.copyWith( subtotal: widget.state.totalAmount, totalAmount: widget.state.totalAmount, diff --git a/lib/presentation/router/app_router.gr.dart b/lib/presentation/router/app_router.gr.dart index 27c60e6..eda9c50 100644 --- a/lib/presentation/router/app_router.gr.dart +++ b/lib/presentation/router/app_router.gr.dart @@ -9,6 +9,7 @@ // coverage:ignore-file // ignore_for_file: no_leading_underscores_for_library_prefixes +import 'package:apskel_pos_flutter_v2/common/types/split_type.dart' as _i22; import 'package:apskel_pos_flutter_v2/domain/order/order.dart' as _i21; import 'package:apskel_pos_flutter_v2/presentation/pages/auth/login/login_page.dart' as _i4; @@ -174,10 +175,21 @@ class PaymentRoute extends _i19.PageRouteInfo { PaymentRoute({ _i20.Key? key, required _i21.Order order, + bool isSplit = false, + _i22.SplitType splitType = _i22.SplitType.unknown, + String? customerId, + String? customerName, List<_i19.PageRouteInfo>? children, }) : super( PaymentRoute.name, - args: PaymentRouteArgs(key: key, order: order), + args: PaymentRouteArgs( + key: key, + order: order, + isSplit: isSplit, + splitType: splitType, + customerId: customerId, + customerName: customerName, + ), initialChildren: children, ); @@ -188,22 +200,44 @@ class PaymentRoute extends _i19.PageRouteInfo { builder: (data) { final args = data.argsAs(); return _i19.WrappedRoute( - child: _i7.PaymentPage(key: args.key, order: args.order), + child: _i7.PaymentPage( + key: args.key, + order: args.order, + isSplit: args.isSplit, + splitType: args.splitType, + customerId: args.customerId, + customerName: args.customerName, + ), ); }, ); } class PaymentRouteArgs { - const PaymentRouteArgs({this.key, required this.order}); + const PaymentRouteArgs({ + this.key, + required this.order, + this.isSplit = false, + this.splitType = _i22.SplitType.unknown, + this.customerId, + this.customerName, + }); final _i20.Key? key; final _i21.Order order; + final bool isSplit; + + final _i22.SplitType splitType; + + final String? customerId; + + final String? customerName; + @override String toString() { - return 'PaymentRouteArgs{key: $key, order: $order}'; + return 'PaymentRouteArgs{key: $key, order: $order, isSplit: $isSplit, splitType: $splitType, customerId: $customerId, customerName: $customerName}'; } }