diff --git a/lib/redux/dashboard/dashboard_selectors.dart b/lib/redux/dashboard/dashboard_selectors.dart index 2f9497e61..440183707 100644 --- a/lib/redux/dashboard/dashboard_selectors.dart +++ b/lib/redux/dashboard/dashboard_selectors.dart @@ -1,10 +1,13 @@ +import 'package:built_collection/built_collection.dart'; import 'package:charts_common/common.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:invoiceninja_flutter/constants.dart'; +import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:invoiceninja_flutter/redux/dashboard/dashboard_state.dart'; import 'package:invoiceninja_flutter/redux/task/task_selectors.dart'; import 'package:invoiceninja_flutter/utils/formatting.dart'; +import 'package:invoiceninja_flutter/utils/money.dart'; import 'package:memoize/memoize.dart'; -import 'package:built_collection/built_collection.dart'; -import 'package:invoiceninja_flutter/data/models/models.dart'; class ChartDataGroup { ChartDataGroup(this.name); @@ -24,17 +27,20 @@ class ChartMoneyData { final double amount; } -var memoizedChartInvoices = memo4((CompanyEntity company, +var memoizedChartInvoices = memo5((BuildContext context, + CompanyEntity company, DashboardUIState settings, BuiltMap invoiceMap, BuiltMap clientMap) => chartInvoices( + context: context, company: company, settings: settings, invoiceMap: invoiceMap, clientMap: clientMap)); List chartInvoices({ + BuildContext context, CompanyEntity company, DashboardUIState settings, BuiltMap invoiceMap, @@ -74,8 +80,21 @@ List chartInvoices({ totals[STATUS_ACTIVE][invoice.invoiceDate] = 0.0; totals[STATUS_OUTSTANDING][invoice.invoiceDate] = 0.0; } - totals[STATUS_ACTIVE][invoice.invoiceDate] += invoice.amount; - totals[STATUS_OUTSTANDING][invoice.invoiceDate] += invoice.balance; + + double amount = invoice.amount; + double balance = invoice.balance; + + // Handle "All" + if (settings.currencyId == kCurrencyAll && + currencyId != company.currencyId) { + amount *= getExchangeRate(context, + fromCurrencyId: currencyId, toCurrencyId: company.currencyId); + balance *= getExchangeRate(context, + fromCurrencyId: currencyId, toCurrencyId: company.currencyId); + } + + totals[STATUS_ACTIVE][invoice.invoiceDate] += amount; + totals[STATUS_OUTSTANDING][invoice.invoiceDate] += balance; counts[STATUS_ACTIVE]++; if (invoice.balance > 0) { @@ -119,17 +138,20 @@ List chartInvoices({ return data; } -var memoizedChartQuotes = memo4((CompanyEntity company, +var memoizedChartQuotes = memo5((BuildContext context, + CompanyEntity company, DashboardUIState settings, BuiltMap quoteMap, BuiltMap clientMap) => chartQuotes( + context: context, company: company, settings: settings, quoteMap: quoteMap, clientMap: clientMap)); List chartQuotes({ + BuildContext context, CompanyEntity company, DashboardUIState settings, BuiltMap quoteMap, @@ -174,7 +196,16 @@ List chartQuotes({ totals[STATUS_UNAPPROVED][quote.invoiceDate] = 0.0; } - totals[STATUS_ACTIVE][quote.invoiceDate] += quote.amount; + double amount = quote.amount; + + // Handle "All" + if (settings.currencyId == kCurrencyAll && + currencyId != company.currencyId) { + amount *= getExchangeRate(context, + fromCurrencyId: currencyId, toCurrencyId: company.currencyId); + } + + totals[STATUS_ACTIVE][quote.invoiceDate] += amount; counts[STATUS_ACTIVE]++; if (quote.isApproved) { totals[STATUS_APPROVED][quote.invoiceDate] += quote.amount; @@ -229,14 +260,17 @@ List chartQuotes({ return data; } -var memoizedChartPayments = memo5((CompanyEntity company, +var memoizedChartPayments = memo6((BuildContext context, + CompanyEntity company, DashboardUIState settings, BuiltMap invoiceMap, BuiltMap clientMap, BuiltMap paymentMap) => - chartPayments(company, settings, invoiceMap, clientMap, paymentMap)); + chartPayments( + context, company, settings, invoiceMap, clientMap, paymentMap)); List chartPayments( + BuildContext context, CompanyEntity company, DashboardUIState settings, BuiltMap invoiceMap, @@ -275,8 +309,21 @@ List chartPayments( totals[STATUS_ACTIVE][payment.paymentDate] = 0.0; totals[STATUS_REFUNDED][payment.paymentDate] = 0.0; } - totals[STATUS_ACTIVE][payment.paymentDate] += payment.completedAmount; - totals[STATUS_REFUNDED][payment.paymentDate] += payment.refunded; + + double completedAmount = payment.completedAmount; + double refunded = payment.refunded; + + // Handle "All" + if (settings.currencyId == kCurrencyAll && + currencyId != company.currencyId) { + completedAmount *= getExchangeRate(context, + fromCurrencyId: currencyId, toCurrencyId: company.currencyId); + refunded *= getExchangeRate(context, + fromCurrencyId: currencyId, toCurrencyId: company.currencyId); + } + + totals[STATUS_ACTIVE][payment.paymentDate] += completedAmount; + totals[STATUS_REFUNDED][payment.paymentDate] += refunded; counts[STATUS_ACTIVE]++; if (payment.refunded > 0) { @@ -321,6 +368,7 @@ List chartPayments( } List chartTasks( + BuildContext context, CompanyEntity company, DashboardUIState settings, BuiltMap taskMap, @@ -368,7 +416,14 @@ List chartTasks( final taskRate = taskRateSelector( company: company, project: project, client: client); - final double amount = taskRate * round(duration.inSeconds / 3600, 3); + double amount = taskRate * round(duration.inSeconds / 3600, 3); + + // Handle "All" + if (settings.currencyId == kCurrencyAll && + currencyId != company.currencyId) { + amount *= getExchangeRate(context, + fromCurrencyId: currencyId, toCurrencyId: company.currencyId); + } if (task.isInvoiced) { if (invoiceMap.containsKey(task.invoiceId) && @@ -429,15 +484,18 @@ List chartTasks( return data; } -var memoizedChartTasks = memo6((CompanyEntity company, +var memoizedChartTasks = memo7((BuildContext context, + CompanyEntity company, DashboardUIState settings, BuiltMap taskMap, BuiltMap invoiceMap, BuiltMap projectMap, BuiltMap clientMap) => - chartTasks(company, settings, taskMap, invoiceMap, projectMap, clientMap)); + chartTasks(context, company, settings, taskMap, invoiceMap, projectMap, + clientMap)); List chartExpenses( + BuildContext context, CompanyEntity company, DashboardUIState settings, BuiltMap invoiceMap, @@ -464,7 +522,7 @@ List chartExpenses( expenseMap.forEach((int, expense) { final currencyId = expense.expenseCurrencyId; final date = expense.expenseDate; - final amount = expense.amountWithTax; + double amount = expense.amountWithTax; if (expense.isDeleted) { // skip it @@ -481,6 +539,13 @@ List chartExpenses( totals[STATUS_PAID][date] = 0.0; } + // Handle "All" + if (settings.currencyId == kCurrencyAll && + currencyId != company.currencyId) { + amount *= getExchangeRate(context, + fromCurrencyId: currencyId, toCurrencyId: company.currencyId); + } + if (expense.isInvoiced) { final invoice = invoiceMap[expense.invoiceId] ?? InvoiceEntity(); if (invoice.isPaid) { @@ -549,8 +614,9 @@ List chartExpenses( return data; } -var memoizedChartExpenses = memo4((CompanyEntity company, +var memoizedChartExpenses = memo5((BuildContext context, + CompanyEntity company, DashboardUIState settings, BuiltMap invoiceMap, BuiltMap expenseMap) => - chartExpenses(company, settings, invoiceMap, expenseMap)); + chartExpenses(context, company, settings, invoiceMap, expenseMap)); diff --git a/lib/ui/dashboard/dashboard_panels.dart b/lib/ui/dashboard/dashboard_panels.dart index 9ff09c381..65c2062be 100644 --- a/lib/ui/dashboard/dashboard_panels.dart +++ b/lib/ui/dashboard/dashboard_panels.dart @@ -95,9 +95,10 @@ class DashboardPanels extends StatelessWidget { child: DropdownButton( items: memoizedGetCurrencyIds(company, clientMap) .map((currencyId) => DropdownMenuItem( - child: Text( - viewModel.currencyMap[currencyId]?.code ?? - localization.all), + child: Text(currencyId == kCurrencyAll + ? localization.all + : viewModel + .currencyMap[currencyId]?.code), value: currencyId, )) .toList(), @@ -184,12 +185,13 @@ class DashboardPanels extends StatelessWidget { final isLoaded = viewModel.state.invoiceState.isLoaded; final settings = viewModel.dashboardUIState; final state = viewModel.state; - final currentData = memoizedChartInvoices(state.selectedCompany, settings, - state.invoiceState.map, state.clientState.map); + final currentData = memoizedChartInvoices(context, state.selectedCompany, + settings, state.invoiceState.map, state.clientState.map); List previousData; if (settings.enableComparison) { previousData = memoizedChartInvoices( + context, state.selectedCompany, settings.rebuild((b) => b..offset += 1), state.invoiceState.map, @@ -209,6 +211,7 @@ class DashboardPanels extends StatelessWidget { final settings = viewModel.dashboardUIState; final state = viewModel.state; final currentData = memoizedChartPayments( + context, state.selectedCompany, settings, state.invoiceState.map, @@ -218,6 +221,7 @@ class DashboardPanels extends StatelessWidget { List previousData; if (settings.enableComparison) { previousData = memoizedChartPayments( + context, state.selectedCompany, settings.rebuild((b) => b..offset += 1), state.invoiceState.map, @@ -237,12 +241,13 @@ class DashboardPanels extends StatelessWidget { final settings = viewModel.dashboardUIState; final state = viewModel.state; final isLoaded = state.quoteState.isLoaded; - final currentData = memoizedChartQuotes(state.selectedCompany, settings, - state.quoteState.map, state.clientState.map); + final currentData = memoizedChartQuotes(context, state.selectedCompany, + settings, state.quoteState.map, state.clientState.map); List previousData; if (settings.enableComparison) { previousData = memoizedChartQuotes( + context, state.selectedCompany, settings.rebuild((b) => b..offset += 1), state.quoteState.map, @@ -263,6 +268,7 @@ class DashboardPanels extends StatelessWidget { final isLoaded = state.taskState.isLoaded; final currentData = memoizedChartTasks( + context, state.selectedCompany, settings, state.taskState.map, @@ -273,6 +279,7 @@ class DashboardPanels extends StatelessWidget { List previousData; if (settings.enableComparison) { previousData = memoizedChartTasks( + context, state.selectedCompany, settings.rebuild((b) => b..offset += 1), state.taskState.map, @@ -293,12 +300,13 @@ class DashboardPanels extends StatelessWidget { final settings = viewModel.dashboardUIState; final state = viewModel.state; final isLoaded = state.expenseState.isLoaded; - final currentData = memoizedChartExpenses(state.selectedCompany, settings, - state.invoiceState.map, state.expenseState.map); + final currentData = memoizedChartExpenses(context, state.selectedCompany, + settings, state.invoiceState.map, state.expenseState.map); List previousData; if (settings.enableComparison) { previousData = memoizedChartExpenses( + context, state.selectedCompany, settings.rebuild((b) => b..offset += 1), state.invoiceState.map,