feat: report page
This commit is contained in:
@@ -34,264 +34,314 @@ class _ReportPageState extends State<ReportPage> {
|
||||
DateTime fromDate = DateTime.now().subtract(const Duration(days: 30));
|
||||
DateTime toDate = DateTime.now();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
context.read<TransactionReportBloc>().add(
|
||||
TransactionReportEvent.getReport(
|
||||
startDate: DateFormatter.formatDateTime(fromDate),
|
||||
endDate: DateFormatter.formatDateTime(toDate)),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String searchDateFormatted =
|
||||
'${fromDate.toFormattedDate2()} to ${toDate.toFormattedDate2()}';
|
||||
return Scaffold(
|
||||
body: Row(
|
||||
backgroundColor: AppColors.background,
|
||||
body: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// LEFT CONTENT
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const ReportTitle(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Flexible(
|
||||
child: CustomDatePicker(
|
||||
prefix: const Text('From: '),
|
||||
initialDate: fromDate,
|
||||
onDateSelected: (selectedDate) {
|
||||
fromDate = selectedDate;
|
||||
ReportTitle(
|
||||
actionWidget: [
|
||||
SizedBox(
|
||||
width: 300,
|
||||
child: CustomDatePicker(
|
||||
prefix: const Text('From: '),
|
||||
initialDate: fromDate,
|
||||
onDateSelected: (selectedDate) {
|
||||
fromDate = selectedDate;
|
||||
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
),
|
||||
const SpaceWidth(24.0),
|
||||
Flexible(
|
||||
child: CustomDatePicker(
|
||||
prefix: const Text('To: '),
|
||||
initialDate: toDate,
|
||||
onDateSelected: (selectedDate) {
|
||||
toDate = selectedDate;
|
||||
setState(() {});
|
||||
// context.read<TransactionReportBloc>().add(
|
||||
// TransactionReportEvent.getReport(
|
||||
// startDate:
|
||||
// DateFormatter.formatDateTime(
|
||||
// fromDate),
|
||||
// endDate: DateFormatter.formatDateTime(
|
||||
// toDate)),
|
||||
// );
|
||||
// context.read<ItemSalesReportBloc>().add(
|
||||
// ItemSalesReportEvent.getItemSales(
|
||||
// startDate:
|
||||
// DateFormatter.formatDateTime(
|
||||
// fromDate),
|
||||
// endDate: DateFormatter.formatDateTime(
|
||||
// toDate)),
|
||||
// );
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(15.0),
|
||||
child: Wrap(
|
||||
children: [
|
||||
ReportMenu(
|
||||
label: 'Transaction Report',
|
||||
onPressed: () {
|
||||
selectedMenu = 0;
|
||||
title = 'Transaction Report';
|
||||
setState(() {});
|
||||
//enddate is 1 month before the current date
|
||||
context.read<TransactionReportBloc>().add(
|
||||
TransactionReportEvent.getReport(
|
||||
startDate: DateFormatter.formatDateTime(
|
||||
fromDate),
|
||||
endDate: DateFormatter.formatDateTime(
|
||||
toDate)),
|
||||
);
|
||||
},
|
||||
isActive: selectedMenu == 0,
|
||||
),
|
||||
ReportMenu(
|
||||
label: 'Item Sales Report',
|
||||
onPressed: () {
|
||||
selectedMenu = 1;
|
||||
title = 'Item Sales Report';
|
||||
setState(() {});
|
||||
context.read<ItemSalesReportBloc>().add(
|
||||
ItemSalesReportEvent.getItemSales(
|
||||
startDate: DateFormatter.formatDateTime(
|
||||
fromDate),
|
||||
endDate: DateFormatter.formatDateTime(
|
||||
toDate)),
|
||||
);
|
||||
},
|
||||
isActive: selectedMenu == 1,
|
||||
),
|
||||
ReportMenu(
|
||||
label: 'Product Sales Chart',
|
||||
onPressed: () {
|
||||
selectedMenu = 2;
|
||||
title = 'Product Sales Chart';
|
||||
setState(() {});
|
||||
context.read<ProductSalesBloc>().add(
|
||||
ProductSalesEvent.getProductSales(
|
||||
DateFormatter.formatDateTime(fromDate),
|
||||
DateFormatter.formatDateTime(toDate)),
|
||||
);
|
||||
},
|
||||
isActive: selectedMenu == 2,
|
||||
),
|
||||
ReportMenu(
|
||||
label: 'Summary Sales Report',
|
||||
onPressed: () {
|
||||
selectedMenu = 3;
|
||||
title = 'Summary Sales Report';
|
||||
setState(() {});
|
||||
context.read<SummaryBloc>().add(
|
||||
SummaryEvent.getSummary(
|
||||
DateFormatter.formatDateTime(fromDate),
|
||||
DateFormatter.formatDateTime(toDate)),
|
||||
);
|
||||
|
||||
log("Date ${DateFormatter.formatDateTime(fromDate)}");
|
||||
},
|
||||
isActive: selectedMenu == 3,
|
||||
),
|
||||
ReportMenu(
|
||||
label: 'Payment Method Report',
|
||||
onPressed: () {
|
||||
selectedMenu = 4;
|
||||
title = 'Payment Method Report';
|
||||
setState(() {});
|
||||
context.read<PaymentMethodReportBloc>().add(
|
||||
PaymentMethodReportEvent.getPaymentMethodReport(
|
||||
startDate: DateFormatter.formatDateTime(fromDate),
|
||||
endDate: DateFormatter.formatDateTime(toDate)),
|
||||
);
|
||||
},
|
||||
isActive: selectedMenu == 4,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
),
|
||||
const SpaceWidth(24.0),
|
||||
SizedBox(
|
||||
width: 300,
|
||||
child: CustomDatePicker(
|
||||
prefix: const Text('To: '),
|
||||
initialDate: toDate,
|
||||
onDateSelected: (selectedDate) {
|
||||
toDate = selectedDate;
|
||||
setState(() {});
|
||||
// context.read<TransactionReportBloc>().add(
|
||||
// TransactionReportEvent.getReport(
|
||||
// startDate:
|
||||
// DateFormatter.formatDateTime(
|
||||
// fromDate),
|
||||
// endDate: DateFormatter.formatDateTime(
|
||||
// toDate)),
|
||||
// );
|
||||
// context.read<ItemSalesReportBloc>().add(
|
||||
// ItemSalesReportEvent.getItemSales(
|
||||
// startDate:
|
||||
// DateFormatter.formatDateTime(
|
||||
// fromDate),
|
||||
// endDate: DateFormatter.formatDateTime(
|
||||
// toDate)),
|
||||
// );
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
// LEFT CONTENT
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Material(
|
||||
color: AppColors.white,
|
||||
child: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ReportMenu(
|
||||
label: 'Laporan Transaksi',
|
||||
subtitle:
|
||||
'Menampilkan riwayat lengkap semua transaksi yang telah dilakukan.',
|
||||
icon: Icons.receipt_long_outlined,
|
||||
onPressed: () {
|
||||
selectedMenu = 0;
|
||||
title = 'Laporan Transaksi';
|
||||
setState(() {});
|
||||
//enddate is 1 month before the current date
|
||||
context.read<TransactionReportBloc>().add(
|
||||
TransactionReportEvent.getReport(
|
||||
startDate:
|
||||
DateFormatter.formatDateTime(
|
||||
fromDate),
|
||||
endDate: DateFormatter.formatDateTime(
|
||||
toDate)),
|
||||
);
|
||||
},
|
||||
isActive: selectedMenu == 0,
|
||||
),
|
||||
ReportMenu(
|
||||
label: 'Laporan Penjualan Item',
|
||||
subtitle:
|
||||
'Laporan penjualan berdasarkan masing-masing item atau produk.',
|
||||
icon: Icons.inventory_2_outlined,
|
||||
onPressed: () {
|
||||
selectedMenu = 1;
|
||||
title = 'Laporan Penjualan Item';
|
||||
setState(() {});
|
||||
context.read<ItemSalesReportBloc>().add(
|
||||
ItemSalesReportEvent.getItemSales(
|
||||
startDate:
|
||||
DateFormatter.formatDateTime(
|
||||
fromDate),
|
||||
endDate: DateFormatter.formatDateTime(
|
||||
toDate)),
|
||||
);
|
||||
},
|
||||
isActive: selectedMenu == 1,
|
||||
),
|
||||
ReportMenu(
|
||||
label: 'Chart Penjualan Produk',
|
||||
subtitle:
|
||||
'Grafik visual penjualan produk untuk analisa performa penjualan.',
|
||||
icon: Icons.bar_chart_outlined,
|
||||
onPressed: () {
|
||||
selectedMenu = 2;
|
||||
title = 'Chart Penjualan Produk';
|
||||
setState(() {});
|
||||
context.read<ProductSalesBloc>().add(
|
||||
ProductSalesEvent.getProductSales(
|
||||
DateFormatter.formatDateTime(
|
||||
fromDate),
|
||||
DateFormatter.formatDateTime(toDate)),
|
||||
);
|
||||
},
|
||||
isActive: selectedMenu == 2,
|
||||
),
|
||||
ReportMenu(
|
||||
label: 'Ringkasan Laporan Penjualan',
|
||||
subtitle:
|
||||
'Ringkasan total penjualan dalam periode tertentu.',
|
||||
icon: Icons.insert_drive_file_outlined,
|
||||
onPressed: () {
|
||||
selectedMenu = 3;
|
||||
title = 'Ringkasan Laporan Penjualan';
|
||||
setState(() {});
|
||||
context.read<SummaryBloc>().add(
|
||||
SummaryEvent.getSummary(
|
||||
DateFormatter.formatDateTime(
|
||||
fromDate),
|
||||
DateFormatter.formatDateTime(toDate)),
|
||||
);
|
||||
|
||||
log("Date ${DateFormatter.formatDateTime(fromDate)}");
|
||||
},
|
||||
isActive: selectedMenu == 3,
|
||||
),
|
||||
ReportMenu(
|
||||
label: 'Laporan Metode Pembayaran',
|
||||
subtitle:
|
||||
'Laporan metode pembayaran yang digunakan.',
|
||||
icon: Icons.payment_outlined,
|
||||
onPressed: () {
|
||||
selectedMenu = 4;
|
||||
title = 'Laporan Metode Pembayaran';
|
||||
setState(() {});
|
||||
context.read<PaymentMethodReportBloc>().add(
|
||||
PaymentMethodReportEvent
|
||||
.getPaymentMethodReport(
|
||||
startDate:
|
||||
DateFormatter.formatDateTime(
|
||||
fromDate),
|
||||
endDate:
|
||||
DateFormatter.formatDateTime(
|
||||
toDate)),
|
||||
);
|
||||
},
|
||||
isActive: selectedMenu == 4,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// RIGHT CONTENT
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: selectedMenu == 0
|
||||
? BlocBuilder<TransactionReportBloc,
|
||||
TransactionReportState>(
|
||||
builder: (context, state) {
|
||||
return state.maybeWhen(
|
||||
orElse: () => const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
error: (message) {
|
||||
return Text(message);
|
||||
},
|
||||
loaded: (transactionReport) {
|
||||
return TransactionReportWidget(
|
||||
transactionReport: transactionReport,
|
||||
title: title,
|
||||
searchDateFormatted: searchDateFormatted,
|
||||
headerWidgets: _getTitleReportPageWidget(),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
)
|
||||
: selectedMenu == 1
|
||||
? BlocBuilder<ItemSalesReportBloc,
|
||||
ItemSalesReportState>(
|
||||
builder: (context, state) {
|
||||
return state.maybeWhen(
|
||||
orElse: () => const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
error: (message) {
|
||||
return Text(message);
|
||||
},
|
||||
loaded: (itemSales) {
|
||||
return ItemSalesReportWidget(
|
||||
itemSales: itemSales,
|
||||
title: title,
|
||||
searchDateFormatted:
|
||||
searchDateFormatted,
|
||||
headerWidgets:
|
||||
_getItemSalesPageWidget(),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
)
|
||||
: selectedMenu == 2
|
||||
? BlocBuilder<ProductSalesBloc,
|
||||
ProductSalesState>(
|
||||
builder: (context, state) {
|
||||
return state.maybeWhen(
|
||||
orElse: () => const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
error: (message) {
|
||||
return Text(message);
|
||||
},
|
||||
success: (productSales) {
|
||||
return ProductSalesChartWidgets(
|
||||
title: title,
|
||||
searchDateFormatted:
|
||||
searchDateFormatted,
|
||||
productSales: productSales,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
)
|
||||
: selectedMenu == 3
|
||||
? BlocBuilder<SummaryBloc, SummaryState>(
|
||||
builder: (context, state) {
|
||||
return state.maybeWhen(
|
||||
orElse: () => const Center(
|
||||
child:
|
||||
CircularProgressIndicator(),
|
||||
),
|
||||
error: (message) {
|
||||
return Text(message);
|
||||
},
|
||||
success: (summary) {
|
||||
return SummaryReportWidget(
|
||||
summary: summary,
|
||||
title: title,
|
||||
searchDateFormatted:
|
||||
searchDateFormatted,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
)
|
||||
: selectedMenu == 4
|
||||
? BlocBuilder<PaymentMethodReportBloc,
|
||||
PaymentMethodReportState>(
|
||||
builder: (context, state) {
|
||||
return state.maybeWhen(
|
||||
orElse: () => const Center(
|
||||
child:
|
||||
CircularProgressIndicator(),
|
||||
),
|
||||
error: (message) {
|
||||
return Text(message);
|
||||
},
|
||||
loaded: (paymentMethodData) {
|
||||
return PaymentMethodReportWidget(
|
||||
paymentMethodData:
|
||||
paymentMethodData,
|
||||
title: title,
|
||||
searchDateFormatted:
|
||||
searchDateFormatted,
|
||||
headerWidgets:
|
||||
_getPaymentMethodPageWidget(),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
)
|
||||
: const SizedBox.shrink()),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// RIGHT CONTENT
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: selectedMenu == 0
|
||||
? BlocBuilder<TransactionReportBloc, TransactionReportState>(
|
||||
builder: (context, state) {
|
||||
return state.maybeWhen(
|
||||
orElse: () => const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
error: (message) {
|
||||
return Text(message);
|
||||
},
|
||||
loaded: (transactionReport) {
|
||||
return TransactionReportWidget(
|
||||
transactionReport: transactionReport,
|
||||
title: title,
|
||||
searchDateFormatted: searchDateFormatted,
|
||||
headerWidgets: _getTitleReportPageWidget(),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
)
|
||||
: selectedMenu == 1
|
||||
? BlocBuilder<ItemSalesReportBloc, ItemSalesReportState>(
|
||||
builder: (context, state) {
|
||||
return state.maybeWhen(
|
||||
orElse: () => const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
error: (message) {
|
||||
return Text(message);
|
||||
},
|
||||
loaded: (itemSales) {
|
||||
return ItemSalesReportWidget(
|
||||
itemSales: itemSales,
|
||||
title: title,
|
||||
searchDateFormatted: searchDateFormatted,
|
||||
headerWidgets: _getItemSalesPageWidget(),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
)
|
||||
: selectedMenu == 2
|
||||
? BlocBuilder<ProductSalesBloc, ProductSalesState>(
|
||||
builder: (context, state) {
|
||||
return state.maybeWhen(
|
||||
orElse: () => const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
error: (message) {
|
||||
return Text(message);
|
||||
},
|
||||
success: (productSales) {
|
||||
return ProductSalesChartWidgets(
|
||||
title: title,
|
||||
searchDateFormatted: searchDateFormatted,
|
||||
productSales: productSales,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
)
|
||||
: selectedMenu == 3
|
||||
? BlocBuilder<SummaryBloc, SummaryState>(
|
||||
builder: (context, state) {
|
||||
return state.maybeWhen(
|
||||
orElse: () => const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
error: (message) {
|
||||
return Text(message);
|
||||
},
|
||||
success: (summary) {
|
||||
return SummaryReportWidget(
|
||||
summary: summary,
|
||||
title: title,
|
||||
searchDateFormatted: searchDateFormatted,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
)
|
||||
: selectedMenu == 4
|
||||
? BlocBuilder<PaymentMethodReportBloc, PaymentMethodReportState>(
|
||||
builder: (context, state) {
|
||||
return state.maybeWhen(
|
||||
orElse: () => const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
error: (message) {
|
||||
return Text(message);
|
||||
},
|
||||
loaded: (paymentMethodData) {
|
||||
return PaymentMethodReportWidget(
|
||||
paymentMethodData: paymentMethodData,
|
||||
title: title,
|
||||
searchDateFormatted: searchDateFormatted,
|
||||
headerWidgets: _getPaymentMethodPageWidget(),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
)
|
||||
: const SizedBox.shrink()),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -314,11 +364,11 @@ class _ReportPageState extends State<ReportPage> {
|
||||
List<Widget> _getItemSalesPageWidget() {
|
||||
return [
|
||||
_getTitleItemWidget('ID', 80),
|
||||
_getTitleItemWidget('Order', 60),
|
||||
_getTitleItemWidget('Product', 160),
|
||||
_getTitleItemWidget('Order', 100),
|
||||
_getTitleItemWidget('Product', 200),
|
||||
_getTitleItemWidget('Qty', 60),
|
||||
_getTitleItemWidget('Price', 140),
|
||||
_getTitleItemWidget('Total Price', 140),
|
||||
_getTitleItemWidget('Price', 150),
|
||||
_getTitleItemWidget('Total Price', 160),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user