This commit is contained in:
efrilm 2025-10-30 16:35:47 +07:00
parent adc90a90a0
commit b335102677
20 changed files with 1591 additions and 79 deletions

View File

@ -1500,6 +1500,8 @@ abstract class _$$OrderAddedItemsImplCopyWith<$Res> {
) = __$$OrderAddedItemsImplCopyWithImpl<$Res>; ) = __$$OrderAddedItemsImplCopyWithImpl<$Res>;
@useResult @useResult
$Res call({Order? order}); $Res call({Order? order});
$OrderCopyWith<$Res>? get order;
} }
/// @nodoc /// @nodoc
@ -1525,6 +1527,20 @@ class __$$OrderAddedItemsImplCopyWithImpl<$Res>
), ),
); );
} }
/// Create a copy of CheckoutFormEvent
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$OrderCopyWith<$Res>? get order {
if (_value.order == null) {
return null;
}
return $OrderCopyWith<$Res>(_value.order!, (value) {
return _then(_value.copyWith(order: value));
});
}
} }
/// @nodoc /// @nodoc
@ -1720,6 +1736,7 @@ abstract class $CheckoutFormStateCopyWith<$Res> {
bool isLoading, bool isLoading,
}); });
$OrderCopyWith<$Res>? get orderAdded;
$TableCopyWith<$Res>? get table; $TableCopyWith<$Res>? get table;
} }
@ -1811,6 +1828,20 @@ class _$CheckoutFormStateCopyWithImpl<$Res, $Val extends CheckoutFormState>
); );
} }
/// Create a copy of CheckoutFormState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$OrderCopyWith<$Res>? get orderAdded {
if (_value.orderAdded == null) {
return null;
}
return $OrderCopyWith<$Res>(_value.orderAdded!, (value) {
return _then(_value.copyWith(orderAdded: value) as $Val);
});
}
/// Create a copy of CheckoutFormState /// Create a copy of CheckoutFormState
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@override @override
@ -1851,6 +1882,8 @@ abstract class _$$CheckoutFormStateImplCopyWith<$Res>
bool isLoading, bool isLoading,
}); });
@override
$OrderCopyWith<$Res>? get orderAdded;
@override @override
$TableCopyWith<$Res>? get table; $TableCopyWith<$Res>? get table;
} }

View File

@ -108,6 +108,7 @@ class OrderLoaderBloc extends Bloc<OrderLoaderEvent, OrderLoaderState> {
failureOption: none(), failureOption: none(),
page: state.page + 1, page: state.page + 1,
hasReachedMax: orders.orders.length < 10, hasReachedMax: orders.orders.length < 10,
totalOrder: orders.totalCount,
); );
}, },
); );

View File

@ -955,6 +955,7 @@ mixin _$OrderLoaderState {
String? get search => throw _privateConstructorUsedError; String? get search => throw _privateConstructorUsedError;
DateTime get startDate => throw _privateConstructorUsedError; DateTime get startDate => throw _privateConstructorUsedError;
DateTime get endDate => throw _privateConstructorUsedError; DateTime get endDate => throw _privateConstructorUsedError;
int get totalOrder => throw _privateConstructorUsedError;
bool get isFetching => throw _privateConstructorUsedError; bool get isFetching => throw _privateConstructorUsedError;
bool get isFetchingById => throw _privateConstructorUsedError; bool get isFetchingById => throw _privateConstructorUsedError;
bool get hasReachedMax => throw _privateConstructorUsedError; bool get hasReachedMax => throw _privateConstructorUsedError;
@ -983,6 +984,7 @@ abstract class $OrderLoaderStateCopyWith<$Res> {
String? search, String? search,
DateTime startDate, DateTime startDate,
DateTime endDate, DateTime endDate,
int totalOrder,
bool isFetching, bool isFetching,
bool isFetchingById, bool isFetchingById,
bool hasReachedMax, bool hasReachedMax,
@ -1016,6 +1018,7 @@ class _$OrderLoaderStateCopyWithImpl<$Res, $Val extends OrderLoaderState>
Object? search = freezed, Object? search = freezed,
Object? startDate = null, Object? startDate = null,
Object? endDate = null, Object? endDate = null,
Object? totalOrder = null,
Object? isFetching = null, Object? isFetching = null,
Object? isFetchingById = null, Object? isFetchingById = null,
Object? hasReachedMax = null, Object? hasReachedMax = null,
@ -1055,6 +1058,10 @@ class _$OrderLoaderStateCopyWithImpl<$Res, $Val extends OrderLoaderState>
? _value.endDate ? _value.endDate
: endDate // ignore: cast_nullable_to_non_nullable : endDate // ignore: cast_nullable_to_non_nullable
as DateTime, as DateTime,
totalOrder: null == totalOrder
? _value.totalOrder
: totalOrder // ignore: cast_nullable_to_non_nullable
as int,
isFetching: null == isFetching isFetching: null == isFetching
? _value.isFetching ? _value.isFetching
: isFetching // ignore: cast_nullable_to_non_nullable : isFetching // ignore: cast_nullable_to_non_nullable
@ -1119,6 +1126,7 @@ abstract class _$$OrderLoaderStateImplCopyWith<$Res>
String? search, String? search,
DateTime startDate, DateTime startDate,
DateTime endDate, DateTime endDate,
int totalOrder,
bool isFetching, bool isFetching,
bool isFetchingById, bool isFetchingById,
bool hasReachedMax, bool hasReachedMax,
@ -1153,6 +1161,7 @@ class __$$OrderLoaderStateImplCopyWithImpl<$Res>
Object? search = freezed, Object? search = freezed,
Object? startDate = null, Object? startDate = null,
Object? endDate = null, Object? endDate = null,
Object? totalOrder = null,
Object? isFetching = null, Object? isFetching = null,
Object? isFetchingById = null, Object? isFetchingById = null,
Object? hasReachedMax = null, Object? hasReachedMax = null,
@ -1192,6 +1201,10 @@ class __$$OrderLoaderStateImplCopyWithImpl<$Res>
? _value.endDate ? _value.endDate
: endDate // ignore: cast_nullable_to_non_nullable : endDate // ignore: cast_nullable_to_non_nullable
as DateTime, as DateTime,
totalOrder: null == totalOrder
? _value.totalOrder
: totalOrder // ignore: cast_nullable_to_non_nullable
as int,
isFetching: null == isFetching isFetching: null == isFetching
? _value.isFetching ? _value.isFetching
: isFetching // ignore: cast_nullable_to_non_nullable : isFetching // ignore: cast_nullable_to_non_nullable
@ -1225,6 +1238,7 @@ class _$OrderLoaderStateImpl implements _OrderLoaderState {
this.search, this.search,
required this.startDate, required this.startDate,
required this.endDate, required this.endDate,
this.totalOrder = 0,
this.isFetching = false, this.isFetching = false,
this.isFetchingById = false, this.isFetchingById = false,
this.hasReachedMax = false, this.hasReachedMax = false,
@ -1255,6 +1269,9 @@ class _$OrderLoaderStateImpl implements _OrderLoaderState {
final DateTime endDate; final DateTime endDate;
@override @override
@JsonKey() @JsonKey()
final int totalOrder;
@override
@JsonKey()
final bool isFetching; final bool isFetching;
@override @override
@JsonKey() @JsonKey()
@ -1268,7 +1285,7 @@ class _$OrderLoaderStateImpl implements _OrderLoaderState {
@override @override
String toString() { String toString() {
return 'OrderLoaderState(orders: $orders, failureOption: $failureOption, failureOptionGetById: $failureOptionGetById, order: $order, selectedOrder: $selectedOrder, search: $search, startDate: $startDate, endDate: $endDate, isFetching: $isFetching, isFetchingById: $isFetchingById, hasReachedMax: $hasReachedMax, page: $page)'; return 'OrderLoaderState(orders: $orders, failureOption: $failureOption, failureOptionGetById: $failureOptionGetById, order: $order, selectedOrder: $selectedOrder, search: $search, startDate: $startDate, endDate: $endDate, totalOrder: $totalOrder, isFetching: $isFetching, isFetchingById: $isFetchingById, hasReachedMax: $hasReachedMax, page: $page)';
} }
@override @override
@ -1288,6 +1305,8 @@ class _$OrderLoaderStateImpl implements _OrderLoaderState {
(identical(other.startDate, startDate) || (identical(other.startDate, startDate) ||
other.startDate == startDate) && other.startDate == startDate) &&
(identical(other.endDate, endDate) || other.endDate == endDate) && (identical(other.endDate, endDate) || other.endDate == endDate) &&
(identical(other.totalOrder, totalOrder) ||
other.totalOrder == totalOrder) &&
(identical(other.isFetching, isFetching) || (identical(other.isFetching, isFetching) ||
other.isFetching == isFetching) && other.isFetching == isFetching) &&
(identical(other.isFetchingById, isFetchingById) || (identical(other.isFetchingById, isFetchingById) ||
@ -1308,6 +1327,7 @@ class _$OrderLoaderStateImpl implements _OrderLoaderState {
search, search,
startDate, startDate,
endDate, endDate,
totalOrder,
isFetching, isFetching,
isFetchingById, isFetchingById,
hasReachedMax, hasReachedMax,
@ -1336,6 +1356,7 @@ abstract class _OrderLoaderState implements OrderLoaderState {
final String? search, final String? search,
required final DateTime startDate, required final DateTime startDate,
required final DateTime endDate, required final DateTime endDate,
final int totalOrder,
final bool isFetching, final bool isFetching,
final bool isFetchingById, final bool isFetchingById,
final bool hasReachedMax, final bool hasReachedMax,
@ -1359,6 +1380,8 @@ abstract class _OrderLoaderState implements OrderLoaderState {
@override @override
DateTime get endDate; DateTime get endDate;
@override @override
int get totalOrder;
@override
bool get isFetching; bool get isFetching;
@override @override
bool get isFetchingById; bool get isFetchingById;

View File

@ -11,6 +11,7 @@ class OrderLoaderState with _$OrderLoaderState {
String? search, String? search,
required DateTime startDate, required DateTime startDate,
required DateTime endDate, required DateTime endDate,
@Default(0) int totalOrder,
@Default(false) bool isFetching, @Default(false) bool isFetching,
@Default(false) bool isFetchingById, @Default(false) bool isFetchingById,
@Default(false) bool hasReachedMax, @Default(false) bool hasReachedMax,

View File

@ -0,0 +1,69 @@
import 'package:bloc/bloc.dart';
import 'package:dartz/dartz.dart' hide Order;
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:injectable/injectable.dart' hide Order;
import '../../../domain/order/order.dart';
import '../../../domain/payment_method/payment_method.dart';
part 'payment_form_event.dart';
part 'payment_form_state.dart';
part 'payment_form_bloc.freezed.dart';
@injectable
class PaymentFormBloc extends Bloc<PaymentFormEvent, PaymentFormState> {
final IOrderRepository _repository;
PaymentFormBloc(this._repository) : super(PaymentFormState.initial()) {
on<PaymentFormEvent>(_onPaymentFormEvent);
}
Future<void> _onPaymentFormEvent(
PaymentFormEvent event,
Emitter<PaymentFormState> emit,
) {
return event.map(
setOrder: (e) async {
List<OrderItem> pendingItems = e.order.orderItems
.where((item) => item.status == 'pending')
.toList();
emit(state.copyWith(order: e.order, pendingItems: pendingItems));
},
setPaymentMethod: (e) async {
emit(state.copyWith(paymentMethod: e.paymentMethod));
},
submitted: (e) async {
Either<OrderFailure, Payment> failureOrPayment;
emit(state.copyWith(isSubmitting: true, failureOrPayment: none()));
final request = PaymentRequest(
orderId: state.order.id,
paymentMethodId: state.paymentMethod?.id ?? '',
amount: state.order.totalAmount,
transactionId: '',
splitNumber: 1,
splitTotal: 1,
splitDescription: '',
paymentOrderItems: state.pendingItems
.map(
(item) => PaymentItemRequest(
orderItemId: item.id,
amount: item.totalPrice,
),
)
.toList(),
);
failureOrPayment = await _repository.createPayment(request: request);
emit(
state.copyWith(
isSubmitting: false,
failureOrPayment: optionOf(failureOrPayment),
),
);
},
);
}
}

View File

@ -0,0 +1,795 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'payment_form_bloc.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models',
);
/// @nodoc
mixin _$PaymentFormEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(Order order) setOrder,
required TResult Function(PaymentMethod paymentMethod) setPaymentMethod,
required TResult Function() submitted,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(Order order)? setOrder,
TResult? Function(PaymentMethod paymentMethod)? setPaymentMethod,
TResult? Function()? submitted,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(Order order)? setOrder,
TResult Function(PaymentMethod paymentMethod)? setPaymentMethod,
TResult Function()? submitted,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_SetOrder value) setOrder,
required TResult Function(_SetPayment value) setPaymentMethod,
required TResult Function(_Submitted value) submitted,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_SetOrder value)? setOrder,
TResult? Function(_SetPayment value)? setPaymentMethod,
TResult? Function(_Submitted value)? submitted,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_SetOrder value)? setOrder,
TResult Function(_SetPayment value)? setPaymentMethod,
TResult Function(_Submitted value)? submitted,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $PaymentFormEventCopyWith<$Res> {
factory $PaymentFormEventCopyWith(
PaymentFormEvent value,
$Res Function(PaymentFormEvent) then,
) = _$PaymentFormEventCopyWithImpl<$Res, PaymentFormEvent>;
}
/// @nodoc
class _$PaymentFormEventCopyWithImpl<$Res, $Val extends PaymentFormEvent>
implements $PaymentFormEventCopyWith<$Res> {
_$PaymentFormEventCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of PaymentFormEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$SetOrderImplCopyWith<$Res> {
factory _$$SetOrderImplCopyWith(
_$SetOrderImpl value,
$Res Function(_$SetOrderImpl) then,
) = __$$SetOrderImplCopyWithImpl<$Res>;
@useResult
$Res call({Order order});
$OrderCopyWith<$Res> get order;
}
/// @nodoc
class __$$SetOrderImplCopyWithImpl<$Res>
extends _$PaymentFormEventCopyWithImpl<$Res, _$SetOrderImpl>
implements _$$SetOrderImplCopyWith<$Res> {
__$$SetOrderImplCopyWithImpl(
_$SetOrderImpl _value,
$Res Function(_$SetOrderImpl) _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? order = null}) {
return _then(
_$SetOrderImpl(
null == order
? _value.order
: order // ignore: cast_nullable_to_non_nullable
as Order,
),
);
}
/// Create a copy of PaymentFormEvent
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$OrderCopyWith<$Res> get order {
return $OrderCopyWith<$Res>(_value.order, (value) {
return _then(_value.copyWith(order: value));
});
}
}
/// @nodoc
class _$SetOrderImpl implements _SetOrder {
const _$SetOrderImpl(this.order);
@override
final Order order;
@override
String toString() {
return 'PaymentFormEvent.setOrder(order: $order)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$SetOrderImpl &&
(identical(other.order, order) || other.order == order));
}
@override
int get hashCode => Object.hash(runtimeType, order);
/// 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')
_$$SetOrderImplCopyWith<_$SetOrderImpl> get copyWith =>
__$$SetOrderImplCopyWithImpl<_$SetOrderImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(Order order) setOrder,
required TResult Function(PaymentMethod paymentMethod) setPaymentMethod,
required TResult Function() submitted,
}) {
return setOrder(order);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(Order order)? setOrder,
TResult? Function(PaymentMethod paymentMethod)? setPaymentMethod,
TResult? Function()? submitted,
}) {
return setOrder?.call(order);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(Order order)? setOrder,
TResult Function(PaymentMethod paymentMethod)? setPaymentMethod,
TResult Function()? submitted,
required TResult orElse(),
}) {
if (setOrder != null) {
return setOrder(order);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_SetOrder value) setOrder,
required TResult Function(_SetPayment value) setPaymentMethod,
required TResult Function(_Submitted value) submitted,
}) {
return setOrder(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_SetOrder value)? setOrder,
TResult? Function(_SetPayment value)? setPaymentMethod,
TResult? Function(_Submitted value)? submitted,
}) {
return setOrder?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_SetOrder value)? setOrder,
TResult Function(_SetPayment value)? setPaymentMethod,
TResult Function(_Submitted value)? submitted,
required TResult orElse(),
}) {
if (setOrder != null) {
return setOrder(this);
}
return orElse();
}
}
abstract class _SetOrder implements PaymentFormEvent {
const factory _SetOrder(final Order order) = _$SetOrderImpl;
Order get order;
/// Create a copy of PaymentFormEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$SetOrderImplCopyWith<_$SetOrderImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$SetPaymentImplCopyWith<$Res> {
factory _$$SetPaymentImplCopyWith(
_$SetPaymentImpl value,
$Res Function(_$SetPaymentImpl) then,
) = __$$SetPaymentImplCopyWithImpl<$Res>;
@useResult
$Res call({PaymentMethod paymentMethod});
$PaymentMethodCopyWith<$Res> get paymentMethod;
}
/// @nodoc
class __$$SetPaymentImplCopyWithImpl<$Res>
extends _$PaymentFormEventCopyWithImpl<$Res, _$SetPaymentImpl>
implements _$$SetPaymentImplCopyWith<$Res> {
__$$SetPaymentImplCopyWithImpl(
_$SetPaymentImpl _value,
$Res Function(_$SetPaymentImpl) _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? paymentMethod = null}) {
return _then(
_$SetPaymentImpl(
null == paymentMethod
? _value.paymentMethod
: paymentMethod // ignore: cast_nullable_to_non_nullable
as PaymentMethod,
),
);
}
/// Create a copy of PaymentFormEvent
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$PaymentMethodCopyWith<$Res> get paymentMethod {
return $PaymentMethodCopyWith<$Res>(_value.paymentMethod, (value) {
return _then(_value.copyWith(paymentMethod: value));
});
}
}
/// @nodoc
class _$SetPaymentImpl implements _SetPayment {
const _$SetPaymentImpl(this.paymentMethod);
@override
final PaymentMethod paymentMethod;
@override
String toString() {
return 'PaymentFormEvent.setPaymentMethod(paymentMethod: $paymentMethod)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$SetPaymentImpl &&
(identical(other.paymentMethod, paymentMethod) ||
other.paymentMethod == paymentMethod));
}
@override
int get hashCode => Object.hash(runtimeType, paymentMethod);
/// 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')
_$$SetPaymentImplCopyWith<_$SetPaymentImpl> get copyWith =>
__$$SetPaymentImplCopyWithImpl<_$SetPaymentImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(Order order) setOrder,
required TResult Function(PaymentMethod paymentMethod) setPaymentMethod,
required TResult Function() submitted,
}) {
return setPaymentMethod(paymentMethod);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(Order order)? setOrder,
TResult? Function(PaymentMethod paymentMethod)? setPaymentMethod,
TResult? Function()? submitted,
}) {
return setPaymentMethod?.call(paymentMethod);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(Order order)? setOrder,
TResult Function(PaymentMethod paymentMethod)? setPaymentMethod,
TResult Function()? submitted,
required TResult orElse(),
}) {
if (setPaymentMethod != null) {
return setPaymentMethod(paymentMethod);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_SetOrder value) setOrder,
required TResult Function(_SetPayment value) setPaymentMethod,
required TResult Function(_Submitted value) submitted,
}) {
return setPaymentMethod(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_SetOrder value)? setOrder,
TResult? Function(_SetPayment value)? setPaymentMethod,
TResult? Function(_Submitted value)? submitted,
}) {
return setPaymentMethod?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_SetOrder value)? setOrder,
TResult Function(_SetPayment value)? setPaymentMethod,
TResult Function(_Submitted value)? submitted,
required TResult orElse(),
}) {
if (setPaymentMethod != null) {
return setPaymentMethod(this);
}
return orElse();
}
}
abstract class _SetPayment implements PaymentFormEvent {
const factory _SetPayment(final PaymentMethod paymentMethod) =
_$SetPaymentImpl;
PaymentMethod get paymentMethod;
/// Create a copy of PaymentFormEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$SetPaymentImplCopyWith<_$SetPaymentImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$SubmittedImplCopyWith<$Res> {
factory _$$SubmittedImplCopyWith(
_$SubmittedImpl value,
$Res Function(_$SubmittedImpl) then,
) = __$$SubmittedImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$SubmittedImplCopyWithImpl<$Res>
extends _$PaymentFormEventCopyWithImpl<$Res, _$SubmittedImpl>
implements _$$SubmittedImplCopyWith<$Res> {
__$$SubmittedImplCopyWithImpl(
_$SubmittedImpl _value,
$Res Function(_$SubmittedImpl) _then,
) : super(_value, _then);
/// Create a copy of PaymentFormEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$SubmittedImpl implements _Submitted {
const _$SubmittedImpl();
@override
String toString() {
return 'PaymentFormEvent.submitted()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$SubmittedImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(Order order) setOrder,
required TResult Function(PaymentMethod paymentMethod) setPaymentMethod,
required TResult Function() submitted,
}) {
return submitted();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(Order order)? setOrder,
TResult? Function(PaymentMethod paymentMethod)? setPaymentMethod,
TResult? Function()? submitted,
}) {
return submitted?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(Order order)? setOrder,
TResult Function(PaymentMethod paymentMethod)? setPaymentMethod,
TResult Function()? submitted,
required TResult orElse(),
}) {
if (submitted != null) {
return submitted();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_SetOrder value) setOrder,
required TResult Function(_SetPayment value) setPaymentMethod,
required TResult Function(_Submitted value) submitted,
}) {
return submitted(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_SetOrder value)? setOrder,
TResult? Function(_SetPayment value)? setPaymentMethod,
TResult? Function(_Submitted value)? submitted,
}) {
return submitted?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_SetOrder value)? setOrder,
TResult Function(_SetPayment value)? setPaymentMethod,
TResult Function(_Submitted value)? submitted,
required TResult orElse(),
}) {
if (submitted != null) {
return submitted(this);
}
return orElse();
}
}
abstract class _Submitted implements PaymentFormEvent {
const factory _Submitted() = _$SubmittedImpl;
}
/// @nodoc
mixin _$PaymentFormState {
Order get order => throw _privateConstructorUsedError;
List<OrderItem> get pendingItems => throw _privateConstructorUsedError;
Option<Either<OrderFailure, Payment>> get failureOrPayment =>
throw _privateConstructorUsedError;
PaymentMethod? get paymentMethod => throw _privateConstructorUsedError;
bool get isSubmitting => throw _privateConstructorUsedError;
/// Create a copy of PaymentFormState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$PaymentFormStateCopyWith<PaymentFormState> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $PaymentFormStateCopyWith<$Res> {
factory $PaymentFormStateCopyWith(
PaymentFormState value,
$Res Function(PaymentFormState) then,
) = _$PaymentFormStateCopyWithImpl<$Res, PaymentFormState>;
@useResult
$Res call({
Order order,
List<OrderItem> pendingItems,
Option<Either<OrderFailure, Payment>> failureOrPayment,
PaymentMethod? paymentMethod,
bool isSubmitting,
});
$OrderCopyWith<$Res> get order;
$PaymentMethodCopyWith<$Res>? get paymentMethod;
}
/// @nodoc
class _$PaymentFormStateCopyWithImpl<$Res, $Val extends PaymentFormState>
implements $PaymentFormStateCopyWith<$Res> {
_$PaymentFormStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of PaymentFormState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? order = null,
Object? pendingItems = null,
Object? failureOrPayment = null,
Object? paymentMethod = freezed,
Object? isSubmitting = null,
}) {
return _then(
_value.copyWith(
order: null == order
? _value.order
: order // ignore: cast_nullable_to_non_nullable
as Order,
pendingItems: null == pendingItems
? _value.pendingItems
: pendingItems // ignore: cast_nullable_to_non_nullable
as List<OrderItem>,
failureOrPayment: null == failureOrPayment
? _value.failureOrPayment
: failureOrPayment // ignore: cast_nullable_to_non_nullable
as Option<Either<OrderFailure, Payment>>,
paymentMethod: freezed == paymentMethod
? _value.paymentMethod
: paymentMethod // ignore: cast_nullable_to_non_nullable
as PaymentMethod?,
isSubmitting: null == isSubmitting
? _value.isSubmitting
: isSubmitting // ignore: cast_nullable_to_non_nullable
as bool,
)
as $Val,
);
}
/// Create a copy of PaymentFormState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$OrderCopyWith<$Res> get order {
return $OrderCopyWith<$Res>(_value.order, (value) {
return _then(_value.copyWith(order: value) as $Val);
});
}
/// Create a copy of PaymentFormState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$PaymentMethodCopyWith<$Res>? get paymentMethod {
if (_value.paymentMethod == null) {
return null;
}
return $PaymentMethodCopyWith<$Res>(_value.paymentMethod!, (value) {
return _then(_value.copyWith(paymentMethod: value) as $Val);
});
}
}
/// @nodoc
abstract class _$$PaymentFormStateImplCopyWith<$Res>
implements $PaymentFormStateCopyWith<$Res> {
factory _$$PaymentFormStateImplCopyWith(
_$PaymentFormStateImpl value,
$Res Function(_$PaymentFormStateImpl) then,
) = __$$PaymentFormStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
Order order,
List<OrderItem> pendingItems,
Option<Either<OrderFailure, Payment>> failureOrPayment,
PaymentMethod? paymentMethod,
bool isSubmitting,
});
@override
$OrderCopyWith<$Res> get order;
@override
$PaymentMethodCopyWith<$Res>? get paymentMethod;
}
/// @nodoc
class __$$PaymentFormStateImplCopyWithImpl<$Res>
extends _$PaymentFormStateCopyWithImpl<$Res, _$PaymentFormStateImpl>
implements _$$PaymentFormStateImplCopyWith<$Res> {
__$$PaymentFormStateImplCopyWithImpl(
_$PaymentFormStateImpl _value,
$Res Function(_$PaymentFormStateImpl) _then,
) : super(_value, _then);
/// Create a copy of PaymentFormState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? order = null,
Object? pendingItems = null,
Object? failureOrPayment = null,
Object? paymentMethod = freezed,
Object? isSubmitting = null,
}) {
return _then(
_$PaymentFormStateImpl(
order: null == order
? _value.order
: order // ignore: cast_nullable_to_non_nullable
as Order,
pendingItems: null == pendingItems
? _value._pendingItems
: pendingItems // ignore: cast_nullable_to_non_nullable
as List<OrderItem>,
failureOrPayment: null == failureOrPayment
? _value.failureOrPayment
: failureOrPayment // ignore: cast_nullable_to_non_nullable
as Option<Either<OrderFailure, Payment>>,
paymentMethod: freezed == paymentMethod
? _value.paymentMethod
: paymentMethod // ignore: cast_nullable_to_non_nullable
as PaymentMethod?,
isSubmitting: null == isSubmitting
? _value.isSubmitting
: isSubmitting // ignore: cast_nullable_to_non_nullable
as bool,
),
);
}
}
/// @nodoc
class _$PaymentFormStateImpl implements _PaymentFormState {
_$PaymentFormStateImpl({
required this.order,
required final List<OrderItem> pendingItems,
required this.failureOrPayment,
this.paymentMethod,
this.isSubmitting = false,
}) : _pendingItems = pendingItems;
@override
final Order order;
final List<OrderItem> _pendingItems;
@override
List<OrderItem> get pendingItems {
if (_pendingItems is EqualUnmodifiableListView) return _pendingItems;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_pendingItems);
}
@override
final Option<Either<OrderFailure, Payment>> failureOrPayment;
@override
final PaymentMethod? paymentMethod;
@override
@JsonKey()
final bool isSubmitting;
@override
String toString() {
return 'PaymentFormState(order: $order, pendingItems: $pendingItems, failureOrPayment: $failureOrPayment, paymentMethod: $paymentMethod, isSubmitting: $isSubmitting)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$PaymentFormStateImpl &&
(identical(other.order, order) || other.order == order) &&
const DeepCollectionEquality().equals(
other._pendingItems,
_pendingItems,
) &&
(identical(other.failureOrPayment, failureOrPayment) ||
other.failureOrPayment == failureOrPayment) &&
(identical(other.paymentMethod, paymentMethod) ||
other.paymentMethod == paymentMethod) &&
(identical(other.isSubmitting, isSubmitting) ||
other.isSubmitting == isSubmitting));
}
@override
int get hashCode => Object.hash(
runtimeType,
order,
const DeepCollectionEquality().hash(_pendingItems),
failureOrPayment,
paymentMethod,
isSubmitting,
);
/// Create a copy of PaymentFormState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$PaymentFormStateImplCopyWith<_$PaymentFormStateImpl> get copyWith =>
__$$PaymentFormStateImplCopyWithImpl<_$PaymentFormStateImpl>(
this,
_$identity,
);
}
abstract class _PaymentFormState implements PaymentFormState {
factory _PaymentFormState({
required final Order order,
required final List<OrderItem> pendingItems,
required final Option<Either<OrderFailure, Payment>> failureOrPayment,
final PaymentMethod? paymentMethod,
final bool isSubmitting,
}) = _$PaymentFormStateImpl;
@override
Order get order;
@override
List<OrderItem> get pendingItems;
@override
Option<Either<OrderFailure, Payment>> get failureOrPayment;
@override
PaymentMethod? get paymentMethod;
@override
bool get isSubmitting;
/// Create a copy of PaymentFormState
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$PaymentFormStateImplCopyWith<_$PaymentFormStateImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,9 @@
part of 'payment_form_bloc.dart';
@freezed
class PaymentFormEvent with _$PaymentFormEvent {
const factory PaymentFormEvent.setOrder(Order order) = _SetOrder;
const factory PaymentFormEvent.setPaymentMethod(PaymentMethod paymentMethod) =
_SetPayment;
const factory PaymentFormEvent.submitted() = _Submitted;
}

View File

@ -0,0 +1,18 @@
part of 'payment_form_bloc.dart';
@freezed
class PaymentFormState with _$PaymentFormState {
factory PaymentFormState({
required Order order,
required List<OrderItem> pendingItems,
required Option<Either<OrderFailure, Payment>> failureOrPayment,
PaymentMethod? paymentMethod,
@Default(false) bool isSubmitting,
}) = _PaymentFormState;
factory PaymentFormState.initial() => PaymentFormState(
order: Order.empty(),
pendingItems: [],
failureOrPayment: none(),
);
}

View File

@ -25,4 +25,8 @@ abstract class IOrderRepository {
required String id, required String id,
required List<AddItemOrderRequest> request, required List<AddItemOrderRequest> request,
}); });
Future<Either<OrderFailure, Payment>> createPayment({
required PaymentRequest request,
});
} }

View File

@ -31,6 +31,20 @@ class PaymentRequestDto with _$PaymentRequestDto {
paymentOrderItems: paymentOrderItems:
paymentOrderItems?.map((e) => e.toDomain()).toList() ?? const [], paymentOrderItems?.map((e) => e.toDomain()).toList() ?? const [],
); );
factory PaymentRequestDto.fromDomain(PaymentRequest request) =>
PaymentRequestDto(
orderId: request.orderId,
paymentMethodId: request.paymentMethodId,
amount: request.amount,
transactionId: request.transactionId,
splitNumber: request.splitNumber,
splitTotal: request.splitTotal,
splitDescription: request.splitDescription,
paymentOrderItems: request.paymentOrderItems
.map((e) => PaymentItemRequestDto.fromDomain(e))
.toList(),
);
} }
@freezed @freezed
@ -48,4 +62,10 @@ class PaymentItemRequestDto with _$PaymentItemRequestDto {
// Optional: mapper ke domain entity // Optional: mapper ke domain entity
PaymentItemRequest toDomain() => PaymentItemRequest toDomain() =>
PaymentItemRequest(orderItemId: orderItemId ?? '', amount: amount ?? 0); PaymentItemRequest(orderItemId: orderItemId ?? '', amount: amount ?? 0);
factory PaymentItemRequestDto.fromDomain(PaymentItemRequest request) =>
PaymentItemRequestDto(
orderItemId: request.orderItemId,
amount: request.amount,
);
} }

View File

@ -130,4 +130,25 @@ class OrderRepository implements IOrderRepository {
return left(const OrderFailure.unexpectedError()); return left(const OrderFailure.unexpectedError());
} }
} }
@override
Future<Either<OrderFailure, Payment>> createPayment({
required PaymentRequest request,
}) async {
try {
final result = await _dataProvider.storePayment(
PaymentRequestDto.fromDomain(request),
);
if (result.hasError) {
return left(result.error!);
}
final payment = result.data!.toDomain();
return right(payment);
} catch (e) {
log('createPaymentError', name: _logName, error: e);
return left(const OrderFailure.unexpectedError());
}
}
} }

View File

@ -24,6 +24,8 @@ import 'package:apskel_pos_flutter_v2/application/order/order_loader/order_loade
as _i94; as _i94;
import 'package:apskel_pos_flutter_v2/application/outlet/outlet_loader/outlet_loader_bloc.dart' import 'package:apskel_pos_flutter_v2/application/outlet/outlet_loader/outlet_loader_bloc.dart'
as _i76; as _i76;
import 'package:apskel_pos_flutter_v2/application/payment/payment_form/payment_form_bloc.dart'
as _i194;
import 'package:apskel_pos_flutter_v2/application/payment_method/payment_method_loader/payment_method_loader_bloc.dart' import 'package:apskel_pos_flutter_v2/application/payment_method/payment_method_loader/payment_method_loader_bloc.dart'
as _i952; as _i952;
import 'package:apskel_pos_flutter_v2/application/product/product_loader/product_loader_bloc.dart' import 'package:apskel_pos_flutter_v2/application/product/product_loader/product_loader_bloc.dart'
@ -232,6 +234,9 @@ extension GetItInjectableX on _i174.GetIt {
gh.factory<_i94.OrderLoaderBloc>( gh.factory<_i94.OrderLoaderBloc>(
() => _i94.OrderLoaderBloc(gh<_i299.IOrderRepository>()), () => _i94.OrderLoaderBloc(gh<_i299.IOrderRepository>()),
); );
gh.factory<_i194.PaymentFormBloc>(
() => _i194.PaymentFormBloc(gh<_i299.IOrderRepository>()),
);
gh.factory<_i683.CustomerLoaderBloc>( gh.factory<_i683.CustomerLoaderBloc>(
() => _i683.CustomerLoaderBloc(gh<_i143.ICustomerRepository>()), () => _i683.CustomerLoaderBloc(gh<_i143.ICustomerRepository>()),
); );

View File

@ -36,6 +36,7 @@ class _OrderLeftPanelState extends State<OrderLeftPanel> {
child: Column( child: Column(
children: [ children: [
OrderTitle( OrderTitle(
totalOrder: widget.state.totalOrder,
startDate: widget.state.startDate, startDate: widget.state.startDate,
endDate: widget.state.endDate, endDate: widget.state.endDate,
title: widget.status == 'pending' title: widget.status == 'pending'

View File

@ -1,9 +1,11 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../../application/order/order_loader/order_loader_bloc.dart'; import '../../../../application/order/order_loader/order_loader_bloc.dart';
import '../../../../common/theme/theme.dart'; import '../../../../common/theme/theme.dart';
import '../../../components/button/button.dart'; import '../../../components/button/button.dart';
import '../../../components/spaces/space.dart'; import '../../../components/spaces/space.dart';
import '../../../router/app_router.gr.dart';
import 'order_information.dart'; import 'order_information.dart';
import 'order_list.dart'; import 'order_list.dart';
import 'order_list_payment.dart'; import 'order_list_payment.dart';
@ -100,7 +102,11 @@ class OrderRightPanel extends StatelessWidget {
SpaceWidth(8), SpaceWidth(8),
AppElevatedButton.filled( AppElevatedButton.filled(
width: 120, width: 120,
onPressed: () {}, onPressed: () {
context.router.push(
PaymentRoute(order: state.selectedOrder!),
);
},
label: 'Bayar', label: 'Bayar',
icon: Icon(Icons.payment, color: Colors.white), icon: Icon(Icons.payment, color: Colors.white),
), ),

View File

@ -13,6 +13,7 @@ class OrderTitle extends StatelessWidget {
final DateTime endDate; final DateTime endDate;
final Function(String) onChanged; final Function(String) onChanged;
final void Function(DateTime? start, DateTime? end) onDateRangeChanged; final void Function(DateTime? start, DateTime? end) onDateRangeChanged;
final int totalOrder;
const OrderTitle({ const OrderTitle({
super.key, super.key,
required this.title, required this.title,
@ -20,6 +21,7 @@ class OrderTitle extends StatelessWidget {
required this.endDate, required this.endDate,
required this.onChanged, required this.onChanged,
required this.onDateRangeChanged, required this.onDateRangeChanged,
required this.totalOrder,
}); });
@override @override
@ -46,7 +48,7 @@ class OrderTitle extends StatelessWidget {
style: AppStyle.md.copyWith(fontWeight: FontWeight.w600), style: AppStyle.md.copyWith(fontWeight: FontWeight.w600),
), ),
Text( Text(
'0 Pesanan', '$totalOrder Pesanan',
style: AppStyle.md.copyWith(fontWeight: FontWeight.w600), style: AppStyle.md.copyWith(fontWeight: FontWeight.w600),
), ),
], ],

View File

@ -0,0 +1,103 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
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 '../../../domain/order/order.dart';
import '../../../injection.dart';
import '../../components/spaces/space.dart';
import '../../components/toast/flushbar.dart';
import 'widgets/payment_left_panel.dart';
import 'widgets/payment_right_panel.dart';
@RoutePage()
class PaymentPage extends StatelessWidget implements AutoRouteWrapper {
final Order order;
const PaymentPage({super.key, required this.order});
@override
Widget build(BuildContext context) {
return BlocListener<PaymentFormBloc, PaymentFormState>(
listenWhen: (p, c) => p.failureOrPayment != c.failureOrPayment,
listener: (context, state) {
state.failureOrPayment.fold(
() {},
(either) => either.fold(
(f) => AppFlushbar.showOrderFailureToast(context, f),
(data) {},
),
);
},
child: Scaffold(
backgroundColor: AppColor.background,
appBar: AppBar(
backgroundColor: AppColor.white,
elevation: 0,
title: const Text(
'Pembayaran',
style: TextStyle(color: AppColor.primary),
),
leading: IconButton(
onPressed: () => context.router.maybePop(),
icon: Icon(Icons.arrow_back, color: AppColor.primary),
),
),
body: LayoutBuilder(
builder: (context, constraints) {
final isWide = constraints.maxWidth > 800;
return BlocBuilder<PaymentFormBloc, PaymentFormState>(
builder: (context, state) {
return Padding(
padding: const EdgeInsets.all(16),
child: isWide
? Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 3,
child: PaymentLeftPanel(state: state),
),
const SizedBox(width: 24),
Expanded(
flex: 2,
child: PaymentRightPanel(state: state),
),
],
)
: SingleChildScrollView(
child: Column(
children: [
PaymentLeftPanel(state: state),
const SpaceHeight(24),
PaymentRightPanel(state: state),
],
),
),
);
},
);
},
),
),
);
}
@override
Widget wrappedRoute(BuildContext context) => MultiBlocProvider(
providers: [
BlocProvider(
create: (context) =>
getIt<PaymentFormBloc>()..add(PaymentFormEvent.setOrder(order)),
),
BlocProvider(
create: (context) =>
getIt<PaymentMethodLoaderBloc>()
..add(PaymentMethodLoaderEvent.fetched(isRefresh: true)),
),
],
child: this,
);
}

View File

@ -0,0 +1,131 @@
import 'package:flutter/material.dart';
import '../../../../application/payment/payment_form/payment_form_bloc.dart';
import '../../../../common/extension/extension.dart';
import '../../../../common/theme/theme.dart';
import '../../../components/border/dashed_border.dart';
import '../../../components/spaces/space.dart';
class PaymentLeftPanel extends StatelessWidget {
final PaymentFormState state;
const PaymentLeftPanel({super.key, required this.state});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: AppColor.white,
borderRadius: BorderRadius.circular(12),
),
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Detail Order',
style: AppStyle.h5.copyWith(
fontWeight: FontWeight.bold,
color: AppColor.primary,
),
),
const SpaceHeight(16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'No. Pesanan',
style: AppStyle.md.copyWith(fontWeight: FontWeight.w600),
),
Text(
state.order.orderNumber,
style: AppStyle.md.copyWith(fontWeight: FontWeight.bold),
),
],
),
SpaceHeight(8),
Divider(color: AppColor.border),
SpaceHeight(8),
Expanded(
child: state.pendingItems.isEmpty
? const Center(child: Text('Tidak ada item'))
: ListView.separated(
shrinkWrap: true,
itemCount: state.pendingItems.length,
separatorBuilder: (_, __) =>
Divider(color: AppColor.border),
itemBuilder: (context, index) {
final item = state.pendingItems[index];
return ListTile(
contentPadding: EdgeInsets.zero,
title: Text(
item.productName,
style: AppStyle.md.copyWith(
fontWeight: FontWeight.w600,
color: AppColor.primary,
),
),
subtitle: Text(
'Qty: ${item.quantity} | ${item.productVariantName}',
style: AppStyle.sm,
),
trailing: Text(
(item.totalPrice).currencyFormatRpV2,
style: AppStyle.md.copyWith(
fontWeight: FontWeight.bold,
color: AppColor.primary,
),
),
);
},
),
),
Divider(color: AppColor.border),
_buildSummaryRow('Subtotal', state.order.subtotal),
_buildSummaryRow('Pajak', state.order.taxAmount),
_buildSummaryRow('Diskon', state.order.discountAmount),
SpaceHeight(8),
DashedDivider(color: AppColor.border),
SpaceHeight(8),
_buildSummaryRow(
'Total',
state.order.totalAmount,
isTotal: true,
color: AppColor.primary,
),
],
),
);
}
Widget _buildSummaryRow(
String label,
int amount, {
bool isTotal = false,
Color? color,
}) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
label,
style: TextStyle(
fontWeight: isTotal ? FontWeight.bold : FontWeight.normal,
fontSize: isTotal ? 18 : 14,
color: color ?? Colors.black,
),
),
Text(
amount.currencyFormatRpV2,
style: TextStyle(
fontWeight: isTotal ? FontWeight.bold : FontWeight.normal,
fontSize: isTotal ? 18 : 14,
color: color ?? Colors.black,
),
),
],
),
);
}
}

View File

@ -0,0 +1,226 @@
import 'package:flutter/material.dart';
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/extension/extension.dart';
import '../../../../common/theme/theme.dart';
import '../../../components/button/button.dart';
import '../../../components/card/payment_card.dart';
import '../../../components/error/payment_method_error_state_widget.dart';
import '../../../components/field/field.dart';
import '../../../components/loader/loader_with_text.dart';
import '../../../components/spaces/space.dart';
import '../../../components/toast/flushbar.dart';
class PaymentRightPanel extends StatefulWidget {
final PaymentFormState state;
const PaymentRightPanel({super.key, required this.state});
@override
State<PaymentRightPanel> createState() => _PaymentRightPanelState();
}
class _PaymentRightPanelState extends State<PaymentRightPanel> {
TextEditingController totalPriceController = TextEditingController();
int priceValue = 0;
int pasMoney1 = 0;
int pasMoney2 = 0;
int pasMoney3 = 0;
initMoney() {
setState(() {
priceValue = widget.state.order.totalAmount;
pasMoney1 = widget.state.order.totalAmount;
pasMoney2 = pasMoney1 ~/ 50000 * 50000 + 50000;
pasMoney3 = pasMoney1 ~/ 50000 * 50000 + 100000;
totalPriceController.text =
widget.state.order.totalAmount.currencyFormatRpV2;
});
}
@override
void initState() {
super.initState();
initMoney();
}
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: AppColor.white,
borderRadius: BorderRadius.circular(12),
),
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Pembayaran',
style: AppStyle.h5.copyWith(
fontWeight: FontWeight.bold,
color: AppColor.primary,
),
),
Expanded(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SpaceHeight(24),
Text(
'Metode Pembayaran',
style: AppStyle.md.copyWith(fontWeight: FontWeight.w600),
),
SpaceHeight(12),
BlocBuilder<
PaymentMethodLoaderBloc,
PaymentMethodLoaderState
>(
builder: (context, pmState) {
if (pmState.isFetching) {
return Center(child: LoaderWithText());
}
return pmState.failureOption.fold(
() => Wrap(
spacing: 12.0,
runSpacing: 8.0,
children: pmState.paymentMethods.map((item) {
// Set default selected payment method if none selected or if current selection is not in the list
if (widget.state.paymentMethod == null ||
!pmState.paymentMethods.any(
(method) =>
method.id ==
widget.state.paymentMethod?.id,
)) {
context.read<PaymentFormBloc>().add(
PaymentFormEvent.setPaymentMethod(
pmState.paymentMethods.first,
),
);
}
return PaymentCard(
payment: item,
isSelected: widget.state.paymentMethod == item,
onSelected: (_) {
context.read<PaymentFormBloc>().add(
PaymentFormEvent.setPaymentMethod(item),
);
},
);
}).toList(),
),
(f) => PaymentMethodErrorStateWidget(failure: f),
);
},
),
SpaceHeight(24),
if (widget.state.paymentMethod != null &&
widget.state.paymentMethod!.type == 'cash')
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Total Bayar',
style: AppStyle.lg.copyWith(
fontWeight: FontWeight.w600,
),
),
const SpaceHeight(8.0),
AppTextFormField(
label: 'Total Bayar',
showLabel: false,
keyboardType: TextInputType.number,
controller: totalPriceController,
onChanged: (value) {
priceValue = value.toIntegerFromText;
final int newValue = value.toIntegerFromText;
totalPriceController.text =
newValue.currencyFormatRp;
totalPriceController.selection =
TextSelection.fromPosition(
TextPosition(
offset: totalPriceController.text.length,
),
);
},
),
const SpaceHeight(20.0),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
AppElevatedButton.outlined(
width: 150.0,
onPressed: () {
totalPriceController.text = pasMoney1
.toString()
.currencyFormatRpV2;
priceValue = pasMoney1;
},
label: 'UANG PAS',
),
const SpaceWidth(20.0),
AppElevatedButton.outlined(
width: 150.0,
onPressed: () {
totalPriceController.text = pasMoney2
.toString()
.currencyFormatRpV2;
priceValue = pasMoney2;
},
label: pasMoney2.toString().currencyFormatRpV2,
),
const SpaceWidth(20.0),
AppElevatedButton.outlined(
width: 150.0,
onPressed: () {
totalPriceController.text = pasMoney3
.toString()
.currencyFormatRpV2;
priceValue = pasMoney3;
},
label: pasMoney3.toString().currencyFormatRpV2,
),
],
),
),
],
),
],
),
),
),
AppElevatedButton.filled(
onPressed: () {
if (widget.state.paymentMethod == null) {
AppFlushbar.showError(
context,
'Pilih metode pembayaran terlebih dahulu',
);
return;
}
if (widget.state.paymentMethod?.type == "cash" &&
priceValue == 0) {
AppFlushbar.showError(context, 'Total bayar tidak boleh 0');
return;
}
if (!widget.state.isSubmitting) {
context.read<PaymentFormBloc>().add(
PaymentFormEvent.submitted(),
);
}
},
label: 'Bayar',
isLoading: widget.state.isSubmitting,
),
],
),
);
}
}

View File

@ -33,5 +33,8 @@ class AppRouter extends RootStackRouter {
AutoRoute(page: OrderRoute.page), AutoRoute(page: OrderRoute.page),
AutoRoute(page: SuccessOrderRoute.page), AutoRoute(page: SuccessOrderRoute.page),
AutoRoute(page: SuccessAddItemOrderRoute.page), AutoRoute(page: SuccessAddItemOrderRoute.page),
// Payment
AutoRoute(page: PaymentRoute.page),
]; ];
} }

View File

@ -9,7 +9,7 @@
// coverage:ignore-file // coverage:ignore-file
// ignore_for_file: no_leading_underscores_for_library_prefixes // ignore_for_file: no_leading_underscores_for_library_prefixes
import 'package:apskel_pos_flutter_v2/domain/order/order.dart' as _i16; import 'package:apskel_pos_flutter_v2/domain/order/order.dart' as _i17;
import 'package:apskel_pos_flutter_v2/presentation/pages/auth/login/login_page.dart' import 'package:apskel_pos_flutter_v2/presentation/pages/auth/login/login_page.dart'
as _i4; as _i4;
import 'package:apskel_pos_flutter_v2/presentation/pages/checkout/checkout_page.dart' import 'package:apskel_pos_flutter_v2/presentation/pages/checkout/checkout_page.dart'
@ -21,97 +21,99 @@ import 'package:apskel_pos_flutter_v2/presentation/pages/main/pages/customer/cus
import 'package:apskel_pos_flutter_v2/presentation/pages/main/pages/home/home_page.dart' import 'package:apskel_pos_flutter_v2/presentation/pages/main/pages/home/home_page.dart'
as _i3; as _i3;
import 'package:apskel_pos_flutter_v2/presentation/pages/main/pages/report/report_page.dart' import 'package:apskel_pos_flutter_v2/presentation/pages/main/pages/report/report_page.dart'
as _i7;
import 'package:apskel_pos_flutter_v2/presentation/pages/main/pages/setting/setting_page.dart'
as _i8; as _i8;
import 'package:apskel_pos_flutter_v2/presentation/pages/main/pages/setting/setting_page.dart'
as _i9;
import 'package:apskel_pos_flutter_v2/presentation/pages/main/pages/table/table_page.dart' import 'package:apskel_pos_flutter_v2/presentation/pages/main/pages/table/table_page.dart'
as _i13; as _i14;
import 'package:apskel_pos_flutter_v2/presentation/pages/order/order_page.dart' import 'package:apskel_pos_flutter_v2/presentation/pages/order/order_page.dart'
as _i6; as _i6;
import 'package:apskel_pos_flutter_v2/presentation/pages/order/pages/success_add_item_order/success_add_item_order_page.dart' import 'package:apskel_pos_flutter_v2/presentation/pages/order/pages/success_add_item_order/success_add_item_order_page.dart'
as _i10;
import 'package:apskel_pos_flutter_v2/presentation/pages/order/pages/success_order/success_order_page.dart'
as _i11; as _i11;
import 'package:apskel_pos_flutter_v2/presentation/pages/splash/splash_page.dart' import 'package:apskel_pos_flutter_v2/presentation/pages/order/pages/success_order/success_order_page.dart'
as _i9;
import 'package:apskel_pos_flutter_v2/presentation/pages/sync/sync_page.dart'
as _i12; as _i12;
import 'package:auto_route/auto_route.dart' as _i14; import 'package:apskel_pos_flutter_v2/presentation/pages/payment/payment_page.dart'
import 'package:flutter/material.dart' as _i15; as _i7;
import 'package:apskel_pos_flutter_v2/presentation/pages/splash/splash_page.dart'
as _i10;
import 'package:apskel_pos_flutter_v2/presentation/pages/sync/sync_page.dart'
as _i13;
import 'package:auto_route/auto_route.dart' as _i15;
import 'package:flutter/material.dart' as _i16;
/// generated route for /// generated route for
/// [_i1.CheckoutPage] /// [_i1.CheckoutPage]
class CheckoutRoute extends _i14.PageRouteInfo<void> { class CheckoutRoute extends _i15.PageRouteInfo<void> {
const CheckoutRoute({List<_i14.PageRouteInfo>? children}) const CheckoutRoute({List<_i15.PageRouteInfo>? children})
: super(CheckoutRoute.name, initialChildren: children); : super(CheckoutRoute.name, initialChildren: children);
static const String name = 'CheckoutRoute'; static const String name = 'CheckoutRoute';
static _i14.PageInfo page = _i14.PageInfo( static _i15.PageInfo page = _i15.PageInfo(
name, name,
builder: (data) { builder: (data) {
return _i14.WrappedRoute(child: const _i1.CheckoutPage()); return _i15.WrappedRoute(child: const _i1.CheckoutPage());
}, },
); );
} }
/// generated route for /// generated route for
/// [_i2.CustomerPage] /// [_i2.CustomerPage]
class CustomerRoute extends _i14.PageRouteInfo<void> { class CustomerRoute extends _i15.PageRouteInfo<void> {
const CustomerRoute({List<_i14.PageRouteInfo>? children}) const CustomerRoute({List<_i15.PageRouteInfo>? children})
: super(CustomerRoute.name, initialChildren: children); : super(CustomerRoute.name, initialChildren: children);
static const String name = 'CustomerRoute'; static const String name = 'CustomerRoute';
static _i14.PageInfo page = _i14.PageInfo( static _i15.PageInfo page = _i15.PageInfo(
name, name,
builder: (data) { builder: (data) {
return _i14.WrappedRoute(child: const _i2.CustomerPage()); return _i15.WrappedRoute(child: const _i2.CustomerPage());
}, },
); );
} }
/// generated route for /// generated route for
/// [_i3.HomePage] /// [_i3.HomePage]
class HomeRoute extends _i14.PageRouteInfo<void> { class HomeRoute extends _i15.PageRouteInfo<void> {
const HomeRoute({List<_i14.PageRouteInfo>? children}) const HomeRoute({List<_i15.PageRouteInfo>? children})
: super(HomeRoute.name, initialChildren: children); : super(HomeRoute.name, initialChildren: children);
static const String name = 'HomeRoute'; static const String name = 'HomeRoute';
static _i14.PageInfo page = _i14.PageInfo( static _i15.PageInfo page = _i15.PageInfo(
name, name,
builder: (data) { builder: (data) {
return _i14.WrappedRoute(child: const _i3.HomePage()); return _i15.WrappedRoute(child: const _i3.HomePage());
}, },
); );
} }
/// generated route for /// generated route for
/// [_i4.LoginPage] /// [_i4.LoginPage]
class LoginRoute extends _i14.PageRouteInfo<void> { class LoginRoute extends _i15.PageRouteInfo<void> {
const LoginRoute({List<_i14.PageRouteInfo>? children}) const LoginRoute({List<_i15.PageRouteInfo>? children})
: super(LoginRoute.name, initialChildren: children); : super(LoginRoute.name, initialChildren: children);
static const String name = 'LoginRoute'; static const String name = 'LoginRoute';
static _i14.PageInfo page = _i14.PageInfo( static _i15.PageInfo page = _i15.PageInfo(
name, name,
builder: (data) { builder: (data) {
return _i14.WrappedRoute(child: const _i4.LoginPage()); return _i15.WrappedRoute(child: const _i4.LoginPage());
}, },
); );
} }
/// generated route for /// generated route for
/// [_i5.MainPage] /// [_i5.MainPage]
class MainRoute extends _i14.PageRouteInfo<void> { class MainRoute extends _i15.PageRouteInfo<void> {
const MainRoute({List<_i14.PageRouteInfo>? children}) const MainRoute({List<_i15.PageRouteInfo>? children})
: super(MainRoute.name, initialChildren: children); : super(MainRoute.name, initialChildren: children);
static const String name = 'MainRoute'; static const String name = 'MainRoute';
static _i14.PageInfo page = _i14.PageInfo( static _i15.PageInfo page = _i15.PageInfo(
name, name,
builder: (data) { builder: (data) {
return const _i5.MainPage(); return const _i5.MainPage();
@ -121,11 +123,11 @@ class MainRoute extends _i14.PageRouteInfo<void> {
/// generated route for /// generated route for
/// [_i6.OrderPage] /// [_i6.OrderPage]
class OrderRoute extends _i14.PageRouteInfo<OrderRouteArgs> { class OrderRoute extends _i15.PageRouteInfo<OrderRouteArgs> {
OrderRoute({ OrderRoute({
_i15.Key? key, _i16.Key? key,
required String status, required String status,
List<_i14.PageRouteInfo>? children, List<_i15.PageRouteInfo>? children,
}) : super( }) : super(
OrderRoute.name, OrderRoute.name,
args: OrderRouteArgs(key: key, status: status), args: OrderRouteArgs(key: key, status: status),
@ -134,11 +136,11 @@ class OrderRoute extends _i14.PageRouteInfo<OrderRouteArgs> {
static const String name = 'OrderRoute'; static const String name = 'OrderRoute';
static _i14.PageInfo page = _i14.PageInfo( static _i15.PageInfo page = _i15.PageInfo(
name, name,
builder: (data) { builder: (data) {
final args = data.argsAs<OrderRouteArgs>(); final args = data.argsAs<OrderRouteArgs>();
return _i14.WrappedRoute( return _i15.WrappedRoute(
child: _i6.OrderPage(key: args.key, status: args.status), child: _i6.OrderPage(key: args.key, status: args.status),
); );
}, },
@ -148,7 +150,7 @@ class OrderRoute extends _i14.PageRouteInfo<OrderRouteArgs> {
class OrderRouteArgs { class OrderRouteArgs {
const OrderRouteArgs({this.key, required this.status}); const OrderRouteArgs({this.key, required this.status});
final _i15.Key? key; final _i16.Key? key;
final String status; final String status;
@ -159,76 +161,115 @@ class OrderRouteArgs {
} }
/// generated route for /// generated route for
/// [_i7.ReportPage] /// [_i7.PaymentPage]
class ReportRoute extends _i14.PageRouteInfo<void> { class PaymentRoute extends _i15.PageRouteInfo<PaymentRouteArgs> {
const ReportRoute({List<_i14.PageRouteInfo>? children}) PaymentRoute({
_i16.Key? key,
required _i17.Order order,
List<_i15.PageRouteInfo>? children,
}) : super(
PaymentRoute.name,
args: PaymentRouteArgs(key: key, order: order),
initialChildren: children,
);
static const String name = 'PaymentRoute';
static _i15.PageInfo page = _i15.PageInfo(
name,
builder: (data) {
final args = data.argsAs<PaymentRouteArgs>();
return _i15.WrappedRoute(
child: _i7.PaymentPage(key: args.key, order: args.order),
);
},
);
}
class PaymentRouteArgs {
const PaymentRouteArgs({this.key, required this.order});
final _i16.Key? key;
final _i17.Order order;
@override
String toString() {
return 'PaymentRouteArgs{key: $key, order: $order}';
}
}
/// generated route for
/// [_i8.ReportPage]
class ReportRoute extends _i15.PageRouteInfo<void> {
const ReportRoute({List<_i15.PageRouteInfo>? children})
: super(ReportRoute.name, initialChildren: children); : super(ReportRoute.name, initialChildren: children);
static const String name = 'ReportRoute'; static const String name = 'ReportRoute';
static _i14.PageInfo page = _i14.PageInfo( static _i15.PageInfo page = _i15.PageInfo(
name, name,
builder: (data) { builder: (data) {
return const _i7.ReportPage(); return const _i8.ReportPage();
}, },
); );
} }
/// generated route for /// generated route for
/// [_i8.SettingPage] /// [_i9.SettingPage]
class SettingRoute extends _i14.PageRouteInfo<void> { class SettingRoute extends _i15.PageRouteInfo<void> {
const SettingRoute({List<_i14.PageRouteInfo>? children}) const SettingRoute({List<_i15.PageRouteInfo>? children})
: super(SettingRoute.name, initialChildren: children); : super(SettingRoute.name, initialChildren: children);
static const String name = 'SettingRoute'; static const String name = 'SettingRoute';
static _i14.PageInfo page = _i14.PageInfo( static _i15.PageInfo page = _i15.PageInfo(
name, name,
builder: (data) { builder: (data) {
return const _i8.SettingPage(); return const _i9.SettingPage();
}, },
); );
} }
/// generated route for /// generated route for
/// [_i9.SplashPage] /// [_i10.SplashPage]
class SplashRoute extends _i14.PageRouteInfo<void> { class SplashRoute extends _i15.PageRouteInfo<void> {
const SplashRoute({List<_i14.PageRouteInfo>? children}) const SplashRoute({List<_i15.PageRouteInfo>? children})
: super(SplashRoute.name, initialChildren: children); : super(SplashRoute.name, initialChildren: children);
static const String name = 'SplashRoute'; static const String name = 'SplashRoute';
static _i14.PageInfo page = _i14.PageInfo( static _i15.PageInfo page = _i15.PageInfo(
name, name,
builder: (data) { builder: (data) {
return const _i9.SplashPage(); return const _i10.SplashPage();
}, },
); );
} }
/// generated route for /// generated route for
/// [_i10.SuccessAddItemOrderPage] /// [_i11.SuccessAddItemOrderPage]
class SuccessAddItemOrderRoute extends _i14.PageRouteInfo<void> { class SuccessAddItemOrderRoute extends _i15.PageRouteInfo<void> {
const SuccessAddItemOrderRoute({List<_i14.PageRouteInfo>? children}) const SuccessAddItemOrderRoute({List<_i15.PageRouteInfo>? children})
: super(SuccessAddItemOrderRoute.name, initialChildren: children); : super(SuccessAddItemOrderRoute.name, initialChildren: children);
static const String name = 'SuccessAddItemOrderRoute'; static const String name = 'SuccessAddItemOrderRoute';
static _i14.PageInfo page = _i14.PageInfo( static _i15.PageInfo page = _i15.PageInfo(
name, name,
builder: (data) { builder: (data) {
return const _i10.SuccessAddItemOrderPage(); return const _i11.SuccessAddItemOrderPage();
}, },
); );
} }
/// generated route for /// generated route for
/// [_i11.SuccessOrderPage] /// [_i12.SuccessOrderPage]
class SuccessOrderRoute extends _i14.PageRouteInfo<SuccessOrderRouteArgs> { class SuccessOrderRoute extends _i15.PageRouteInfo<SuccessOrderRouteArgs> {
SuccessOrderRoute({ SuccessOrderRoute({
_i15.Key? key, _i16.Key? key,
required _i16.Order order, required _i17.Order order,
List<_i14.PageRouteInfo>? children, List<_i15.PageRouteInfo>? children,
}) : super( }) : super(
SuccessOrderRoute.name, SuccessOrderRoute.name,
args: SuccessOrderRouteArgs(key: key, order: order), args: SuccessOrderRouteArgs(key: key, order: order),
@ -237,12 +278,12 @@ class SuccessOrderRoute extends _i14.PageRouteInfo<SuccessOrderRouteArgs> {
static const String name = 'SuccessOrderRoute'; static const String name = 'SuccessOrderRoute';
static _i14.PageInfo page = _i14.PageInfo( static _i15.PageInfo page = _i15.PageInfo(
name, name,
builder: (data) { builder: (data) {
final args = data.argsAs<SuccessOrderRouteArgs>(); final args = data.argsAs<SuccessOrderRouteArgs>();
return _i14.WrappedRoute( return _i15.WrappedRoute(
child: _i11.SuccessOrderPage(key: args.key, order: args.order), child: _i12.SuccessOrderPage(key: args.key, order: args.order),
); );
}, },
); );
@ -251,9 +292,9 @@ class SuccessOrderRoute extends _i14.PageRouteInfo<SuccessOrderRouteArgs> {
class SuccessOrderRouteArgs { class SuccessOrderRouteArgs {
const SuccessOrderRouteArgs({this.key, required this.order}); const SuccessOrderRouteArgs({this.key, required this.order});
final _i15.Key? key; final _i16.Key? key;
final _i16.Order order; final _i17.Order order;
@override @override
String toString() { String toString() {
@ -262,33 +303,33 @@ class SuccessOrderRouteArgs {
} }
/// generated route for /// generated route for
/// [_i12.SyncPage] /// [_i13.SyncPage]
class SyncRoute extends _i14.PageRouteInfo<void> { class SyncRoute extends _i15.PageRouteInfo<void> {
const SyncRoute({List<_i14.PageRouteInfo>? children}) const SyncRoute({List<_i15.PageRouteInfo>? children})
: super(SyncRoute.name, initialChildren: children); : super(SyncRoute.name, initialChildren: children);
static const String name = 'SyncRoute'; static const String name = 'SyncRoute';
static _i14.PageInfo page = _i14.PageInfo( static _i15.PageInfo page = _i15.PageInfo(
name, name,
builder: (data) { builder: (data) {
return _i14.WrappedRoute(child: const _i12.SyncPage()); return _i15.WrappedRoute(child: const _i13.SyncPage());
}, },
); );
} }
/// generated route for /// generated route for
/// [_i13.TablePage] /// [_i14.TablePage]
class TableRoute extends _i14.PageRouteInfo<void> { class TableRoute extends _i15.PageRouteInfo<void> {
const TableRoute({List<_i14.PageRouteInfo>? children}) const TableRoute({List<_i15.PageRouteInfo>? children})
: super(TableRoute.name, initialChildren: children); : super(TableRoute.name, initialChildren: children);
static const String name = 'TableRoute'; static const String name = 'TableRoute';
static _i14.PageInfo page = _i14.PageInfo( static _i15.PageInfo page = _i15.PageInfo(
name, name,
builder: (data) { builder: (data) {
return _i14.WrappedRoute(child: const _i13.TablePage()); return _i15.WrappedRoute(child: const _i14.TablePage());
}, },
); );
} }