Line data Source code
1 : // Copyright 2024 The terCAD team. All rights reserved.
2 : // Use of this source code is governed by a CC BY-NC-ND 4.0 license that can be found in the LICENSE file.
3 :
4 : import 'package:app_finance/_classes/herald/app_locale.dart';
5 : import 'package:app_finance/_classes/herald/app_start_of_month.dart';
6 : import 'package:app_finance/_classes/storage/app_data.dart';
7 : import 'package:app_finance/_classes/structure/bill_app_data.dart';
8 : import 'package:app_finance/_classes/structure/currency/exchange.dart';
9 : import 'package:app_finance/_classes/structure/invoice_app_data.dart';
10 : import 'package:app_finance/_ext/date_time_ext.dart';
11 : import 'package:excel/excel.dart';
12 : import 'package:file_picker/file_picker.dart';
13 : import 'package:flutter/foundation.dart';
14 :
15 : class ExportExcel {
16 : final AppData state;
17 : late final Excel excel;
18 : late final Exchange exchange;
19 :
20 0 : ExportExcel(this.state) {
21 0 : excel = Excel.createExcel();
22 0 : exchange = Exchange(store: state);
23 : }
24 :
25 0 : Future<void> exportAll() async {
26 0 : DateTime now = DateTime.now();
27 0 : int startingDay = AppStartOfMonth.get();
28 0 : DateTime curr = now.getStartingDay(startingDay);
29 0 : final invoiceStream = state.getStream(AppDataType.invoice, filter: (o) => o.accountFrom != null);
30 0 : final billStream = state.getStream(AppDataType.bills);
31 : int increment = 0;
32 0 : while (!(billStream.isFinished && invoiceStream.isFinished)) {
33 0 : var tabName = curr.yearMonth().replaceAll('/', '-');
34 0 : _addHeader(tabName);
35 0 : var boundary = curr.millisecondsSinceEpoch.toDouble();
36 0 : var invoiceList = invoiceStream.getTill(boundary);
37 0 : for (var invoice in invoiceList) {
38 0 : _addInvoiceRow(tabName, invoice);
39 : }
40 0 : var billList = billStream.getTill(boundary);
41 0 : for (var bill in billList) {
42 0 : _addBillRow(tabName, bill);
43 : }
44 0 : increment++;
45 0 : curr = DateTime(now.year, now.month - increment, now.day).getStartingDay(startingDay);
46 : }
47 0 : excel.delete('Sheet1');
48 : const fileName = 'fingrom_export.xlsx';
49 : if (kIsWeb) {
50 0 : excel.save(fileName: fileName);
51 : return;
52 : }
53 0 : final bytes = excel.encode();
54 : if (bytes == null) {
55 0 : throw Exception('Failed to generate $fileName');
56 : }
57 0 : await FilePicker.saveFile(
58 0 : dialogTitle: AppLocale.labels.outputFile,
59 : fileName: fileName,
60 0 : bytes: Uint8List.fromList(bytes),
61 : );
62 : }
63 :
64 0 : _addHeader(String name) {
65 0 : final sheet = excel[name];
66 0 : sheet.appendRow([
67 0 : TextCellValue(AppLocale.labels.uuid),
68 0 : TextCellValue(AppLocale.labels.balanceDate),
69 0 : TextCellValue(AppLocale.labels.flowTypeTooltip),
70 0 : TextCellValue(AppLocale.labels.title),
71 0 : TextCellValue(AppLocale.labels.account),
72 0 : TextCellValue(AppLocale.labels.budget),
73 0 : TextCellValue(AppLocale.labels.currency),
74 0 : TextCellValue(AppLocale.labels.details),
75 0 : TextCellValue(AppLocale.labels.currencyIn(exchange.getDefaultCurrency()?.code ?? '?')),
76 : ]);
77 0 : CellStyle cellStyle = CellStyle(
78 : bold: true,
79 0 : bottomBorder: Border(borderStyle: BorderStyle.Thin),
80 : );
81 0 : sheet.cell(CellIndex.indexByString("A1")).cellStyle = cellStyle;
82 0 : sheet.cell(CellIndex.indexByString("B1")).cellStyle = cellStyle;
83 0 : sheet.cell(CellIndex.indexByString("C1")).cellStyle = cellStyle;
84 0 : sheet.cell(CellIndex.indexByString("D1")).cellStyle = cellStyle;
85 0 : sheet.cell(CellIndex.indexByString("E1")).cellStyle = cellStyle;
86 0 : sheet.cell(CellIndex.indexByString("F1")).cellStyle = cellStyle;
87 0 : sheet.cell(CellIndex.indexByString("G1")).cellStyle = cellStyle;
88 0 : sheet.cell(CellIndex.indexByString("H1")).cellStyle = cellStyle;
89 0 : sheet.cell(CellIndex.indexByString("I1")).cellStyle = cellStyle;
90 : }
91 :
92 0 : void _addInvoiceRow(String name, InvoiceAppData data) {
93 0 : final sheet = excel[name];
94 0 : sheet.appendRow([
95 0 : TextCellValue(data.uuid ?? '?'),
96 0 : DateTimeCellValue.fromDateTime(data.createdAt),
97 0 : TextCellValue(AppLocale.labels.flowTypeInvoice),
98 0 : TextCellValue(data.title),
99 0 : TextCellValue(data.accountNamed),
100 0 : TextCellValue(' '),
101 0 : TextCellValue(data.currency?.code ?? '?'),
102 0 : DoubleCellValue(data.details),
103 0 : DoubleCellValue(exchange.reform(data.details ?? 0.0, data.currency, exchange.getDefaultCurrency())),
104 : ]);
105 : }
106 :
107 0 : void _addBillRow(String name, BillAppData data) {
108 0 : final sheet = excel[name];
109 0 : sheet.appendRow([
110 0 : TextCellValue(data.uuid ?? '?'),
111 0 : DateTimeCellValue.fromDateTime(data.createdAt),
112 0 : TextCellValue(AppLocale.labels.bill),
113 0 : TextCellValue(data.title),
114 0 : TextCellValue(data.accountNamed),
115 0 : TextCellValue(state.getByUuid(data.category)?.title ?? '?'),
116 0 : TextCellValue(data.currency?.code ?? '?'),
117 0 : DoubleCellValue(data.details),
118 0 : DoubleCellValue(exchange.reform(data.details ?? 0.0, data.currency, exchange.getDefaultCurrency())),
119 : ]);
120 : }
121 : }
|