dev #1
@ -587,4 +587,39 @@ class OrderRemoteDatasource {
|
||||
return const Left('Terjadi kesalahan tak terduga');
|
||||
}
|
||||
}
|
||||
|
||||
Future<Either<String, PaymentSuccessResponseModel>> createPaymentSplitBill(
|
||||
PaymentSplitBillRequest request) async {
|
||||
final authData = await AuthLocalDataSource().getAuthData();
|
||||
final url = '${Variables.baseUrl}/api/v1/orders/split-bill';
|
||||
|
||||
try {
|
||||
final response = await dio.post(
|
||||
url,
|
||||
data: request.toMap(),
|
||||
options: Options(
|
||||
headers: {
|
||||
'Authorization': 'Bearer ${authData.token}',
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
return Right(PaymentSuccessResponseModel.fromMap(response.data));
|
||||
} else {
|
||||
return const Left('Gagal membuat pembayaran');
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
final errorMessage =
|
||||
e.response?.data['message'] ?? 'Terjadi kesalahan, coba lagi nanti.';
|
||||
log("💥 Dio error: ${e.message}");
|
||||
log("💥 Dio response: ${e.response?.data}");
|
||||
return Left(errorMessage);
|
||||
} catch (e) {
|
||||
log("💥 Unexpected error: $e");
|
||||
return const Left('Terjadi kesalahan tak terduga');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,3 +78,57 @@ class PaymentOrderItemModel {
|
||||
"amount": amount,
|
||||
};
|
||||
}
|
||||
|
||||
class PaymentSplitBillRequest {
|
||||
final String orderId;
|
||||
final String paymentMethodId;
|
||||
final String customerId;
|
||||
final String type; // e.g., "AMOUNT" or "ITEM"
|
||||
final int amount;
|
||||
final List<SplitItem> items;
|
||||
|
||||
PaymentSplitBillRequest({
|
||||
required this.orderId,
|
||||
required this.paymentMethodId,
|
||||
required this.customerId,
|
||||
required this.type,
|
||||
required this.amount,
|
||||
required this.items,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
Map<String, dynamic> data = {
|
||||
'order_id': orderId,
|
||||
'payment_method_id': paymentMethodId,
|
||||
'customer_id': customerId,
|
||||
'type': type,
|
||||
};
|
||||
|
||||
if (type == "AMOUNT") {
|
||||
data['amount'] = amount;
|
||||
}
|
||||
|
||||
if (type == "ITEM") {
|
||||
data['items'] = items.map((e) => e.toJson()).toList();
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class SplitItem {
|
||||
final String orderItemId;
|
||||
final int quantity;
|
||||
|
||||
SplitItem({
|
||||
required this.orderItemId,
|
||||
required this.quantity,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'order_item_id': orderItemId,
|
||||
'quantity': quantity,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +17,14 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class PaymentPage extends StatefulWidget {
|
||||
final Order order;
|
||||
const PaymentPage({Key? key, required this.order}) : super(key: key);
|
||||
final bool isSplit;
|
||||
final String? splitType;
|
||||
const PaymentPage({
|
||||
super.key,
|
||||
required this.order,
|
||||
this.isSplit = false,
|
||||
this.splitType,
|
||||
});
|
||||
|
||||
@override
|
||||
State<PaymentPage> createState() => _PaymentPageState();
|
||||
@ -434,7 +441,7 @@ class _PaymentPageState extends State<PaymentPage> {
|
||||
final itemPending = widget.order.orderItems
|
||||
?.where((item) => item.status == "pending")
|
||||
.toList();
|
||||
|
||||
if (widget.isSplit == false) {
|
||||
final request = PaymentRequestModel(
|
||||
amount: widget.order.totalAmount ?? 0,
|
||||
orderId: widget.order.id,
|
||||
@ -452,5 +459,24 @@ class _PaymentPageState extends State<PaymentPage> {
|
||||
);
|
||||
|
||||
context.read<PaymentFormBloc>().add(PaymentFormEvent.create(request));
|
||||
} else {
|
||||
final request = PaymentSplitBillRequest(
|
||||
amount: widget.order.totalAmount ?? 0,
|
||||
customerId: '',
|
||||
items: itemPending
|
||||
?.map((item) => SplitItem(
|
||||
orderItemId: item.id ?? "",
|
||||
quantity: item.quantity ?? 0,
|
||||
))
|
||||
.toList() ??
|
||||
[],
|
||||
orderId: widget.order.id ?? "",
|
||||
paymentMethodId: selectedPaymentMethod?.id ?? "",
|
||||
type: widget.splitType ?? "",
|
||||
);
|
||||
context.read<PaymentFormBloc>().add(
|
||||
PaymentFormEvent.createSplitBill(request),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,5 +29,22 @@ class PaymentFormBloc extends Bloc<PaymentFormEvent, PaymentFormState> {
|
||||
}
|
||||
},
|
||||
);
|
||||
on<_CreateSplitBill>(
|
||||
(event, emit) async {
|
||||
emit(const _Loading());
|
||||
|
||||
try {
|
||||
final result = await _orderRemoteDatasource
|
||||
.createPaymentSplitBill(event.payment);
|
||||
|
||||
result.fold(
|
||||
(error) => emit(_Error(error)),
|
||||
(success) => emit(_Success(success.data!)),
|
||||
);
|
||||
} catch (e) {
|
||||
emit(_Error("Failed to create payment split bill: $e"));
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,45 +16,45 @@ final _privateConstructorUsedError = UnsupportedError(
|
||||
|
||||
/// @nodoc
|
||||
mixin _$PaymentFormEvent {
|
||||
PaymentRequestModel get payment => throw _privateConstructorUsedError;
|
||||
Object get payment => throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(PaymentRequestModel payment) create,
|
||||
required TResult Function(PaymentSplitBillRequest payment) createSplitBill,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function(PaymentRequestModel payment)? create,
|
||||
TResult? Function(PaymentSplitBillRequest payment)? createSplitBill,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(PaymentRequestModel payment)? create,
|
||||
TResult Function(PaymentSplitBillRequest payment)? createSplitBill,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(_Create value) create,
|
||||
required TResult Function(_CreateSplitBill value) createSplitBill,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult? Function(_Create value)? create,
|
||||
TResult? Function(_CreateSplitBill value)? createSplitBill,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(_Create value)? create,
|
||||
TResult Function(_CreateSplitBill value)? createSplitBill,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of PaymentFormEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$PaymentFormEventCopyWith<PaymentFormEvent> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@ -62,8 +62,6 @@ abstract class $PaymentFormEventCopyWith<$Res> {
|
||||
factory $PaymentFormEventCopyWith(
|
||||
PaymentFormEvent value, $Res Function(PaymentFormEvent) then) =
|
||||
_$PaymentFormEventCopyWithImpl<$Res, PaymentFormEvent>;
|
||||
@useResult
|
||||
$Res call({PaymentRequestModel payment});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@ -78,27 +76,13 @@ class _$PaymentFormEventCopyWithImpl<$Res, $Val extends PaymentFormEvent>
|
||||
|
||||
/// Create a copy of PaymentFormEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? payment = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
payment: null == payment
|
||||
? _value.payment
|
||||
: payment // ignore: cast_nullable_to_non_nullable
|
||||
as PaymentRequestModel,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$CreateImplCopyWith<$Res>
|
||||
implements $PaymentFormEventCopyWith<$Res> {
|
||||
abstract class _$$CreateImplCopyWith<$Res> {
|
||||
factory _$$CreateImplCopyWith(
|
||||
_$CreateImpl value, $Res Function(_$CreateImpl) then) =
|
||||
__$$CreateImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({PaymentRequestModel payment});
|
||||
}
|
||||
@ -163,6 +147,7 @@ class _$CreateImpl implements _Create {
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(PaymentRequestModel payment) create,
|
||||
required TResult Function(PaymentSplitBillRequest payment) createSplitBill,
|
||||
}) {
|
||||
return create(payment);
|
||||
}
|
||||
@ -171,6 +156,7 @@ class _$CreateImpl implements _Create {
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function(PaymentRequestModel payment)? create,
|
||||
TResult? Function(PaymentSplitBillRequest payment)? createSplitBill,
|
||||
}) {
|
||||
return create?.call(payment);
|
||||
}
|
||||
@ -179,6 +165,7 @@ class _$CreateImpl implements _Create {
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(PaymentRequestModel payment)? create,
|
||||
TResult Function(PaymentSplitBillRequest payment)? createSplitBill,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (create != null) {
|
||||
@ -191,6 +178,7 @@ class _$CreateImpl implements _Create {
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(_Create value) create,
|
||||
required TResult Function(_CreateSplitBill value) createSplitBill,
|
||||
}) {
|
||||
return create(this);
|
||||
}
|
||||
@ -199,6 +187,7 @@ class _$CreateImpl implements _Create {
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult? Function(_Create value)? create,
|
||||
TResult? Function(_CreateSplitBill value)? createSplitBill,
|
||||
}) {
|
||||
return create?.call(this);
|
||||
}
|
||||
@ -207,6 +196,7 @@ class _$CreateImpl implements _Create {
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(_Create value)? create,
|
||||
TResult Function(_CreateSplitBill value)? createSplitBill,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (create != null) {
|
||||
@ -224,12 +214,154 @@ abstract class _Create implements PaymentFormEvent {
|
||||
|
||||
/// Create a copy of PaymentFormEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$CreateImplCopyWith<_$CreateImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$CreateSplitBillImplCopyWith<$Res> {
|
||||
factory _$$CreateSplitBillImplCopyWith(_$CreateSplitBillImpl value,
|
||||
$Res Function(_$CreateSplitBillImpl) then) =
|
||||
__$$CreateSplitBillImplCopyWithImpl<$Res>;
|
||||
@useResult
|
||||
$Res call({PaymentSplitBillRequest payment});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$CreateSplitBillImplCopyWithImpl<$Res>
|
||||
extends _$PaymentFormEventCopyWithImpl<$Res, _$CreateSplitBillImpl>
|
||||
implements _$$CreateSplitBillImplCopyWith<$Res> {
|
||||
__$$CreateSplitBillImplCopyWithImpl(
|
||||
_$CreateSplitBillImpl _value, $Res Function(_$CreateSplitBillImpl) _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? payment = null,
|
||||
}) {
|
||||
return _then(_$CreateSplitBillImpl(
|
||||
null == payment
|
||||
? _value.payment
|
||||
: payment // ignore: cast_nullable_to_non_nullable
|
||||
as PaymentSplitBillRequest,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$CreateSplitBillImpl implements _CreateSplitBill {
|
||||
const _$CreateSplitBillImpl(this.payment);
|
||||
|
||||
@override
|
||||
final PaymentSplitBillRequest payment;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PaymentFormEvent.createSplitBill(payment: $payment)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$CreateSplitBillImpl &&
|
||||
(identical(other.payment, payment) || other.payment == payment));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, payment);
|
||||
|
||||
/// 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')
|
||||
_$$CreateSplitBillImplCopyWith<_$CreateSplitBillImpl> get copyWith =>
|
||||
__$$CreateSplitBillImplCopyWithImpl<_$CreateSplitBillImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(PaymentRequestModel payment) create,
|
||||
required TResult Function(PaymentSplitBillRequest payment) createSplitBill,
|
||||
}) {
|
||||
return createSplitBill(payment);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function(PaymentRequestModel payment)? create,
|
||||
TResult? Function(PaymentSplitBillRequest payment)? createSplitBill,
|
||||
}) {
|
||||
return createSplitBill?.call(payment);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(PaymentRequestModel payment)? create,
|
||||
TResult Function(PaymentSplitBillRequest payment)? createSplitBill,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (createSplitBill != null) {
|
||||
return createSplitBill(payment);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(_Create value) create,
|
||||
required TResult Function(_CreateSplitBill value) createSplitBill,
|
||||
}) {
|
||||
return createSplitBill(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult? Function(_Create value)? create,
|
||||
TResult? Function(_CreateSplitBill value)? createSplitBill,
|
||||
}) {
|
||||
return createSplitBill?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(_Create value)? create,
|
||||
TResult Function(_CreateSplitBill value)? createSplitBill,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (createSplitBill != null) {
|
||||
return createSplitBill(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _CreateSplitBill implements PaymentFormEvent {
|
||||
const factory _CreateSplitBill(final PaymentSplitBillRequest payment) =
|
||||
_$CreateSplitBillImpl;
|
||||
|
||||
@override
|
||||
PaymentSplitBillRequest get payment;
|
||||
|
||||
/// Create a copy of PaymentFormEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$CreateSplitBillImplCopyWith<_$CreateSplitBillImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$PaymentFormState {
|
||||
@optionalTypeArgs
|
||||
|
||||
@ -2,5 +2,10 @@ part of 'payment_form_bloc.dart';
|
||||
|
||||
@freezed
|
||||
class PaymentFormEvent with _$PaymentFormEvent {
|
||||
const factory PaymentFormEvent.create(PaymentRequestModel payment) = _Create;
|
||||
const factory PaymentFormEvent.create(
|
||||
PaymentRequestModel payment,
|
||||
) = _Create;
|
||||
const factory PaymentFormEvent.createSplitBill(
|
||||
PaymentSplitBillRequest payment,
|
||||
) = _CreateSplitBill;
|
||||
}
|
||||
|
||||
@ -760,7 +760,11 @@ class _SplitBillPageState extends State<SplitBillPage> {
|
||||
log("Split Order: ${splitItems.length}");
|
||||
|
||||
// Navigate to PaymentPage with the split order
|
||||
context.push(PaymentPage(order: splitOrder));
|
||||
context.push(PaymentPage(
|
||||
order: splitOrder,
|
||||
isSplit: true,
|
||||
splitType: 'ITEM',
|
||||
));
|
||||
} else {
|
||||
AppFlushbar.showError(context, "Pilih minimal satu produk untuk split");
|
||||
}
|
||||
@ -781,7 +785,13 @@ class _SplitBillPageState extends State<SplitBillPage> {
|
||||
);
|
||||
|
||||
// Navigate to PaymentPage with the split order
|
||||
context.push(PaymentPage(order: splitOrder));
|
||||
context.push(
|
||||
PaymentPage(
|
||||
order: splitOrder,
|
||||
isSplit: true,
|
||||
splitType: 'AMOUNT',
|
||||
),
|
||||
);
|
||||
} else if (splitAmount > totalAmount) {
|
||||
AppFlushbar.showError(
|
||||
context, "Jumlah split tidak boleh melebihi total bill");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user