feat: inventory report
This commit is contained in:
@@ -1,16 +1,34 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
|
||||
import '../../../application/report/inventory_report/inventory_report_bloc.dart';
|
||||
import '../../../common/extension/extension.dart';
|
||||
import '../../../common/theme/theme.dart';
|
||||
import '../../../common/utils/pdf_service.dart';
|
||||
import '../../../common/utils/permission.dart';
|
||||
import '../../../injection.dart';
|
||||
import '../../components/appbar/appbar.dart';
|
||||
import '../../components/field/date_range_picker_field.dart';
|
||||
import '../../components/report/inventory_report.dart';
|
||||
import '../../components/toast/flushbar.dart';
|
||||
|
||||
@RoutePage()
|
||||
class DownloadReportPage extends StatefulWidget {
|
||||
class DownloadReportPage extends StatefulWidget implements AutoRouteWrapper {
|
||||
const DownloadReportPage({super.key});
|
||||
|
||||
@override
|
||||
State<DownloadReportPage> createState() => _DownloadReportPageState();
|
||||
|
||||
@override
|
||||
Widget wrappedRoute(BuildContext context) => BlocProvider(
|
||||
create: (context) =>
|
||||
getIt<InventoryReportBloc>()..add(InventoryReportEvent.fetchedOutlet()),
|
||||
child: this,
|
||||
);
|
||||
}
|
||||
|
||||
class _DownloadReportPageState extends State<DownloadReportPage>
|
||||
@@ -26,10 +44,10 @@ class _DownloadReportPageState extends State<DownloadReportPage>
|
||||
DateTime? _transactionEndDate;
|
||||
DateTime? _inventoryStartDate;
|
||||
DateTime? _inventoryEndDate;
|
||||
DateTime? _salesStartDate;
|
||||
DateTime? _salesEndDate;
|
||||
DateTime? _customerStartDate;
|
||||
DateTime? _customerEndDate;
|
||||
// DateTime? _salesStartDate;
|
||||
// DateTime? _salesEndDate;
|
||||
// DateTime? _customerStartDate;
|
||||
// DateTime? _customerEndDate;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -76,28 +94,9 @@ class _DownloadReportPageState extends State<DownloadReportPage>
|
||||
DateTime? endDate,
|
||||
) {
|
||||
if (startDate == null || endDate == null) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Please select both start and end dates'),
|
||||
backgroundColor: AppColor.error,
|
||||
),
|
||||
);
|
||||
AppFlushbar.showError(context, 'Please select both start and end dates');
|
||||
return;
|
||||
}
|
||||
|
||||
// Implement download logic here
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
'Downloading $reportType from ${_formatDate(startDate)} to ${_formatDate(endDate)}',
|
||||
),
|
||||
backgroundColor: AppColor.success,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _formatDate(DateTime date) {
|
||||
return '${date.day}/${date.month}/${date.year}';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -139,6 +138,7 @@ class _DownloadReportPageState extends State<DownloadReportPage>
|
||||
],
|
||||
startDate: _transactionStartDate,
|
||||
endDate: _transactionEndDate,
|
||||
isLoading: false,
|
||||
onDateRangeChanged: (start, end) {
|
||||
setState(() {
|
||||
_transactionStartDate = start;
|
||||
@@ -156,79 +156,115 @@ class _DownloadReportPageState extends State<DownloadReportPage>
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Inventory Report Card
|
||||
_ReportOptionCard(
|
||||
title: 'Inventory Report',
|
||||
subtitle:
|
||||
'Export inventory and stock data with trends',
|
||||
icon: Icons.inventory_2_outlined,
|
||||
gradient: const [
|
||||
AppColor.secondary,
|
||||
AppColor.secondaryLight,
|
||||
],
|
||||
startDate: _inventoryStartDate,
|
||||
endDate: _inventoryEndDate,
|
||||
onDateRangeChanged: (start, end) {
|
||||
setState(() {
|
||||
_inventoryStartDate = start;
|
||||
_inventoryEndDate = end;
|
||||
});
|
||||
BlocBuilder<InventoryReportBloc, InventoryReportState>(
|
||||
builder: (context, state) {
|
||||
return _ReportOptionCard(
|
||||
title: 'Inventory Report',
|
||||
subtitle:
|
||||
'Export inventory and stock data with trends',
|
||||
icon: Icons.inventory_2_outlined,
|
||||
gradient: const [
|
||||
AppColor.secondary,
|
||||
AppColor.secondaryLight,
|
||||
],
|
||||
startDate: _inventoryStartDate,
|
||||
endDate: _inventoryEndDate,
|
||||
isLoading: state.isFetching,
|
||||
onDateRangeChanged: (start, end) {
|
||||
setState(() {
|
||||
_inventoryStartDate = start;
|
||||
_inventoryEndDate = end;
|
||||
});
|
||||
if (start != null || end != null) {
|
||||
context.read<InventoryReportBloc>().add(
|
||||
InventoryReportEvent.fetchedInventory(
|
||||
start!,
|
||||
end!,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
onDownload: () async {
|
||||
try {
|
||||
final status = await PermessionHelper()
|
||||
.checkPermission();
|
||||
if (status) {
|
||||
final pdfFile =
|
||||
await InventoryReport.previewPdf(
|
||||
searchDateFormatted:
|
||||
"${_inventoryStartDate?.toServerDate} - ${_inventoryEndDate?.toServerDate}",
|
||||
inventory: state.inventoryAnalytic,
|
||||
outlet: state.outlet,
|
||||
);
|
||||
log("pdfFile: $pdfFile");
|
||||
await HelperPdfService.openFile(pdfFile);
|
||||
} else {
|
||||
AppFlushbar.showError(
|
||||
context,
|
||||
'Storage permission is required to save PDF',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
log("Error generating PDF: $e");
|
||||
AppFlushbar.showError(
|
||||
context,
|
||||
'Failed to generate PDF: $e',
|
||||
);
|
||||
}
|
||||
},
|
||||
delay: 400,
|
||||
);
|
||||
},
|
||||
onDownload: () => _downloadReport(
|
||||
'Inventory Report',
|
||||
_inventoryStartDate,
|
||||
_inventoryEndDate,
|
||||
),
|
||||
delay: 400,
|
||||
),
|
||||
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Sales Report Card
|
||||
_ReportOptionCard(
|
||||
title: 'Sales Report',
|
||||
subtitle: 'Export sales performance and revenue data',
|
||||
icon: Icons.trending_up_outlined,
|
||||
gradient: const [AppColor.info, Color(0xFF64B5F6)],
|
||||
startDate: _salesStartDate,
|
||||
endDate: _salesEndDate,
|
||||
onDateRangeChanged: (start, end) {
|
||||
setState(() {
|
||||
_salesStartDate = start;
|
||||
_salesEndDate = end;
|
||||
});
|
||||
},
|
||||
onDownload: () => _downloadReport(
|
||||
'Sales Report',
|
||||
_salesStartDate,
|
||||
_salesEndDate,
|
||||
),
|
||||
delay: 600,
|
||||
),
|
||||
// _ReportOptionCard(
|
||||
// title: 'Sales Report',
|
||||
// subtitle: 'Export sales performance and revenue data',
|
||||
// icon: Icons.trending_up_outlined,
|
||||
// gradient: const [AppColor.info, Color(0xFF64B5F6)],
|
||||
// startDate: _salesStartDate,
|
||||
// endDate: _salesEndDate,
|
||||
// onDateRangeChanged: (start, end) {
|
||||
// setState(() {
|
||||
// _salesStartDate = start;
|
||||
// _salesEndDate = end;
|
||||
// });
|
||||
// },
|
||||
// onDownload: () => _downloadReport(
|
||||
// 'Sales Report',
|
||||
// _salesStartDate,
|
||||
// _salesEndDate,
|
||||
// ),
|
||||
// delay: 600,
|
||||
// ),
|
||||
|
||||
const SizedBox(height: 20),
|
||||
// const SizedBox(height: 20),
|
||||
|
||||
// Customer Report Card
|
||||
_ReportOptionCard(
|
||||
title: 'Customer Report',
|
||||
subtitle:
|
||||
'Export customer data and behavior analytics',
|
||||
icon: Icons.people_outline,
|
||||
gradient: const [AppColor.warning, Color(0xFFFFB74D)],
|
||||
startDate: _customerStartDate,
|
||||
endDate: _customerEndDate,
|
||||
onDateRangeChanged: (start, end) {
|
||||
setState(() {
|
||||
_customerStartDate = start;
|
||||
_customerEndDate = end;
|
||||
});
|
||||
},
|
||||
onDownload: () => _downloadReport(
|
||||
'Customer Report',
|
||||
_customerStartDate,
|
||||
_customerEndDate,
|
||||
),
|
||||
delay: 800,
|
||||
),
|
||||
// // Customer Report Card
|
||||
// _ReportOptionCard(
|
||||
// title: 'Customer Report',
|
||||
// subtitle:
|
||||
// 'Export customer data and behavior analytics',
|
||||
// icon: Icons.people_outline,
|
||||
// gradient: const [AppColor.warning, Color(0xFFFFB74D)],
|
||||
// startDate: _customerStartDate,
|
||||
// endDate: _customerEndDate,
|
||||
// onDateRangeChanged: (start, end) {
|
||||
// setState(() {
|
||||
// _customerStartDate = start;
|
||||
// _customerEndDate = end;
|
||||
// });
|
||||
// },
|
||||
// onDownload: () => _downloadReport(
|
||||
// 'Customer Report',
|
||||
// _customerStartDate,
|
||||
// _customerEndDate,
|
||||
// ),
|
||||
// delay: 800,
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -253,6 +289,7 @@ class _ReportOptionCard extends StatefulWidget {
|
||||
final DateTime? endDate;
|
||||
final Function(DateTime? startDate, DateTime? endDate) onDateRangeChanged;
|
||||
final VoidCallback onDownload;
|
||||
final bool isLoading;
|
||||
final int delay;
|
||||
|
||||
const _ReportOptionCard({
|
||||
@@ -265,6 +302,7 @@ class _ReportOptionCard extends StatefulWidget {
|
||||
required this.onDateRangeChanged,
|
||||
required this.onDownload,
|
||||
required this.delay,
|
||||
required this.isLoading,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -431,23 +469,41 @@ class _ReportOptionCardState extends State<_ReportOptionCard>
|
||||
),
|
||||
elevation: 0,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.download_rounded,
|
||||
color: widget.gradient.first,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'Download Report',
|
||||
style: AppStyle.md.copyWith(
|
||||
color: widget.gradient.first,
|
||||
fontWeight: FontWeight.bold,
|
||||
child: widget.isLoading
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SpinKitCircle(
|
||||
color: widget.gradient.first,
|
||||
size: 24,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'Loading',
|
||||
style: AppStyle.md.copyWith(
|
||||
color: widget.gradient.first,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.download_rounded,
|
||||
color: widget.gradient.first,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'Download Report',
|
||||
style: AppStyle.md.copyWith(
|
||||
color: widget.gradient.first,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user