Linking expenses to a transaction: Possibility to select currency-converted expenses #609

This commit is contained in:
Hillel Coren 2023-11-15 17:07:19 +02:00
parent 663b587144
commit 4cb8275218
1 changed files with 36 additions and 50 deletions

View File

@ -163,9 +163,9 @@ class _MatchDepositsState extends State<_MatchDeposits> {
TextEditingController? _invoiceFilterController; TextEditingController? _invoiceFilterController;
TextEditingController? _paymentFilterController; TextEditingController? _paymentFilterController;
FocusNode? _focusNode; FocusNode? _focusNode;
late List<InvoiceEntity?> _invoices; late List<InvoiceEntity> _invoices;
late List<InvoiceEntity?> _selectedInvoices; late List<InvoiceEntity> _selectedInvoices;
late List<PaymentEntity?> _payments; late List<PaymentEntity> _payments;
PaymentEntity? _selectedPayment; PaymentEntity? _selectedPayment;
bool _matchExisting = false; bool _matchExisting = false;
@ -200,21 +200,14 @@ class _MatchDepositsState extends State<_MatchDeposits> {
void updateInvoiceList() { void updateInvoiceList() {
final state = widget.viewModel.state; final state = widget.viewModel.state;
final invoiceState = state.invoiceState; final invoiceState = state.invoiceState;
final transactions = widget.viewModel.transactions;
_invoices = invoiceState.map.values.where((invoice) { _invoices = invoiceState.map.values.where((invoice) {
if (_selectedInvoices.isNotEmpty) { if (_selectedInvoices.isNotEmpty) {
if (invoice.clientId != _selectedInvoices.first!.clientId) { if (invoice.clientId != _selectedInvoices.first.clientId) {
return false; return false;
} }
} }
if (transactions.isNotEmpty &&
state.clientState.get(invoice.clientId).currencyId !=
transactions.first.currencyId) {
return false;
}
if (invoice.isPaid || invoice.isDeleted!) { if (invoice.isPaid || invoice.isDeleted!) {
return false; return false;
} }
@ -258,14 +251,13 @@ class _MatchDepositsState extends State<_MatchDeposits> {
return true; return true;
}).toList(); }).toList();
_invoices.sort((invoiceA, invoiceB) { _invoices.sort((invoiceA, invoiceB) {
return invoiceB!.date.compareTo(invoiceA!.date); return invoiceB.date.compareTo(invoiceA.date);
}); });
} }
void updatePaymentList() { void updatePaymentList() {
final state = widget.viewModel.state; final state = widget.viewModel.state;
final paymentState = state.paymentState; final paymentState = state.paymentState;
final transactions = widget.viewModel.transactions;
_payments = paymentState.map.values.where((payment) { _payments = paymentState.map.values.where((payment) {
if (_selectedPayment != null) { if (_selectedPayment != null) {
@ -278,12 +270,6 @@ class _MatchDepositsState extends State<_MatchDeposits> {
return false; return false;
} }
if (transactions.isNotEmpty &&
state.clientState.get(payment.clientId).currencyId !=
transactions.first.currencyId) {
return false;
}
final filter = _paymentFilterController!.text; final filter = _paymentFilterController!.text;
if (filter.isNotEmpty) { if (filter.isNotEmpty) {
@ -323,7 +309,7 @@ class _MatchDepositsState extends State<_MatchDeposits> {
return true; return true;
}).toList(); }).toList();
_payments.sort((paymentA, paymentB) { _payments.sort((paymentA, paymentB) {
return paymentB!.date.compareTo(paymentA!.date); return paymentB.date.compareTo(paymentA.date);
}); });
} }
@ -355,16 +341,20 @@ class _MatchDepositsState extends State<_MatchDeposits> {
final viewModel = widget.viewModel; final viewModel = widget.viewModel;
final state = viewModel.state; final state = viewModel.state;
String? currencyId; final totalSelected = <String, double>{};
if (_selectedInvoices.isNotEmpty) {
currencyId =
state.clientState.get(_selectedInvoices.first!.clientId).currencyId;
}
double totalSelected = 0;
_selectedInvoices.forEach((invoice) { _selectedInvoices.forEach((invoice) {
totalSelected += invoice!.balanceOrAmount; final client = state.clientState.get(invoice.clientId);
final currencyId = client.currencyId ?? kCurrencyUSDollar;
if (!totalSelected.containsKey(currencyId)) {
totalSelected[currencyId] = 0;
}
totalSelected[currencyId] =
totalSelected[currencyId]! + invoice.balanceOrAmount;
}); });
final totalSelectedString = totalSelected.keys.map((currencyId) {
return formatNumber(totalSelected[currencyId], context,
currencyId: currencyId);
}).join(' | ');
return Column( return Column(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
@ -552,7 +542,7 @@ class _MatchDepositsState extends State<_MatchDeposits> {
separatorBuilder: (context, index) => ListDivider(), separatorBuilder: (context, index) => ListDivider(),
itemCount: _payments.length, itemCount: _payments.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
final payment = _payments[index]!; final payment = _payments[index];
return PaymentListItem( return PaymentListItem(
payment: payment, payment: payment,
showCheckbox: true, showCheckbox: true,
@ -581,7 +571,7 @@ class _MatchDepositsState extends State<_MatchDeposits> {
separatorBuilder: (context, index) => ListDivider(), separatorBuilder: (context, index) => ListDivider(),
itemCount: _invoices.length, itemCount: _invoices.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
final invoice = _invoices[index]!; final invoice = _invoices[index];
return InvoiceListItem( return InvoiceListItem(
invoice: invoice, invoice: invoice,
showCheckbox: true, showCheckbox: true,
@ -604,7 +594,7 @@ class _MatchDepositsState extends State<_MatchDeposits> {
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
child: Text( child: Text(
'${_selectedInvoices.length} ${localization.selected}${formatNumber(totalSelected, context, currencyId: currencyId)}', '${_selectedInvoices.length} ${localization.selected}$totalSelectedString',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle(color: Colors.grey), style: TextStyle(color: Colors.grey),
), ),
@ -642,7 +632,7 @@ class _MatchDepositsState extends State<_MatchDeposits> {
viewModel.onConvertToPayment( viewModel.onConvertToPayment(
context, context,
_selectedInvoices _selectedInvoices
.map((invoice) => invoice!.id) .map((invoice) => invoice.id)
.toList(), .toList(),
); );
}, },
@ -689,7 +679,7 @@ class _MatchWithdrawalsState extends State<_MatchWithdrawals> {
late List<ExpenseEntity?> _expenses; late List<ExpenseEntity?> _expenses;
VendorEntity? _selectedVendor; VendorEntity? _selectedVendor;
ExpenseCategoryEntity? _selectedCategory; ExpenseCategoryEntity? _selectedCategory;
late List<ExpenseEntity?> _selectedExpenses; late List<ExpenseEntity> _selectedExpenses;
@override @override
void initState() { void initState() {
@ -793,18 +783,12 @@ class _MatchWithdrawalsState extends State<_MatchWithdrawals> {
void updateExpenseList() { void updateExpenseList() {
final state = widget.viewModel.state; final state = widget.viewModel.state;
final expenseState = state.expenseState; final expenseState = state.expenseState;
final transactions = widget.viewModel.transactions;
_expenses = expenseState.map.values.where((expense) { _expenses = expenseState.map.values.where((expense) {
if (expense.transactionId.isNotEmpty || expense.isDeleted!) { if (expense.transactionId.isNotEmpty || expense.isDeleted!) {
return false; return false;
} }
if (transactions.isNotEmpty &&
expense.currencyId != transactions.first.currencyId) {
return false;
}
final filter = _expenseFilterController!.text; final filter = _expenseFilterController!.text;
if (filter.isNotEmpty) { if (filter.isNotEmpty) {
@ -889,16 +873,18 @@ class _MatchWithdrawalsState extends State<_MatchWithdrawals> {
final transaction = final transaction =
transactions.isNotEmpty ? transactions.first : TransactionEntity(); transactions.isNotEmpty ? transactions.first : TransactionEntity();
String? currencyId; final totalSelected = <String, double>{};
if (_selectedExpenses.isNotEmpty) {
currencyId =
state.clientState.get(_selectedExpenses.first!.clientId!).currencyId;
}
double totalSelected = 0;
_selectedExpenses.forEach((expense) { _selectedExpenses.forEach((expense) {
totalSelected += expense!.grossAmount; if (!totalSelected.containsKey(expense.currencyId)) {
totalSelected[expense.currencyId] = 0;
}
totalSelected[expense.currencyId] =
totalSelected[expense.currencyId]! + expense.grossAmount;
}); });
final totalSelectedString = totalSelected.keys.map((currencyId) {
return formatNumber(totalSelected[currencyId], context,
currencyId: currencyId);
}).join(' | ');
return Column( return Column(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
@ -1063,7 +1049,7 @@ class _MatchWithdrawalsState extends State<_MatchWithdrawals> {
store.dispatch(SaveTransactionSuccess(transaction.rebuild( store.dispatch(SaveTransactionSuccess(transaction.rebuild(
(b) => b (b) => b
..pendingExpenseId = _selectedExpenses ..pendingExpenseId = _selectedExpenses
.map((expense) => expense!.id) .map((expense) => expense.id)
.join(',')))); .join(','))));
}), }),
); );
@ -1258,7 +1244,7 @@ class _MatchWithdrawalsState extends State<_MatchWithdrawals> {
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
child: Text( child: Text(
'${_selectedExpenses.length} ${localization.selected}${formatNumber(totalSelected, context, currencyId: currencyId)}', '${_selectedExpenses.length} ${localization.selected}$totalSelectedString',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle(color: Colors.grey), style: TextStyle(color: Colors.grey),
), ),
@ -1283,7 +1269,7 @@ class _MatchWithdrawalsState extends State<_MatchWithdrawals> {
viewModel.onLinkToExpense( viewModel.onLinkToExpense(
context, context,
_selectedExpenses _selectedExpenses
.map((expense) => expense!.id) .map((expense) => expense.id)
.join(','), .join(','),
); );
}, },