Currency formatting

This commit is contained in:
unknown 2018-06-28 11:10:05 -07:00
parent 8225d49994
commit aff7eb0a73
4 changed files with 101 additions and 38 deletions

View File

@ -17,9 +17,12 @@ class InvoiceItemListTile extends StatelessWidget {
@override
Widget build(BuildContext context) {
String cost = formatNumber(invoiceItem.cost, state, clientId: invoice.clientId);
String qty = formatNumber(invoiceItem.qty, state, clientId: invoice.clientId, formatType: NumberFormatTypes.double);
return ListTile(
title: Text(invoiceItem.productKey),
subtitle: Text('${invoiceItem.qty} x ${invoiceItem.cost.toStringAsFixed(2)}\n${invoiceItem.notes}'),
subtitle: Text('${qty} x ${cost}\n${invoiceItem.notes}'),
trailing: Text(formatNumber(invoiceItem.total, state, clientId: invoice.clientId)),
);
}

View File

@ -1,3 +1,5 @@
import 'package:invoiceninja/redux/app/app_state.dart';
import 'package:invoiceninja/utils/formatting.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja/ui/app/app_loading.dart';
@ -16,14 +18,14 @@ class DashboardPanels extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AppLoading(builder: (context, loading) {
return ! viewModel.dashboardState.isLoaded
return !viewModel.dashboardState.isLoaded
? LoadingIndicator()
: _buildPanels(context);
});
}
Widget _buildPanels(BuildContext context) {
if (! viewModel.dashboardState.isLoaded) {
if (!viewModel.dashboardState.isLoaded) {
return LoadingIndicator();
}
@ -34,20 +36,44 @@ class DashboardPanels extends StatelessWidget {
child: ListView(
padding: EdgeInsets.only(left: 12.0, right: 12.0, top: 20.0),
children: <Widget>[
DashboardRow(localization.totalRevenue, Icons.show_chart,
viewModel.dashboardState.data.paidToDate, Color(0xFF117CC1)),
DashboardRow(
state: viewModel.state,
title: localization.totalRevenue,
color: Color(0xFF117CC1),
icon: Icons.show_chart,
amount: viewModel.dashboardState.data.paidToDate),
Row(
children: <Widget>[
DashboardColumn(localization.averageInvoice, Icons.email,
viewModel.dashboardState.data.averageInvoice, Color(0xFF44AF69)),
DashboardColumn(
localization.outstanding, Icons.schedule, viewModel.dashboardState.data.balances, Color(0xFFF8333C)),
amount: viewModel.dashboardState.data.averageInvoice,
icon: Icons.email,
color: Color(0xFF44AF69),
title: localization.averageInvoice,
state: viewModel.state,
),
DashboardColumn(
amount: viewModel.dashboardState.data.balances,
icon: Icons.schedule,
color: Color(0xFFF8333C),
title: localization.outstanding,
state: viewModel.state,
),
],
),
DashboardRow(localization.invoicesSent, Icons.send,
viewModel.dashboardState.data.invoicesSent, Color(0xFFFCAB10), false),
DashboardRow(localization.activeClients, Icons.people,
viewModel.dashboardState.data.activeClients, Color(0xFFDBD5B5), false),
DashboardRow(
state: viewModel.state,
title: localization.invoicesSent,
color: Color(0xFFFCAB10),
icon: Icons.send,
isMoney: false,
amount: viewModel.dashboardState.data.invoicesSent.toDouble()),
DashboardRow(
state: viewModel.state,
title: localization.activeClients,
color: Color(0xFFDBD5B5),
icon: Icons.people,
isMoney: false,
amount: viewModel.dashboardState.data.activeClients.toDouble()),
]),
);
}
@ -63,7 +89,11 @@ class ColorIcon extends StatelessWidget {
return Container(
width: 52.0,
height: 52.0,
child: Icon(this.icon, color: Colors.white, size: 30.0,),
child: Icon(
this.icon,
color: Colors.white,
size: 30.0,
),
decoration: new BoxDecoration(
shape: BoxShape.circle,
color: this.backgroundColor,
@ -75,8 +105,15 @@ class ColorIcon extends StatelessWidget {
}
class DashboardRow extends StatelessWidget {
DashboardRow(this.title, this.icon, this.amount, this.color, [this.isMoney = true]);
DashboardRow(
{@required this.state,
@required this.title,
@required this.icon,
@required this.amount,
@required this.color,
this.isMoney = true});
final AppState state;
final String title;
final IconData icon;
final num amount;
@ -86,24 +123,26 @@ class DashboardRow extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(top: 3.0, bottom: 3.0 ),
padding: EdgeInsets.only(top: 3.0, bottom: 3.0),
child: Card(
elevation: 2.0,
child: ListTile(
title: Padding(
padding: EdgeInsets.only(top: 12.0, bottom: 12.0 ),
padding: EdgeInsets.only(top: 12.0, bottom: 12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(this.title,
style: TextStyle()),
Text(this.isMoney
? "\$" + this.amount.toStringAsFixed(2)
: this.amount.toString(),
style: TextStyle(
fontSize: 26.0,
fontWeight: FontWeight.bold,
),)
Text(this.title, style: TextStyle()),
Text(
formatNumber(amount, state,
formatType: isMoney
? NumberFormatTypes.money
: NumberFormatTypes.int),
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
)
],
),
),
@ -114,10 +153,16 @@ class DashboardRow extends StatelessWidget {
}
}
class DashboardColumn extends StatelessWidget {
DashboardColumn(this.title, this.icon, this.amount, this.color, [this.isMoney = true]);
DashboardColumn(
{@required this.state,
@required this.title,
@required this.icon,
@required this.amount,
@required this.color,
this.isMoney = true});
final AppState state;
final String title;
final IconData icon;
final num amount;
@ -128,7 +173,7 @@ class DashboardColumn extends StatelessWidget {
Widget build(BuildContext context) {
return Expanded(
child: Padding(
padding: EdgeInsets.only(top: 3.0, bottom: 3.0 ),
padding: EdgeInsets.only(top: 3.0, bottom: 3.0),
child: Card(
elevation: 2.0,
child: Padding(
@ -138,15 +183,17 @@ class DashboardColumn extends StatelessWidget {
children: <Widget>[
Center(child: ColorIcon(this.icon, this.color)),
SizedBox(height: 18.0),
Text(this.title,
style: TextStyle()),
Text(this.isMoney
? "\$" + this.amount.toStringAsFixed(2)
: this.amount.toString(),
Text(this.title, style: TextStyle()),
Text(
formatNumber(amount, state,
formatType: isMoney
? NumberFormatTypes.money
: NumberFormatTypes.int),
style: TextStyle(
fontSize: 26.0,
fontSize: 20.0,
fontWeight: FontWeight.bold,
),)
),
)
],
),
),
@ -155,4 +202,3 @@ class DashboardColumn extends StatelessWidget {
);
}
}

View File

@ -29,11 +29,13 @@ class DashboardBuilder extends StatelessWidget {
}
class DashboardVM {
final AppState state;
final DashboardState dashboardState;
final bool isLoading;
final Function(BuildContext) onRefreshed;
DashboardVM({
@required this.state,
@required this.dashboardState,
@required this.isLoading,
@required this.onRefreshed,
@ -53,6 +55,7 @@ class DashboardVM {
}
return DashboardVM(
state: store.state,
dashboardState: store.state.dashboardState,
isLoading: store.state.isLoading,
onRefreshed: (context) => _handleRefresh(context),

View File

@ -8,6 +8,8 @@ import 'package:invoiceninja/redux/app/app_state.dart';
enum NumberFormatTypes {
money,
percent,
int,
double,
}
String formatNumber(double value, AppState state, {
@ -60,8 +62,17 @@ String formatNumber(double value, AppState state, {
MINUS_SIGN: '-',
);
var formatter = NumberFormat('#,##0.00##', 'custom');
String formatted = formatter.format(value);
var formatter;
String formatted;
if (formatType == NumberFormatTypes.int) {
return NumberFormat('#,##0', 'custom').format(value);
} else if (formatType == NumberFormatTypes.double) {
return NumberFormat('#,##0.####', 'custom').format(value);
} else {
formatter = NumberFormat('#,##0.00##', 'custom');
formatted = formatter.format(value);
}
if (formatType == NumberFormatTypes.percent) {
return '${formatted}%';