diff --git a/lib/redux/dashboard/dashboard_selectors.dart b/lib/redux/dashboard/dashboard_selectors.dart index 4bb9603da..f9221f6c5 100644 --- a/lib/redux/dashboard/dashboard_selectors.dart +++ b/lib/redux/dashboard/dashboard_selectors.dart @@ -4,6 +4,15 @@ 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); + + final String name; + final List rawSeries = []; + dynamic chartSeries; + double total = 0.0; +} + class ChartMoneyData { ChartMoneyData(this.date, this.amount); @@ -32,14 +41,17 @@ var memoizedChartOutstandingQuotes = memo4((CompanyEntity company, clientMap: clientMap, isQuote: true)); -List chartOutstandingInvoices({ +List chartOutstandingInvoices({ CompanyEntity company, DashboardUIState settings, BuiltMap invoiceMap, BuiltMap clientMap, bool isQuote = false, }) { - final Map totals = {}; + final Map> totals = {}; + + const STATUS_ACTIVE = 'active'; + const STATUS_OUTSTANDING = 'outstanding'; invoiceMap.forEach((int, invoice) { final client = @@ -61,26 +73,41 @@ List chartOutstandingInvoices({ // skip it } else { if (totals[invoice.invoiceDate] == null) { - totals[invoice.invoiceDate] = 0.0; + totals[STATUS_ACTIVE][invoice.invoiceDate] = 0.0; + totals[STATUS_OUTSTANDING][invoice.invoiceDate] = 0.0; } - totals[invoice.invoiceDate] += invoice.amount; + + totals[STATUS_ACTIVE][invoice.invoiceDate] += invoice.amount; + totals[STATUS_OUTSTANDING][invoice.invoiceDate] += invoice.balance; } }); - final List data = []; + final ChartDataGroup activeData = ChartDataGroup(STATUS_ACTIVE); + final ChartDataGroup outstandingData = ChartDataGroup(STATUS_OUTSTANDING); var date = DateTime.parse(settings.startDate(company)); final endDate = DateTime.parse(settings.endDate(company)); + while (!date.isAfter(endDate)) { final key = convertDateTimeToSqlDate(date); - if (totals.containsKey(key)) { - data.add(ChartMoneyData(date, totals[key])); + if (totals[STATUS_ACTIVE].containsKey(key)) { + activeData.rawSeries.add(ChartMoneyData(date, totals[STATUS_ACTIVE][key])); + activeData.total += totals[STATUS_ACTIVE][key]; + outstandingData.rawSeries + .add(ChartMoneyData(date, totals[STATUS_OUTSTANDING][key])); + outstandingData.total += totals[STATUS_OUTSTANDING][key]; } else { - data.add(ChartMoneyData(date, 0.0)); + activeData.rawSeries.add(ChartMoneyData(date, 0.0)); + outstandingData.rawSeries.add(ChartMoneyData(date, 0.0)); } date = date.add(Duration(days: 1)); } + final List data = [ + activeData, + outstandingData, + ]; + return data; } diff --git a/lib/ui/dashboard/dashboard_chart.dart b/lib/ui/dashboard/dashboard_chart.dart index 10ecdfaaf..35d39dd81 100644 --- a/lib/ui/dashboard/dashboard_chart.dart +++ b/lib/ui/dashboard/dashboard_chart.dart @@ -1,21 +1,18 @@ import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart'; +import 'package:invoiceninja_flutter/redux/dashboard/dashboard_selectors.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart'; import 'package:charts_flutter/flutter.dart' as charts; import 'package:invoiceninja_flutter/utils/formatting.dart'; class DashboardChart extends StatefulWidget { const DashboardChart( - {this.series, - this.amount, - this.previousAmount, + {this.data, this.title, this.currencyId}); - final List series; - final double previousAmount; - final double amount; + final List data; final String title; final int currencyId; @@ -66,6 +63,7 @@ class _DashboardChartState extends State { ? charts.MaterialPalette.white : charts.MaterialPalette.gray.shade700; + /* final chart = charts.TimeSeriesChart( widget.series, animate: true, @@ -109,6 +107,7 @@ class _DashboardChartState extends State { final String changeString = widget.amount == 0 || widget.previousAmount == 0 ? '' : '$changeAmount ($changePercent)'; + */ return FormCard( children: [ @@ -116,6 +115,7 @@ class _DashboardChartState extends State { padding: EdgeInsets.symmetric(vertical: 14.0, horizontal: 4.0), child: Column( children: [ + Text(widget.title,), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -125,6 +125,7 @@ class _DashboardChartState extends State { children: [ Text(widget.title, style: Theme.of(context).textTheme.subhead), + /* Text( formatNumber(widget.amount, context, currencyId: widget.currencyId), @@ -138,6 +139,7 @@ class _DashboardChartState extends State { fontWeight: FontWeight.bold, ), ), + */ ], ), ), @@ -158,7 +160,7 @@ class _DashboardChartState extends State { height: 200.0, child: Padding( padding: const EdgeInsets.only(top: 10.0), - child: chart, + //child: chart, ), ), ], diff --git a/lib/ui/dashboard/dashboard_panels.dart b/lib/ui/dashboard/dashboard_panels.dart index d74bac752..f210a0160 100644 --- a/lib/ui/dashboard/dashboard_panels.dart +++ b/lib/ui/dashboard/dashboard_panels.dart @@ -112,8 +112,8 @@ class DashboardPanels extends StatelessWidget { final data = memoizedChartOutstandingInvoices(state.selectedCompany, settings, state.invoiceState.map, state.clientState.map); - final series = [ - charts.Series( + data.forEach((dataGroup) { + dataGroup.chartSeries = charts.Series( domainFn: (ChartMoneyData chartData, _) => chartData.date, measureFn: (ChartMoneyData chartData, _) => chartData.amount, colorFn: (ChartMoneyData chartData, _) => @@ -122,49 +122,40 @@ class DashboardPanels extends StatelessWidget { displayName: settings.enableComparison ? localization.current : localization.invoices, - data: data, - ), - ]; - - double total = 0.0; - double previousTotal = 0.0; - data.forEach((dynamic item) { - total += item.amount; - }); - - if (settings.enableComparison) { - final offsetData = memoizedChartOutstandingInvoices( - state.selectedCompany, - settings.rebuild((b) => b..offset += 1), - state.invoiceState.map, - state.clientState.map); - - final List previousData = []; - for (int i = 0; i < min(data.length, offsetData.length); i++) { - previousData.add(ChartMoneyData(data[i].date, offsetData[i].amount)); - } - - series.add( - charts.Series( - domainFn: (ChartMoneyData chartData, _) => chartData.date, - measureFn: (ChartMoneyData chartData, _) => chartData.amount, - colorFn: (ChartMoneyData chartData, _) => - charts.MaterialPalette.gray.shadeDefault, - id: DashboardChart.PERIOD_PREVIOUS, - displayName: localization.previous, - data: previousData, - ), + data: dataGroup.rawSeries, ); - previousData.forEach((dynamic item) { - previousTotal += item.amount; - }); - } + if (settings.enableComparison) { + final offsetData = memoizedChartOutstandingInvoices( + state.selectedCompany, + settings.rebuild((b) => b..offset += 1), + state.invoiceState.map, + state.clientState.map); + + final List previousData = []; + for (int i = 0; + i < min(dataGroup.rawSeries.length, offsetData.length); + i++) { + previousData.add(ChartMoneyData(dataGroup.rawSeries[i].date, + offsetData[data.indexOf(dataGroup)].rawSeries[i].amount)); + } + + dataGroup.chartSeries.add( + charts.Series( + domainFn: (ChartMoneyData chartData, _) => chartData.date, + measureFn: (ChartMoneyData chartData, _) => chartData.amount, + colorFn: (ChartMoneyData chartData, _) => + charts.MaterialPalette.gray.shadeDefault, + id: DashboardChart.PERIOD_PREVIOUS, + displayName: localization.previous, + data: previousData, + ), + ); + } + }); return DashboardChart( - series: series, - amount: total, - previousAmount: previousTotal, + data: data, title: localization.invoices, currencyId: settings.currencyId > 0 ? settings.currencyId @@ -172,6 +163,7 @@ class DashboardPanels extends StatelessWidget { ); } + /* Widget _paymentChart(BuildContext context) { if (!viewModel.state.paymentState.isLoaded) { return LoadingIndicator(useCard: true); @@ -324,6 +316,7 @@ class DashboardPanels extends StatelessWidget { : state.selectedCompany.currencyId, ); } + */ @override Widget build(BuildContext context) { @@ -335,8 +328,8 @@ class DashboardPanels extends StatelessWidget { height: 74.0, ), _invoiceChart(context), - _paymentChart(context), - _quoteChart(context), + //_paymentChart(context), + //_quoteChart(context), ], ), ConstrainedBox(