Correct rounding
This commit is contained in:
parent
72d67e3780
commit
d078276d1a
|
|
@ -1251,7 +1251,7 @@ abstract class InvoiceItemEntity
|
||||||
if (rate == 0) {
|
if (rate == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
final lineTotal = total(invoice);
|
final lineTotal = total(invoice, precision);
|
||||||
if (invoice.usesInclusiveTaxes) {
|
if (invoice.usesInclusiveTaxes) {
|
||||||
taxAmount = lineTotal - (lineTotal / (1 + (rate / 100)));
|
taxAmount = lineTotal - (lineTotal / (1 + (rate / 100)));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1266,9 +1266,9 @@ abstract class InvoiceItemEntity
|
||||||
}
|
}
|
||||||
|
|
||||||
double netTotal(InvoiceEntity invoice, int precision) =>
|
double netTotal(InvoiceEntity invoice, int precision) =>
|
||||||
total(invoice) - taxAmount(invoice, precision);
|
total(invoice, precision) - taxAmount(invoice, precision);
|
||||||
|
|
||||||
double total(InvoiceEntity invoice) {
|
double total(InvoiceEntity invoice, int precision) {
|
||||||
var total = quantity * cost;
|
var total = quantity * cost;
|
||||||
|
|
||||||
if (discount != 0) {
|
if (discount != 0) {
|
||||||
|
|
@ -1279,7 +1279,7 @@ abstract class InvoiceItemEntity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return round(total, 2);
|
return round(total, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get isTask => typeId == TYPE_TASK;
|
bool get isTask => typeId == TYPE_TASK;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
import 'package:invoiceninja_flutter/data/models/entities.dart';
|
import 'package:invoiceninja_flutter/data/models/entities.dart';
|
||||||
|
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/app/lists/list_divider.dart';
|
import 'package:invoiceninja_flutter/ui/app/lists/list_divider.dart';
|
||||||
import 'package:invoiceninja_flutter/utils/formatting.dart';
|
import 'package:invoiceninja_flutter/utils/formatting.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
@ -24,6 +26,12 @@ class InvoiceItemListTile extends StatelessWidget {
|
||||||
clientId: invoice.clientId, formatNumberType: FormatNumberType.double);
|
clientId: invoice.clientId, formatNumberType: FormatNumberType.double);
|
||||||
final localization = AppLocalization.of(context);
|
final localization = AppLocalization.of(context);
|
||||||
|
|
||||||
|
final store = StoreProvider.of<AppState>(context);
|
||||||
|
final state = store.state;
|
||||||
|
final client = state.clientState.get(invoice.clientId);
|
||||||
|
final precision =
|
||||||
|
state.staticState.currencyMap[client.currencyId].precision;
|
||||||
|
|
||||||
String subtitle = '$qty x $cost';
|
String subtitle = '$qty x $cost';
|
||||||
|
|
||||||
if (invoiceItem.discount != 0) {
|
if (invoiceItem.discount != 0) {
|
||||||
|
|
@ -99,7 +107,8 @@ class InvoiceItemListTile extends StatelessWidget {
|
||||||
title: Row(
|
title: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(child: Text(invoiceItem.productKey)),
|
Expanded(child: Text(invoiceItem.productKey)),
|
||||||
Text(formatNumber(invoiceItem.total(invoice), context,
|
Text(formatNumber(
|
||||||
|
invoiceItem.total(invoice, precision), context,
|
||||||
clientId: invoice.clientId)),
|
clientId: invoice.clientId)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,11 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
|
||||||
final viewModel = widget.viewModel;
|
final viewModel = widget.viewModel;
|
||||||
final state = viewModel.state;
|
final state = viewModel.state;
|
||||||
final company = state.company;
|
final company = state.company;
|
||||||
|
|
||||||
final invoice = viewModel.invoice;
|
final invoice = viewModel.invoice;
|
||||||
|
final client = state.clientState.get(invoice.clientId);
|
||||||
|
final precision =
|
||||||
|
state.staticState.currencyMap[client.currencyId]?.precision ?? 2;
|
||||||
final lineItems = invoice.lineItems.toList();
|
final lineItems = invoice.lineItems.toList();
|
||||||
final includedLineItems = lineItems.where((lineItem) {
|
final includedLineItems = lineItems.where((lineItem) {
|
||||||
return (lineItem.typeId == InvoiceItemEntity.TYPE_TASK &&
|
return (lineItem.typeId == InvoiceItemEntity.TYPE_TASK &&
|
||||||
|
|
@ -687,11 +691,11 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
|
||||||
padding: const EdgeInsets.only(right: kTableColumnGap),
|
padding: const EdgeInsets.only(right: kTableColumnGap),
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
key: ValueKey(
|
key: ValueKey(
|
||||||
'__total_${index}_${lineItems[index].total(invoice)}_${invoice.clientId}__'),
|
'__total_${index}_${lineItems[index].total(invoice, precision)}_${invoice.clientId}__'),
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
enabled: false,
|
enabled: false,
|
||||||
initialValue: formatNumber(
|
initialValue: formatNumber(
|
||||||
lineItems[index].total(invoice), context,
|
lineItems[index].total(invoice, precision), context,
|
||||||
clientId: invoice.clientId),
|
clientId: invoice.clientId),
|
||||||
textAlign: TextAlign.right,
|
textAlign: TextAlign.right,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ ReportResult lineItemReport(
|
||||||
value = lineItem.notes;
|
value = lineItem.notes;
|
||||||
break;
|
break;
|
||||||
case InvoiceItemReportFields.total:
|
case InvoiceItemReportFields.total:
|
||||||
value = lineItem.total(invoice);
|
value = lineItem.total(invoice, precision);
|
||||||
break;
|
break;
|
||||||
case InvoiceItemReportFields.productKey:
|
case InvoiceItemReportFields.productKey:
|
||||||
value = lineItem.productKey;
|
value = lineItem.productKey;
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ ReportResult lineItemReport(
|
||||||
value = lineItem.notes;
|
value = lineItem.notes;
|
||||||
break;
|
break;
|
||||||
case QuoteItemReportFields.total:
|
case QuoteItemReportFields.total:
|
||||||
value = lineItem.total(invoice);
|
value = lineItem.total(invoice, precision);
|
||||||
break;
|
break;
|
||||||
case QuoteItemReportFields.productKey:
|
case QuoteItemReportFields.productKey:
|
||||||
value = lineItem.productKey;
|
value = lineItem.productKey;
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,17 @@ import 'package:invoiceninja_flutter/redux/company/company_selectors.dart';
|
||||||
import 'package:invoiceninja_flutter/utils/localization.dart';
|
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||||
|
|
||||||
double round(double value, int precision) {
|
double round(double value, int precision) {
|
||||||
|
var rounded = value;
|
||||||
|
|
||||||
|
// Workaround for floating point issues
|
||||||
|
if ('$value'.contains('9999999')) {
|
||||||
|
rounded = _round(value, precision + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _round(rounded, precision);
|
||||||
|
}
|
||||||
|
|
||||||
|
double _round(double value, int precision) {
|
||||||
if (value == null || value.isNaN) {
|
if (value == null || value.isNaN) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue