Added exchange rate
This commit is contained in:
parent
92a7d72d5f
commit
a10a2f90c4
|
|
@ -159,7 +159,7 @@ abstract class InvoiceEntity extends Object
|
|||
reminder2Sent: '',
|
||||
reminder3Sent: '',
|
||||
reminderLastSent: '',
|
||||
exchangeRate: 0,
|
||||
exchangeRate: 1,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -636,6 +636,8 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
|
|||
//return '${clientState.map[clientUIState.selectedId].gatewayTokens}';
|
||||
//return 'gatewayId: ${companyGatewayState.map[companyGatewayUIState.selectedId].gatewayId}';
|
||||
//return 'Language Id: ${company.settings.languageId}';
|
||||
//return 'Rates: ${staticState.currencyMap.keys.map((key) => 'Rate: ${staticState.currencyMap[key].exchangeRate}').join(',')}';
|
||||
return 'Client ID: ${invoiceUIState?.editing?.clientId ?? 'NULL'}';
|
||||
return '\n\nURL: ${authState.url}\nRoute: ${uiState.currentRoute}\nPrev: ${uiState.previousRoute}\nIs Loaded: ${isLoaded ? 'Yes' : 'No'}\nis Large: ${(company?.isLarge ?? false) ? 'Yes' : 'No'}\nCompany: $companyUpdated${userCompanyState.isStale ? ' [S]' : ''}\nStatic: $staticUpdated${staticState.isStale ? ' [S]' : ''}\n';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,14 @@ abstract class GroupState implements Built<GroupState, GroupStateBuilder> {
|
|||
@memoized
|
||||
int get hashCode;
|
||||
|
||||
GroupEntity get(String groupId) {
|
||||
if (map.containsKey(groupId)) {
|
||||
return map[groupId];
|
||||
} else {
|
||||
return GroupEntity(id: groupId);
|
||||
}
|
||||
}
|
||||
|
||||
BuiltMap<String, GroupEntity> get map;
|
||||
BuiltList<String> get list;
|
||||
|
||||
|
|
|
|||
|
|
@ -72,15 +72,21 @@ class CreditEditDetailsVM extends EntityEditDetailsVM {
|
|||
factory CreditEditDetailsVM.fromStore(Store<AppState> store) {
|
||||
final AppState state = store.state;
|
||||
final credit = state.creditUIState.editing;
|
||||
final company = state.company;
|
||||
|
||||
return CreditEditDetailsVM(
|
||||
state: state,
|
||||
company: state.company,
|
||||
company: company,
|
||||
invoice: credit,
|
||||
onChanged: (InvoiceEntity credit) => store.dispatch(UpdateCredit(credit)),
|
||||
clientMap: state.clientState.map,
|
||||
clientList: state.clientState.list,
|
||||
onClientChanged: (invoice, client) {
|
||||
if (company.convertProductExchangeRate && client != null) {
|
||||
store.dispatch(UpdateCredit(credit.rebuild((b) => b
|
||||
..exchangeRate = state
|
||||
.staticState.currencyMap[client.currencyId].exchangeRate)));
|
||||
}
|
||||
store.dispatch(UpdateCreditClient(client: client));
|
||||
},
|
||||
onAddClientPressed: (context, completer) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import 'package:flutter/foundation.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:invoiceninja_flutter/constants.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/client_model.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/entities.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/forms/app_tab_bar.dart';
|
||||
|
|
@ -62,7 +63,6 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
|
|||
final _privateNotesController = TextEditingController();
|
||||
final _termsController = TextEditingController();
|
||||
final _footerController = TextEditingController();
|
||||
final _exchangeRateController = TextEditingController();
|
||||
|
||||
List<TextEditingController> _controllers = [];
|
||||
final _debouncer = Debouncer();
|
||||
|
|
@ -94,7 +94,6 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
|
|||
_privateNotesController,
|
||||
_termsController,
|
||||
_footerController,
|
||||
_exchangeRateController,
|
||||
];
|
||||
|
||||
_controllers
|
||||
|
|
@ -123,8 +122,6 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
|
|||
_privateNotesController.text = invoice.privateNotes;
|
||||
_termsController.text = invoice.terms;
|
||||
_footerController.text = invoice.footer;
|
||||
_exchangeRateController.text = formatNumber(invoice.exchangeRate, context,
|
||||
formatNumberType: FormatNumberType.input);
|
||||
|
||||
_controllers
|
||||
.forEach((dynamic controller) => controller.addListener(_onChanged));
|
||||
|
|
@ -162,8 +159,7 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
|
|||
..publicNotes = _publicNotesController.text.trim()
|
||||
..privateNotes = _privateNotesController.text.trim()
|
||||
..terms = _termsController.text.trim()
|
||||
..footer = _footerController.text.trim()
|
||||
..exchangeRate = parseDouble(_exchangeRateController.text));
|
||||
..footer = _footerController.text.trim());
|
||||
if (invoice != widget.viewModel.invoice) {
|
||||
widget.viewModel.onChanged(invoice);
|
||||
}
|
||||
|
|
@ -201,8 +197,20 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
|
|||
autofocus: kIsWeb,
|
||||
clientId: invoice.clientId,
|
||||
clientState: viewModel.state.clientState,
|
||||
onSelected: (client) =>
|
||||
viewModel.onClientChanged(invoice, client),
|
||||
onSelected: (client) {
|
||||
viewModel.onClientChanged(invoice, client);
|
||||
/*
|
||||
final currencyId = (client as ClientEntity)?.currencyId;
|
||||
if (company.convertProductExchangeRate &&
|
||||
client != null) {
|
||||
_exchangeRateController.text = formatNumber(
|
||||
viewModel.state.staticState
|
||||
.currencyMap[currencyId].exchangeRate,
|
||||
context,
|
||||
formatNumberType: FormatNumberType.input);
|
||||
}
|
||||
*/
|
||||
},
|
||||
onAddPressed: (completer) =>
|
||||
viewModel.onAddClientPressed(context, completer),
|
||||
)
|
||||
|
|
@ -441,8 +449,16 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
|
|||
children: [
|
||||
Expanded(
|
||||
child: DecoratedFormField(
|
||||
key: ValueKey('__rate_${invoice.clientId}__'),
|
||||
label: localization.exchangeRate,
|
||||
controller: _exchangeRateController,
|
||||
initialValue: formatNumber(
|
||||
invoice.exchangeRate, context,
|
||||
formatNumberType:
|
||||
FormatNumberType.input),
|
||||
onChanged: (value) => viewModel.onChanged(
|
||||
invoice.rebuild((b) => b
|
||||
..exchangeRate =
|
||||
parseDouble(value))),
|
||||
keyboardType:
|
||||
TextInputType.numberWithOptions(
|
||||
decimal: true),
|
||||
|
|
@ -534,6 +550,7 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
|
|||
decoration: InputDecoration(
|
||||
labelText: localization.total,
|
||||
),
|
||||
textAlign: TextAlign.end,
|
||||
key: ValueKey(
|
||||
'__invoice_total_${invoiceTotal}_${invoice.clientId}__'),
|
||||
initialValue: formatNumber(invoiceTotal, context,
|
||||
|
|
|
|||
|
|
@ -91,16 +91,23 @@ class InvoiceEditDetailsVM extends EntityEditDetailsVM {
|
|||
factory InvoiceEditDetailsVM.fromStore(Store<AppState> store) {
|
||||
final AppState state = store.state;
|
||||
final invoice = state.invoiceUIState.editing;
|
||||
final company = state.company;
|
||||
|
||||
return InvoiceEditDetailsVM(
|
||||
state: state,
|
||||
company: state.company,
|
||||
company: company,
|
||||
invoice: invoice,
|
||||
onChanged: (InvoiceEntity invoice) =>
|
||||
store.dispatch(UpdateInvoice(invoice)),
|
||||
clientMap: state.clientState.map,
|
||||
clientList: state.clientState.list,
|
||||
onClientChanged: (invoice, client) {
|
||||
print('## onClientChanged: ${client?.id}');
|
||||
if (company.convertProductExchangeRate && client != null) {
|
||||
store.dispatch(UpdateInvoice(invoice.rebuild((b) => b
|
||||
..exchangeRate = state
|
||||
.staticState.currencyMap[client.currencyId].exchangeRate)));
|
||||
}
|
||||
store.dispatch(UpdateInvoiceClient(client: client));
|
||||
},
|
||||
onAddClientPressed: (context, completer) {
|
||||
|
|
|
|||
|
|
@ -228,6 +228,9 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
|
|||
final item = lineItems[index];
|
||||
final product = productState.map[suggestion];
|
||||
final client = state.clientState.get(invoice.clientId);
|
||||
final currencyId = client.getCurrencyId(
|
||||
company: company,
|
||||
group: state.groupState.get(client.groupId));
|
||||
|
||||
double cost = product.price;
|
||||
if (company.convertProductExchangeRate &&
|
||||
|
|
@ -239,7 +242,7 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
|
|||
toCurrencyId: client.currencyId);
|
||||
cost = round(
|
||||
cost,
|
||||
state.staticState.currencyMap[client.currencyId]
|
||||
state.staticState.currencyMap[currencyId]
|
||||
.precision);
|
||||
}
|
||||
|
||||
|
|
@ -428,7 +431,7 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
|
|||
padding: const EdgeInsets.only(right: kTableColumnGap),
|
||||
child: TextFormField(
|
||||
key: ValueKey(
|
||||
'__total_${index}_${lineItems[index].total}__'),
|
||||
'__total_${index}_${lineItems[index].total}_${invoice.clientId}__'),
|
||||
readOnly: true,
|
||||
enabled: false,
|
||||
initialValue: formatNumber(
|
||||
|
|
|
|||
|
|
@ -71,15 +71,21 @@ class QuoteEditDetailsVM extends EntityEditDetailsVM {
|
|||
factory QuoteEditDetailsVM.fromStore(Store<AppState> store) {
|
||||
final AppState state = store.state;
|
||||
final quote = state.quoteUIState.editing;
|
||||
final company = state.company;
|
||||
|
||||
return QuoteEditDetailsVM(
|
||||
state: state,
|
||||
company: state.company,
|
||||
company: company,
|
||||
invoice: quote,
|
||||
onChanged: (InvoiceEntity quote) => store.dispatch(UpdateQuote(quote)),
|
||||
clientMap: state.clientState.map,
|
||||
clientList: state.clientState.list,
|
||||
onClientChanged: (invoice, client) {
|
||||
onClientChanged: (quote, client) {
|
||||
if (company.convertProductExchangeRate && client != null) {
|
||||
store.dispatch(UpdateQuote(quote.rebuild((b) => b
|
||||
..exchangeRate = state
|
||||
.staticState.currencyMap[client.currencyId].exchangeRate)));
|
||||
}
|
||||
store.dispatch(UpdateQuoteClient(client: client));
|
||||
},
|
||||
onAddClientPressed: (context, completer) {
|
||||
|
|
|
|||
|
|
@ -107,6 +107,8 @@ String formatNumber(
|
|||
return '';
|
||||
}
|
||||
|
||||
print('## Formatting... CLIENT: ${client?.name}, CURRENCY: ${currency.name}');
|
||||
|
||||
if (formatNumberType == FormatNumberType.money) {
|
||||
value = round(value, currency.precision);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@ double getExchangeRate(BuildContext context,
|
|||
|
||||
double getExchangeRateWithMap(BuiltMap<String, CurrencyEntity> currencyMap,
|
||||
{String fromCurrencyId, String toCurrencyId}) {
|
||||
if (fromCurrencyId == null || toCurrencyId == null) {
|
||||
return 1;
|
||||
}
|
||||
final fromCurrency = currencyMap[fromCurrencyId];
|
||||
final toCurrency = currencyMap[toCurrencyId];
|
||||
// TODO replace with data from server
|
||||
|
|
|
|||
Loading…
Reference in New Issue