feat: payment method report
This commit is contained in:
parent
ae4f7b06ce
commit
fd254c22fd
47
lib/data/datasources/analytic_remote_datasource.dart
Normal file
47
lib/data/datasources/analytic_remote_datasource.dart
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:enaklo_pos/core/constants/variables.dart';
|
||||||
|
import 'package:enaklo_pos/core/network/dio_client.dart';
|
||||||
|
import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart';
|
||||||
|
import 'package:enaklo_pos/data/models/response/payment_method_analytic_response_model.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
|
class AnalyticRemoteDatasource {
|
||||||
|
final Dio dio = DioClient.instance;
|
||||||
|
|
||||||
|
Future<Either<String, PaymentMethodAnalyticResponseModel>> getPaymentMethod({
|
||||||
|
required DateTime dateFrom,
|
||||||
|
required DateTime dateTo,
|
||||||
|
}) async {
|
||||||
|
final authData = await AuthLocalDataSource().getAuthData();
|
||||||
|
final headers = {
|
||||||
|
'Authorization': 'Bearer ${authData.token}',
|
||||||
|
'Accept': 'application/json',
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
final response = await dio.get(
|
||||||
|
'${Variables.baseUrl}/api/v1/analytics/payment-methods',
|
||||||
|
queryParameters: {
|
||||||
|
'date_from': DateFormat('dd-MM-yyyy').format(dateFrom),
|
||||||
|
'date_to': DateFormat('dd-MM-yyyy').format(dateTo),
|
||||||
|
},
|
||||||
|
options: Options(headers: headers),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
return right(PaymentMethodAnalyticResponseModel.fromMap(response.data));
|
||||||
|
} else {
|
||||||
|
return left(response.data.toString());
|
||||||
|
}
|
||||||
|
} on DioException catch (e) {
|
||||||
|
log('Dio error: ${e.message}');
|
||||||
|
return left(e.response?.data.toString() ?? e.message ?? 'Unknown error');
|
||||||
|
} catch (e) {
|
||||||
|
log('Unexpected error: $e');
|
||||||
|
return left('Unexpected error occurred');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,170 @@
|
|||||||
|
class PaymentMethodAnalyticResponseModel {
|
||||||
|
final bool success;
|
||||||
|
final PaymentMethodAnalyticData data;
|
||||||
|
final dynamic errors;
|
||||||
|
|
||||||
|
PaymentMethodAnalyticResponseModel({
|
||||||
|
required this.success,
|
||||||
|
required this.data,
|
||||||
|
this.errors,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PaymentMethodAnalyticResponseModel.fromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
PaymentMethodAnalyticResponseModel.fromMap(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => toMap();
|
||||||
|
|
||||||
|
factory PaymentMethodAnalyticResponseModel.fromMap(Map<String, dynamic> map) {
|
||||||
|
return PaymentMethodAnalyticResponseModel(
|
||||||
|
success: map['success'],
|
||||||
|
data: PaymentMethodAnalyticData.fromMap(map['data']),
|
||||||
|
errors: map['errors'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
'success': success,
|
||||||
|
'data': data.toMap(),
|
||||||
|
'errors': errors,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PaymentMethodAnalyticData {
|
||||||
|
final String organizationId;
|
||||||
|
final String outletId;
|
||||||
|
final DateTime dateFrom;
|
||||||
|
final DateTime dateTo;
|
||||||
|
final String groupBy;
|
||||||
|
final PaymentSummary summary;
|
||||||
|
final List<PaymentMethodAnalyticItem> data;
|
||||||
|
|
||||||
|
PaymentMethodAnalyticData({
|
||||||
|
required this.organizationId,
|
||||||
|
required this.outletId,
|
||||||
|
required this.dateFrom,
|
||||||
|
required this.dateTo,
|
||||||
|
required this.groupBy,
|
||||||
|
required this.summary,
|
||||||
|
required this.data,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PaymentMethodAnalyticData.fromJson(Map<String, dynamic> json) =>
|
||||||
|
PaymentMethodAnalyticData.fromMap(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => toMap();
|
||||||
|
|
||||||
|
factory PaymentMethodAnalyticData.fromMap(Map<String, dynamic> map) {
|
||||||
|
return PaymentMethodAnalyticData(
|
||||||
|
organizationId: map['organization_id'],
|
||||||
|
outletId: map['outlet_id'],
|
||||||
|
dateFrom: DateTime.parse(map['date_from']),
|
||||||
|
dateTo: DateTime.parse(map['date_to']),
|
||||||
|
groupBy: map['group_by'],
|
||||||
|
summary: PaymentSummary.fromMap(map['summary']),
|
||||||
|
data: List<PaymentMethodAnalyticItem>.from(
|
||||||
|
map['data']?.map((x) => PaymentMethodAnalyticItem.fromMap(x)) ?? [],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
'organization_id': organizationId,
|
||||||
|
'outlet_id': outletId,
|
||||||
|
'date_from': dateFrom.toIso8601String(),
|
||||||
|
'date_to': dateTo.toIso8601String(),
|
||||||
|
'group_by': groupBy,
|
||||||
|
'summary': summary.toMap(),
|
||||||
|
'data': data.map((x) => x.toMap()).toList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PaymentSummary {
|
||||||
|
final int totalAmount;
|
||||||
|
final int totalOrders;
|
||||||
|
final int totalPayments;
|
||||||
|
final double averageOrderValue;
|
||||||
|
|
||||||
|
PaymentSummary({
|
||||||
|
required this.totalAmount,
|
||||||
|
required this.totalOrders,
|
||||||
|
required this.totalPayments,
|
||||||
|
required this.averageOrderValue,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PaymentSummary.fromJson(Map<String, dynamic> json) =>
|
||||||
|
PaymentSummary.fromMap(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => toMap();
|
||||||
|
|
||||||
|
factory PaymentSummary.fromMap(Map<String, dynamic> map) {
|
||||||
|
return PaymentSummary(
|
||||||
|
totalAmount: map['total_amount'],
|
||||||
|
totalOrders: map['total_orders'],
|
||||||
|
totalPayments: map['total_payments'],
|
||||||
|
averageOrderValue: (map['average_order_value'] as num).toDouble(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
'total_amount': totalAmount,
|
||||||
|
'total_orders': totalOrders,
|
||||||
|
'total_payments': totalPayments,
|
||||||
|
'average_order_value': averageOrderValue,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PaymentMethodAnalyticItem {
|
||||||
|
final String paymentMethodId;
|
||||||
|
final String paymentMethodName;
|
||||||
|
final String paymentMethodType;
|
||||||
|
final int totalAmount;
|
||||||
|
final int orderCount;
|
||||||
|
final int paymentCount;
|
||||||
|
final int percentage;
|
||||||
|
|
||||||
|
PaymentMethodAnalyticItem({
|
||||||
|
required this.paymentMethodId,
|
||||||
|
required this.paymentMethodName,
|
||||||
|
required this.paymentMethodType,
|
||||||
|
required this.totalAmount,
|
||||||
|
required this.orderCount,
|
||||||
|
required this.paymentCount,
|
||||||
|
required this.percentage,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PaymentMethodAnalyticItem.fromJson(Map<String, dynamic> json) =>
|
||||||
|
PaymentMethodAnalyticItem.fromMap(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => toMap();
|
||||||
|
|
||||||
|
factory PaymentMethodAnalyticItem.fromMap(Map<String, dynamic> map) {
|
||||||
|
return PaymentMethodAnalyticItem(
|
||||||
|
paymentMethodId: map['payment_method_id'],
|
||||||
|
paymentMethodName: map['payment_method_name'],
|
||||||
|
paymentMethodType: map['payment_method_type'],
|
||||||
|
totalAmount: map['total_amount'],
|
||||||
|
orderCount: map['order_count'],
|
||||||
|
paymentCount: map['payment_count'],
|
||||||
|
percentage: map['percentage'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
'payment_method_id': paymentMethodId,
|
||||||
|
'payment_method_name': paymentMethodName,
|
||||||
|
'payment_method_type': paymentMethodType,
|
||||||
|
'total_amount': totalAmount,
|
||||||
|
'order_count': orderCount,
|
||||||
|
'payment_count': paymentCount,
|
||||||
|
'percentage': percentage,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
import 'package:enaklo_pos/core/constants/theme.dart';
|
import 'package:enaklo_pos/core/constants/theme.dart';
|
||||||
|
import 'package:enaklo_pos/data/datasources/analytic_remote_datasource.dart';
|
||||||
import 'package:enaklo_pos/data/datasources/customer_remote_datasource.dart';
|
import 'package:enaklo_pos/data/datasources/customer_remote_datasource.dart';
|
||||||
import 'package:enaklo_pos/data/datasources/file_remote_datasource.dart';
|
import 'package:enaklo_pos/data/datasources/file_remote_datasource.dart';
|
||||||
import 'package:enaklo_pos/data/datasources/outlet_remote_data_source.dart';
|
import 'package:enaklo_pos/data/datasources/outlet_remote_data_source.dart';
|
||||||
@ -198,7 +199,8 @@ class _MyAppState extends State<MyApp> {
|
|||||||
create: (context) => ItemSalesReportBloc(OrderItemRemoteDatasource()),
|
create: (context) => ItemSalesReportBloc(OrderItemRemoteDatasource()),
|
||||||
),
|
),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (context) => PaymentMethodReportBloc(OrderRemoteDatasource()),
|
create: (context) =>
|
||||||
|
PaymentMethodReportBloc(AnalyticRemoteDatasource()),
|
||||||
),
|
),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (context) => DaySalesBloc(ProductLocalDatasource.instance),
|
create: (context) => DaySalesBloc(ProductLocalDatasource.instance),
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
|
import 'package:enaklo_pos/data/datasources/analytic_remote_datasource.dart';
|
||||||
|
import 'package:enaklo_pos/data/models/response/payment_method_analytic_response_model.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:enaklo_pos/data/datasources/order_remote_datasource.dart';
|
|
||||||
import 'package:enaklo_pos/data/models/response/payment_method_response_model.dart';
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
part 'payment_method_report_event.dart';
|
part 'payment_method_report_event.dart';
|
||||||
@ -9,16 +9,23 @@ part 'payment_method_report_bloc.freezed.dart';
|
|||||||
|
|
||||||
class PaymentMethodReportBloc
|
class PaymentMethodReportBloc
|
||||||
extends Bloc<PaymentMethodReportEvent, PaymentMethodReportState> {
|
extends Bloc<PaymentMethodReportEvent, PaymentMethodReportState> {
|
||||||
final OrderRemoteDatasource datasource;
|
final AnalyticRemoteDatasource datasource;
|
||||||
PaymentMethodReportBloc(this.datasource) : super(const _Initial()) {
|
PaymentMethodReportBloc(this.datasource) : super(const _Initial()) {
|
||||||
on<_GetPaymentMethodReport>((event, emit) async {
|
on<_GetPaymentMethodReport>((event, emit) async {
|
||||||
emit(const _Loading());
|
emit(const _Loading());
|
||||||
final result = await datasource.getPaymentMethodByRangeDate(
|
final result = await datasource.getPaymentMethod(
|
||||||
event.startDate,
|
dateFrom: event.startDate,
|
||||||
event.endDate,
|
dateTo: event.endDate,
|
||||||
);
|
);
|
||||||
|
|
||||||
result.fold((l) => emit(_Error(l)), (r) => emit(_Loaded(r.data!)));
|
result.fold(
|
||||||
|
(l) => emit(_Error(l)),
|
||||||
|
(r) => emit(
|
||||||
|
_Loaded(
|
||||||
|
r.data,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -16,22 +16,24 @@ final _privateConstructorUsedError = UnsupportedError(
|
|||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$PaymentMethodReportEvent {
|
mixin _$PaymentMethodReportEvent {
|
||||||
String get startDate => throw _privateConstructorUsedError;
|
DateTime get startDate => throw _privateConstructorUsedError;
|
||||||
String get endDate => throw _privateConstructorUsedError;
|
DateTime get endDate => throw _privateConstructorUsedError;
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function(String startDate, String endDate)
|
required TResult Function(DateTime startDate, DateTime endDate)
|
||||||
getPaymentMethodReport,
|
getPaymentMethodReport,
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
TResult? Function(String startDate, String endDate)? getPaymentMethodReport,
|
TResult? Function(DateTime startDate, DateTime endDate)?
|
||||||
|
getPaymentMethodReport,
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function(String startDate, String endDate)? getPaymentMethodReport,
|
TResult Function(DateTime startDate, DateTime endDate)?
|
||||||
|
getPaymentMethodReport,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@ -66,7 +68,7 @@ abstract class $PaymentMethodReportEventCopyWith<$Res> {
|
|||||||
$Res Function(PaymentMethodReportEvent) then) =
|
$Res Function(PaymentMethodReportEvent) then) =
|
||||||
_$PaymentMethodReportEventCopyWithImpl<$Res, PaymentMethodReportEvent>;
|
_$PaymentMethodReportEventCopyWithImpl<$Res, PaymentMethodReportEvent>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({String startDate, String endDate});
|
$Res call({DateTime startDate, DateTime endDate});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -92,11 +94,11 @@ class _$PaymentMethodReportEventCopyWithImpl<$Res,
|
|||||||
startDate: null == startDate
|
startDate: null == startDate
|
||||||
? _value.startDate
|
? _value.startDate
|
||||||
: startDate // ignore: cast_nullable_to_non_nullable
|
: startDate // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as DateTime,
|
||||||
endDate: null == endDate
|
endDate: null == endDate
|
||||||
? _value.endDate
|
? _value.endDate
|
||||||
: endDate // ignore: cast_nullable_to_non_nullable
|
: endDate // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as DateTime,
|
||||||
) as $Val);
|
) as $Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,7 +112,7 @@ abstract class _$$GetPaymentMethodReportImplCopyWith<$Res>
|
|||||||
__$$GetPaymentMethodReportImplCopyWithImpl<$Res>;
|
__$$GetPaymentMethodReportImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({String startDate, String endDate});
|
$Res call({DateTime startDate, DateTime endDate});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -135,11 +137,11 @@ class __$$GetPaymentMethodReportImplCopyWithImpl<$Res>
|
|||||||
startDate: null == startDate
|
startDate: null == startDate
|
||||||
? _value.startDate
|
? _value.startDate
|
||||||
: startDate // ignore: cast_nullable_to_non_nullable
|
: startDate // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as DateTime,
|
||||||
endDate: null == endDate
|
endDate: null == endDate
|
||||||
? _value.endDate
|
? _value.endDate
|
||||||
: endDate // ignore: cast_nullable_to_non_nullable
|
: endDate // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as DateTime,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,9 +153,9 @@ class _$GetPaymentMethodReportImpl implements _GetPaymentMethodReport {
|
|||||||
{required this.startDate, required this.endDate});
|
{required this.startDate, required this.endDate});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final String startDate;
|
final DateTime startDate;
|
||||||
@override
|
@override
|
||||||
final String endDate;
|
final DateTime endDate;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
@ -185,7 +187,7 @@ class _$GetPaymentMethodReportImpl implements _GetPaymentMethodReport {
|
|||||||
@override
|
@override
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function(String startDate, String endDate)
|
required TResult Function(DateTime startDate, DateTime endDate)
|
||||||
getPaymentMethodReport,
|
getPaymentMethodReport,
|
||||||
}) {
|
}) {
|
||||||
return getPaymentMethodReport(startDate, endDate);
|
return getPaymentMethodReport(startDate, endDate);
|
||||||
@ -194,7 +196,8 @@ class _$GetPaymentMethodReportImpl implements _GetPaymentMethodReport {
|
|||||||
@override
|
@override
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
TResult? Function(String startDate, String endDate)? getPaymentMethodReport,
|
TResult? Function(DateTime startDate, DateTime endDate)?
|
||||||
|
getPaymentMethodReport,
|
||||||
}) {
|
}) {
|
||||||
return getPaymentMethodReport?.call(startDate, endDate);
|
return getPaymentMethodReport?.call(startDate, endDate);
|
||||||
}
|
}
|
||||||
@ -202,7 +205,8 @@ class _$GetPaymentMethodReportImpl implements _GetPaymentMethodReport {
|
|||||||
@override
|
@override
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function(String startDate, String endDate)? getPaymentMethodReport,
|
TResult Function(DateTime startDate, DateTime endDate)?
|
||||||
|
getPaymentMethodReport,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
if (getPaymentMethodReport != null) {
|
if (getPaymentMethodReport != null) {
|
||||||
@ -243,13 +247,13 @@ class _$GetPaymentMethodReportImpl implements _GetPaymentMethodReport {
|
|||||||
|
|
||||||
abstract class _GetPaymentMethodReport implements PaymentMethodReportEvent {
|
abstract class _GetPaymentMethodReport implements PaymentMethodReportEvent {
|
||||||
const factory _GetPaymentMethodReport(
|
const factory _GetPaymentMethodReport(
|
||||||
{required final String startDate,
|
{required final DateTime startDate,
|
||||||
required final String endDate}) = _$GetPaymentMethodReportImpl;
|
required final DateTime endDate}) = _$GetPaymentMethodReportImpl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get startDate;
|
DateTime get startDate;
|
||||||
@override
|
@override
|
||||||
String get endDate;
|
DateTime get endDate;
|
||||||
|
|
||||||
/// Create a copy of PaymentMethodReportEvent
|
/// Create a copy of PaymentMethodReportEvent
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@ -265,7 +269,7 @@ mixin _$PaymentMethodReportState {
|
|||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function() initial,
|
required TResult Function() initial,
|
||||||
required TResult Function() loading,
|
required TResult Function() loading,
|
||||||
required TResult Function(PaymentMethodData data) loaded,
|
required TResult Function(PaymentMethodAnalyticData data) loaded,
|
||||||
required TResult Function(String message) error,
|
required TResult Function(String message) error,
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@ -273,7 +277,7 @@ mixin _$PaymentMethodReportState {
|
|||||||
TResult? whenOrNull<TResult extends Object?>({
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
TResult? Function()? initial,
|
TResult? Function()? initial,
|
||||||
TResult? Function()? loading,
|
TResult? Function()? loading,
|
||||||
TResult? Function(PaymentMethodData data)? loaded,
|
TResult? Function(PaymentMethodAnalyticData data)? loaded,
|
||||||
TResult? Function(String message)? error,
|
TResult? Function(String message)? error,
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@ -281,7 +285,7 @@ mixin _$PaymentMethodReportState {
|
|||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function()? initial,
|
TResult Function()? initial,
|
||||||
TResult Function()? loading,
|
TResult Function()? loading,
|
||||||
TResult Function(PaymentMethodData data)? loaded,
|
TResult Function(PaymentMethodAnalyticData data)? loaded,
|
||||||
TResult Function(String message)? error,
|
TResult Function(String message)? error,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) =>
|
}) =>
|
||||||
@ -378,7 +382,7 @@ class _$InitialImpl implements _Initial {
|
|||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function() initial,
|
required TResult Function() initial,
|
||||||
required TResult Function() loading,
|
required TResult Function() loading,
|
||||||
required TResult Function(PaymentMethodData data) loaded,
|
required TResult Function(PaymentMethodAnalyticData data) loaded,
|
||||||
required TResult Function(String message) error,
|
required TResult Function(String message) error,
|
||||||
}) {
|
}) {
|
||||||
return initial();
|
return initial();
|
||||||
@ -389,7 +393,7 @@ class _$InitialImpl implements _Initial {
|
|||||||
TResult? whenOrNull<TResult extends Object?>({
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
TResult? Function()? initial,
|
TResult? Function()? initial,
|
||||||
TResult? Function()? loading,
|
TResult? Function()? loading,
|
||||||
TResult? Function(PaymentMethodData data)? loaded,
|
TResult? Function(PaymentMethodAnalyticData data)? loaded,
|
||||||
TResult? Function(String message)? error,
|
TResult? Function(String message)? error,
|
||||||
}) {
|
}) {
|
||||||
return initial?.call();
|
return initial?.call();
|
||||||
@ -400,7 +404,7 @@ class _$InitialImpl implements _Initial {
|
|||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function()? initial,
|
TResult Function()? initial,
|
||||||
TResult Function()? loading,
|
TResult Function()? loading,
|
||||||
TResult Function(PaymentMethodData data)? loaded,
|
TResult Function(PaymentMethodAnalyticData data)? loaded,
|
||||||
TResult Function(String message)? error,
|
TResult Function(String message)? error,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
@ -495,7 +499,7 @@ class _$LoadingImpl implements _Loading {
|
|||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function() initial,
|
required TResult Function() initial,
|
||||||
required TResult Function() loading,
|
required TResult Function() loading,
|
||||||
required TResult Function(PaymentMethodData data) loaded,
|
required TResult Function(PaymentMethodAnalyticData data) loaded,
|
||||||
required TResult Function(String message) error,
|
required TResult Function(String message) error,
|
||||||
}) {
|
}) {
|
||||||
return loading();
|
return loading();
|
||||||
@ -506,7 +510,7 @@ class _$LoadingImpl implements _Loading {
|
|||||||
TResult? whenOrNull<TResult extends Object?>({
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
TResult? Function()? initial,
|
TResult? Function()? initial,
|
||||||
TResult? Function()? loading,
|
TResult? Function()? loading,
|
||||||
TResult? Function(PaymentMethodData data)? loaded,
|
TResult? Function(PaymentMethodAnalyticData data)? loaded,
|
||||||
TResult? Function(String message)? error,
|
TResult? Function(String message)? error,
|
||||||
}) {
|
}) {
|
||||||
return loading?.call();
|
return loading?.call();
|
||||||
@ -517,7 +521,7 @@ class _$LoadingImpl implements _Loading {
|
|||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function()? initial,
|
TResult Function()? initial,
|
||||||
TResult Function()? loading,
|
TResult Function()? loading,
|
||||||
TResult Function(PaymentMethodData data)? loaded,
|
TResult Function(PaymentMethodAnalyticData data)? loaded,
|
||||||
TResult Function(String message)? error,
|
TResult Function(String message)? error,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
@ -575,7 +579,7 @@ abstract class _$$LoadedImplCopyWith<$Res> {
|
|||||||
_$LoadedImpl value, $Res Function(_$LoadedImpl) then) =
|
_$LoadedImpl value, $Res Function(_$LoadedImpl) then) =
|
||||||
__$$LoadedImplCopyWithImpl<$Res>;
|
__$$LoadedImplCopyWithImpl<$Res>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({PaymentMethodData data});
|
$Res call({PaymentMethodAnalyticData data});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -597,7 +601,7 @@ class __$$LoadedImplCopyWithImpl<$Res>
|
|||||||
null == data
|
null == data
|
||||||
? _value.data
|
? _value.data
|
||||||
: data // ignore: cast_nullable_to_non_nullable
|
: data // ignore: cast_nullable_to_non_nullable
|
||||||
as PaymentMethodData,
|
as PaymentMethodAnalyticData,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -608,7 +612,7 @@ class _$LoadedImpl implements _Loaded {
|
|||||||
const _$LoadedImpl(this.data);
|
const _$LoadedImpl(this.data);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final PaymentMethodData data;
|
final PaymentMethodAnalyticData data;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
@ -639,7 +643,7 @@ class _$LoadedImpl implements _Loaded {
|
|||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function() initial,
|
required TResult Function() initial,
|
||||||
required TResult Function() loading,
|
required TResult Function() loading,
|
||||||
required TResult Function(PaymentMethodData data) loaded,
|
required TResult Function(PaymentMethodAnalyticData data) loaded,
|
||||||
required TResult Function(String message) error,
|
required TResult Function(String message) error,
|
||||||
}) {
|
}) {
|
||||||
return loaded(data);
|
return loaded(data);
|
||||||
@ -650,7 +654,7 @@ class _$LoadedImpl implements _Loaded {
|
|||||||
TResult? whenOrNull<TResult extends Object?>({
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
TResult? Function()? initial,
|
TResult? Function()? initial,
|
||||||
TResult? Function()? loading,
|
TResult? Function()? loading,
|
||||||
TResult? Function(PaymentMethodData data)? loaded,
|
TResult? Function(PaymentMethodAnalyticData data)? loaded,
|
||||||
TResult? Function(String message)? error,
|
TResult? Function(String message)? error,
|
||||||
}) {
|
}) {
|
||||||
return loaded?.call(data);
|
return loaded?.call(data);
|
||||||
@ -661,7 +665,7 @@ class _$LoadedImpl implements _Loaded {
|
|||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function()? initial,
|
TResult Function()? initial,
|
||||||
TResult Function()? loading,
|
TResult Function()? loading,
|
||||||
TResult Function(PaymentMethodData data)? loaded,
|
TResult Function(PaymentMethodAnalyticData data)? loaded,
|
||||||
TResult Function(String message)? error,
|
TResult Function(String message)? error,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
@ -710,9 +714,9 @@ class _$LoadedImpl implements _Loaded {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class _Loaded implements PaymentMethodReportState {
|
abstract class _Loaded implements PaymentMethodReportState {
|
||||||
const factory _Loaded(final PaymentMethodData data) = _$LoadedImpl;
|
const factory _Loaded(final PaymentMethodAnalyticData data) = _$LoadedImpl;
|
||||||
|
|
||||||
PaymentMethodData get data;
|
PaymentMethodAnalyticData get data;
|
||||||
|
|
||||||
/// Create a copy of PaymentMethodReportState
|
/// Create a copy of PaymentMethodReportState
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@ -791,7 +795,7 @@ class _$ErrorImpl implements _Error {
|
|||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function() initial,
|
required TResult Function() initial,
|
||||||
required TResult Function() loading,
|
required TResult Function() loading,
|
||||||
required TResult Function(PaymentMethodData data) loaded,
|
required TResult Function(PaymentMethodAnalyticData data) loaded,
|
||||||
required TResult Function(String message) error,
|
required TResult Function(String message) error,
|
||||||
}) {
|
}) {
|
||||||
return error(message);
|
return error(message);
|
||||||
@ -802,7 +806,7 @@ class _$ErrorImpl implements _Error {
|
|||||||
TResult? whenOrNull<TResult extends Object?>({
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
TResult? Function()? initial,
|
TResult? Function()? initial,
|
||||||
TResult? Function()? loading,
|
TResult? Function()? loading,
|
||||||
TResult? Function(PaymentMethodData data)? loaded,
|
TResult? Function(PaymentMethodAnalyticData data)? loaded,
|
||||||
TResult? Function(String message)? error,
|
TResult? Function(String message)? error,
|
||||||
}) {
|
}) {
|
||||||
return error?.call(message);
|
return error?.call(message);
|
||||||
@ -813,7 +817,7 @@ class _$ErrorImpl implements _Error {
|
|||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function()? initial,
|
TResult Function()? initial,
|
||||||
TResult Function()? loading,
|
TResult Function()? loading,
|
||||||
TResult Function(PaymentMethodData data)? loaded,
|
TResult Function(PaymentMethodAnalyticData data)? loaded,
|
||||||
TResult Function(String message)? error,
|
TResult Function(String message)? error,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
|
|||||||
@ -3,7 +3,7 @@ part of 'payment_method_report_bloc.dart';
|
|||||||
@freezed
|
@freezed
|
||||||
class PaymentMethodReportEvent with _$PaymentMethodReportEvent {
|
class PaymentMethodReportEvent with _$PaymentMethodReportEvent {
|
||||||
const factory PaymentMethodReportEvent.getPaymentMethodReport({
|
const factory PaymentMethodReportEvent.getPaymentMethodReport({
|
||||||
required String startDate,
|
required DateTime startDate,
|
||||||
required String endDate,
|
required DateTime endDate,
|
||||||
}) = _GetPaymentMethodReport;
|
}) = _GetPaymentMethodReport;
|
||||||
}
|
}
|
||||||
@ -4,6 +4,7 @@ part of 'payment_method_report_bloc.dart';
|
|||||||
class PaymentMethodReportState with _$PaymentMethodReportState {
|
class PaymentMethodReportState with _$PaymentMethodReportState {
|
||||||
const factory PaymentMethodReportState.initial() = _Initial;
|
const factory PaymentMethodReportState.initial() = _Initial;
|
||||||
const factory PaymentMethodReportState.loading() = _Loading;
|
const factory PaymentMethodReportState.loading() = _Loading;
|
||||||
const factory PaymentMethodReportState.loaded(PaymentMethodData data) = _Loaded;
|
const factory PaymentMethodReportState.loaded(
|
||||||
|
PaymentMethodAnalyticData data) = _Loaded;
|
||||||
const factory PaymentMethodReportState.error(String message) = _Error;
|
const factory PaymentMethodReportState.error(String message) = _Error;
|
||||||
}
|
}
|
||||||
@ -202,12 +202,9 @@ class _ReportPageState extends State<ReportPage> {
|
|||||||
context.read<PaymentMethodReportBloc>().add(
|
context.read<PaymentMethodReportBloc>().add(
|
||||||
PaymentMethodReportEvent
|
PaymentMethodReportEvent
|
||||||
.getPaymentMethodReport(
|
.getPaymentMethodReport(
|
||||||
startDate:
|
startDate: fromDate,
|
||||||
DateFormatter.formatDateTime(
|
endDate: toDate,
|
||||||
fromDate),
|
),
|
||||||
endDate:
|
|
||||||
DateFormatter.formatDateTime(
|
|
||||||
toDate)),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
isActive: selectedMenu == 4,
|
isActive: selectedMenu == 4,
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
|
import 'package:enaklo_pos/core/extensions/int_ext.dart';
|
||||||
|
import 'package:enaklo_pos/data/models/response/payment_method_analytic_response_model.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:enaklo_pos/core/constants/colors.dart';
|
import 'package:enaklo_pos/core/constants/colors.dart';
|
||||||
import 'package:enaklo_pos/core/extensions/string_ext.dart';
|
|
||||||
import 'package:enaklo_pos/data/models/response/payment_method_response_model.dart';
|
|
||||||
|
|
||||||
import '../../../core/components/spaces.dart';
|
import '../../../core/components/spaces.dart';
|
||||||
|
|
||||||
class PaymentMethodReportWidget extends StatelessWidget {
|
class PaymentMethodReportWidget extends StatelessWidget {
|
||||||
final PaymentMethodData paymentMethodData;
|
final PaymentMethodAnalyticData paymentMethodData;
|
||||||
final String title;
|
final String title;
|
||||||
final String searchDateFormatted;
|
final String searchDateFormatted;
|
||||||
final List<Widget> headerWidgets;
|
final List<Widget> headerWidgets;
|
||||||
@ -23,127 +23,343 @@ class PaymentMethodReportWidget extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: AppColors.white,
|
backgroundColor: AppColors.white,
|
||||||
body: Column(
|
body: Container(
|
||||||
children: [
|
padding: const EdgeInsets.all(20),
|
||||||
// HEADER
|
decoration: BoxDecoration(
|
||||||
Container(
|
color: Colors.white,
|
||||||
padding: const EdgeInsets.all(24.0),
|
border: Border(
|
||||||
decoration: const BoxDecoration(
|
left: BorderSide(
|
||||||
color: AppColors.white,
|
color: Colors.grey.shade200,
|
||||||
border: Border(
|
width: 1,
|
||||||
bottom: BorderSide(
|
|
||||||
color: AppColors.stroke,
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
child: Row(
|
),
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
),
|
||||||
children: [
|
child: SingleChildScrollView(
|
||||||
Column(
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// Header Section
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.grey.shade800,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.blue.shade50,
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
border: Border.all(
|
||||||
|
color: Colors.blue.shade200,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
searchDateFormatted,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.blue.shade700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SpaceHeight(24), // Summary Cards
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.green.shade50,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(
|
||||||
|
color: Colors.green.shade200,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Pendapatan Total',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.green.shade700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
paymentMethodData
|
||||||
|
.summary.totalAmount.currencyFormatRpV2,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.green.shade800,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.orange.shade50,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(
|
||||||
|
color: Colors.orange.shade200,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Jumlah Pesanan',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.orange.shade700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
paymentMethodData.summary.totalOrders.toString(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.orange.shade800,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SpaceHeight(16),
|
||||||
|
// Average Order Value Card
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.purple.shade50,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(
|
||||||
|
color: Colors.purple.shade200,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
title,
|
'Nilai Pesanan Rata-rata',
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 24,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.purple.shade700,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SpaceHeight(8.0),
|
const SizedBox(height: 8),
|
||||||
Text(
|
Text(
|
||||||
searchDateFormatted,
|
paymentMethodData.summary.averageOrderValue
|
||||||
style: const TextStyle(
|
.round()
|
||||||
fontSize: 16,
|
.currencyFormatRpV2,
|
||||||
color: AppColors.grey,
|
style: TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.purple.shade800,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Row(
|
),
|
||||||
|
const SpaceHeight(24),
|
||||||
|
|
||||||
|
// Payment Methods Section
|
||||||
|
Text(
|
||||||
|
'Rincian Metode Pembayaran',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.grey.shade800,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SpaceHeight(16),
|
||||||
|
|
||||||
|
// Payment Method Item
|
||||||
|
...List.generate(paymentMethodData.data.length, (index) {
|
||||||
|
final item = paymentMethodData.data[index];
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 16),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey.shade50,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(
|
||||||
|
color: Colors.grey.shade200,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
// Payment Method Icon
|
||||||
|
Container(
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.primary,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColors.primary,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
Icons.money,
|
||||||
|
color: AppColors.white,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
|
||||||
|
// Payment Method Details
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
item.paymentMethodName,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.grey.shade800,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"${item.percentage}%",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: AppColors.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
item.totalAmount.currencyFormatRpV2,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.grey.shade600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'${item.orderCount} Pesanan',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.grey.shade600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
|
||||||
|
// Progress Bar
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 6,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey.shade200,
|
||||||
|
borderRadius: BorderRadius.circular(3),
|
||||||
|
),
|
||||||
|
child: FractionallySizedBox(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
widthFactor:
|
||||||
|
(item.percentage / 100), // 100%
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.primary,
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(3),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.blue.shade50,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(
|
||||||
|
color: Colors.blue.shade200,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Icon(
|
||||||
padding: const EdgeInsets.symmetric(
|
Icons.info_outline,
|
||||||
horizontal: 16.0,
|
color: Colors.blue.shade600,
|
||||||
vertical: 8.0,
|
size: 16,
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
const SizedBox(width: 8),
|
||||||
color: AppColors.primary,
|
Expanded(
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
|
||||||
),
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'Total: ${paymentMethodData.total?.currencyFormatRpV2 ?? 'Rp 0'}',
|
'All payments processed successfully with 100% cash transactions',
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
color: AppColors.white,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
color: Colors.blue.shade700,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// CONTENT
|
|
||||||
Expanded(
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
// TABLE HEADER
|
|
||||||
Row(
|
|
||||||
children: headerWidgets,
|
|
||||||
),
|
|
||||||
|
|
||||||
// TABLE BODY
|
|
||||||
...paymentMethodData.paymentMethods?.map((item) {
|
|
||||||
return Container(
|
|
||||||
decoration: const BoxDecoration(
|
|
||||||
border: Border(
|
|
||||||
bottom: BorderSide(
|
|
||||||
color: AppColors.stroke,
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
_getBodyItemWidget(
|
|
||||||
item.paymentMethod ?? '-',
|
|
||||||
180,
|
|
||||||
),
|
|
||||||
_getBodyItemWidget(
|
|
||||||
item.totalAmount?.currencyFormatRpV2 ?? 'Rp 0',
|
|
||||||
180,
|
|
||||||
),
|
|
||||||
_getBodyItemWidget(
|
|
||||||
item.transactionCount?.toString() ?? '0',
|
|
||||||
180,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList() ??
|
|
||||||
[],
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _getBodyItemWidget(String label, double width) {
|
|
||||||
return Container(
|
|
||||||
width: width,
|
|
||||||
height: 56,
|
|
||||||
alignment: Alignment.centerLeft,
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
|
||||||
child: Text(
|
|
||||||
label,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user