From c98d08f3f7d8ac0a4e59bae0eb4bea85ddfacabd Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 29 Nov 2023 15:08:29 +0200 Subject: [PATCH 01/11] Add more exports/reports --- lib/data/models/import_model.dart | 8 ++++++++ lib/data/models/import_model.g.dart | 29 +++++++++++++++++++++++++++++ lib/utils/i18n.dart | 6 ++++++ 3 files changed, 43 insertions(+) diff --git a/lib/data/models/import_model.dart b/lib/data/models/import_model.dart index f87edc565dd..f62dabdc917 100644 --- a/lib/data/models/import_model.dart +++ b/lib/data/models/import_model.dart @@ -201,6 +201,14 @@ class ExportType extends EnumClass { static const ExportType products = _$products; static const ExportType tasks = _$tasks; static const ExportType profitloss = _$profitloss; + static const ExportType aged_receivable_detailed_report = + _$aged_receivable_detailed_report; + static const ExportType aged_receivable_summary_report = + _$aged_receivable_summary_report; + static const ExportType client_balance_report = _$client_balance_report; + static const ExportType client_sales_report = _$client_sales_report; + static const ExportType tax_summary_report = _$tax_summary_report; + static const ExportType user_sales_report = _$user_sales_report; static BuiltSet get values => _$exportValues; diff --git a/lib/data/models/import_model.g.dart b/lib/data/models/import_model.g.dart index 3e9c79afa32..2085b103ba1 100644 --- a/lib/data/models/import_model.g.dart +++ b/lib/data/models/import_model.g.dart @@ -62,6 +62,17 @@ const ExportType _$payments = const ExportType._('payments'); const ExportType _$products = const ExportType._('products'); const ExportType _$tasks = const ExportType._('tasks'); const ExportType _$profitloss = const ExportType._('profitloss'); +const ExportType _$aged_receivable_detailed_report = + const ExportType._('aged_receivable_detailed_report'); +const ExportType _$aged_receivable_summary_report = + const ExportType._('aged_receivable_summary_report'); +const ExportType _$client_balance_report = + const ExportType._('client_balance_report'); +const ExportType _$client_sales_report = + const ExportType._('client_sales_report'); +const ExportType _$tax_summary_report = + const ExportType._('tax_summary_report'); +const ExportType _$user_sales_report = const ExportType._('user_sales_report'); ExportType _$exportValueOf(String name) { switch (name) { @@ -95,6 +106,18 @@ ExportType _$exportValueOf(String name) { return _$tasks; case 'profitloss': return _$profitloss; + case 'aged_receivable_detailed_report': + return _$aged_receivable_detailed_report; + case 'aged_receivable_summary_report': + return _$aged_receivable_summary_report; + case 'client_balance_report': + return _$client_balance_report; + case 'client_sales_report': + return _$client_sales_report; + case 'tax_summary_report': + return _$tax_summary_report; + case 'user_sales_report': + return _$user_sales_report; default: throw new ArgumentError(name); } @@ -117,6 +140,12 @@ final BuiltSet _$exportValues = _$products, _$tasks, _$profitloss, + _$aged_receivable_detailed_report, + _$aged_receivable_summary_report, + _$client_balance_report, + _$client_sales_report, + _$tax_summary_report, + _$user_sales_report, ]); Serializer _$preImportResponseSerializer = diff --git a/lib/utils/i18n.dart b/lib/utils/i18n.dart index b20bf58bc4b..6e824c41b62 100644 --- a/lib/utils/i18n.dart +++ b/lib/utils/i18n.dart @@ -18,6 +18,12 @@ mixin LocalizationsProvider on LocaleCodeAware { static final Map> _localizedValues = { 'en': { // STARTER: lang key - do not remove comment + 'aged_receivable_detailed_report': 'Aged Receivable Detailed Report', + 'aged_receivable_summary_report': 'Aged Receivable Summary Report', + 'client_balance_report': 'Client Balance Report', + 'client_sales_report': 'Client Sales Report', + 'tax_summary_report': 'Tax Summary Report', + 'user_sales_report': 'User Sales Report', 'run_template': 'Run Template', 'task_extension_banner': 'Add the Chrome extension to manage your tasks', 'watch_video': 'Watch Video', From 3eac18929bb8055c200d3c19a92139840babf8a4 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 29 Nov 2023 15:18:22 +0200 Subject: [PATCH 02/11] Fix entity actions on edit scaffold --- lib/ui/app/edit_scaffold.dart | 42 +++++++++++++++++------------------ 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/lib/ui/app/edit_scaffold.dart b/lib/ui/app/edit_scaffold.dart index d2f7899d423..ba7b9f7b365 100644 --- a/lib/ui/app/edit_scaffold.dart +++ b/lib/ui/app/edit_scaffold.dart @@ -433,30 +433,28 @@ class EditScaffold extends StatelessWidget { //size: iconSize, //color: color, ), - itemBuilder: (BuildContext context) => - >[ + itemBuilder: (BuildContext context) => [ ...actions! - .map((action) => action == null - ? PopupMenuDivider() - : PopupMenuItem( - child: Row( - children: [ - Icon( - getEntityActionIcon(action), - color: Theme.of(context) - .colorScheme - .secondary, - ), - SizedBox(width: 16.0), - Text(AppLocalization.of( - context)! - .lookup(action.toString())), - ], + .map((action) => action == null + ? PopupMenuDivider() + : PopupMenuItem( + child: Row( + children: [ + Icon( + getEntityActionIcon(action), + color: Theme.of(context) + .colorScheme + .secondary, ), - value: action, - )) - .toList() - as Iterable> + SizedBox(width: 16.0), + Text(AppLocalization.of(context)! + .lookup(action.toString())), + ], + ), + value: action, + )) + .whereType>() + .toList() ], onSelected: (action) => onActionPressed!(context, action), From 9e1e3db08c60c96f295eb5fd65168ce51969a5c1 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 29 Nov 2023 17:15:38 +0200 Subject: [PATCH 03/11] Add 'Insert below' option to invoice item line actions --- lib/redux/invoice/invoice_actions.dart | 6 +++++- lib/redux/invoice/invoice_reducer.dart | 6 +++++- lib/ui/invoice/edit/invoice_edit_items_desktop.dart | 3 +++ lib/ui/invoice/edit/invoice_edit_items_vm.dart | 11 ++++++++--- lib/utils/i18n.dart | 5 +++++ 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/lib/redux/invoice/invoice_actions.dart b/lib/redux/invoice/invoice_actions.dart index 6bdc3f7aa19..e07c762c6a9 100644 --- a/lib/redux/invoice/invoice_actions.dart +++ b/lib/redux/invoice/invoice_actions.dart @@ -172,9 +172,13 @@ class RemoveInvoiceContact implements PersistUI { } class AddInvoiceItem implements PersistUI { - AddInvoiceItem({this.invoiceItem}); + AddInvoiceItem({ + this.invoiceItem, + this.index, + }); final InvoiceItemEntity? invoiceItem; + final int? index; } class MoveInvoiceItem implements PersistUI { diff --git a/lib/redux/invoice/invoice_reducer.dart b/lib/redux/invoice/invoice_reducer.dart index a9d132d6e7b..d2b8da134bb 100644 --- a/lib/redux/invoice/invoice_reducer.dart +++ b/lib/redux/invoice/invoice_reducer.dart @@ -165,7 +165,11 @@ InvoiceEntity _updateEditing(InvoiceEntity? invoice, dynamic action) { InvoiceEntity _addInvoiceItem(InvoiceEntity? invoice, AddInvoiceItem action) { final item = action.invoiceItem ?? InvoiceItemEntity(); - return invoice!.rebuild((b) => b..lineItems.add(item)); + if (action.index == null) { + return invoice!.rebuild((b) => b..lineItems.add(item)); + } else { + return invoice!.rebuild((b) => b..lineItems.insert(action.index!, item)); + } } InvoiceEntity _addInvoiceItems(InvoiceEntity? invoice, AddInvoiceItems action) { diff --git a/lib/ui/invoice/edit/invoice_edit_items_desktop.dart b/lib/ui/invoice/edit/invoice_edit_items_desktop.dart index 0cca7b8f586..43e02c2ebf7 100644 --- a/lib/ui/invoice/edit/invoice_edit_items_desktop.dart +++ b/lib/ui/invoice/edit/invoice_edit_items_desktop.dart @@ -1192,6 +1192,7 @@ class _InvoiceEditItemsDesktopState extends State { final sectionIndex = includedLineItems.indexOf(lineItems[index]); final options = { + localization.insertBelow: MdiIcons.plus, if (widget.isTasks && (lineItems[index].taskId ?? '').isNotEmpty) localization.viewTask: MdiIcons.chevronDoubleRight, @@ -1232,6 +1233,8 @@ class _InvoiceEditItemsDesktopState extends State { index, lineItems.length - 2); } else if (action == localization.remove) { viewModel.onRemoveInvoiceItemPressed!(index); + } else if (action == localization.insertBelow) { + viewModel.addLineItem!(index + 1); } _updateTable(); }, diff --git a/lib/ui/invoice/edit/invoice_edit_items_vm.dart b/lib/ui/invoice/edit/invoice_edit_items_vm.dart index 1cbcede8bb7..02ea68d048e 100644 --- a/lib/ui/invoice/edit/invoice_edit_items_vm.dart +++ b/lib/ui/invoice/edit/invoice_edit_items_vm.dart @@ -79,7 +79,7 @@ class InvoiceEditItemsVM extends EntityEditItemsVM { CompanyEntity? company, InvoiceEntity? invoice, int? invoiceItemIndex, - Function? addLineItem, + Function([int])? addLineItem, Function(int)? deleteLineItem, Function(int)? onRemoveInvoiceItemPressed, Function? clearSelectedInvoiceItem, @@ -107,8 +107,13 @@ class InvoiceEditItemsVM extends EntityEditItemsVM { company: store.state.company, invoice: store.state.invoiceUIState.editing, invoiceItemIndex: store.state.invoiceUIState.editingItemIndex, - addLineItem: () { - store.dispatch(AddInvoiceItem(invoiceItem: InvoiceItemEntity())); + addLineItem: ([int? index]) { + store.dispatch(AddInvoiceItem( + index: index, + invoiceItem: InvoiceItemEntity().rebuild((b) => b + ..typeId = isTasks + ? InvoiceItemEntity.TYPE_TASK + : InvoiceItemEntity.TYPE_STANDARD))); }, deleteLineItem: null, onRemoveInvoiceItemPressed: (index) { diff --git a/lib/utils/i18n.dart b/lib/utils/i18n.dart index 6e824c41b62..75d49813b77 100644 --- a/lib/utils/i18n.dart +++ b/lib/utils/i18n.dart @@ -18,6 +18,7 @@ mixin LocalizationsProvider on LocaleCodeAware { static final Map> _localizedValues = { 'en': { // STARTER: lang key - do not remove comment + 'insert_below': 'Insert Below', 'aged_receivable_detailed_report': 'Aged Receivable Detailed Report', 'aged_receivable_summary_report': 'Aged Receivable Summary Report', 'client_balance_report': 'Client Balance Report', @@ -110947,6 +110948,10 @@ mixin LocalizationsProvider on LocaleCodeAware { _localizedValues[localeCode]!['run_template'] ?? _localizedValues['en']!['run_template']!; + String get insertBelow => + _localizedValues[localeCode]!['insert_below'] ?? + _localizedValues['en']!['insert_below']!; + // STARTER: lang field - do not remove comment String lookup(String? key) { From bbc4a2feb539fc35d7f3b31464b94b56304328e8 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 29 Nov 2023 17:28:42 +0200 Subject: [PATCH 04/11] Fix clearing expense client --- lib/ui/expense/edit/expense_edit_details.dart | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/ui/expense/edit/expense_edit_details.dart b/lib/ui/expense/edit/expense_edit_details.dart index 1e96550e2eb..5c0913ac2ec 100644 --- a/lib/ui/expense/edit/expense_edit_details.dart +++ b/lib/ui/expense/edit/expense_edit_details.dart @@ -176,11 +176,13 @@ class ExpenseEditDetailsState extends State { entityList: memoizedDropdownClientList(clientState.map, clientState.list, state.userState.map, state.staticState), onSelected: (client) { - final currencyId = - (client as ClientEntity).settings.currencyId ?? - company.currencyId; + String currencyId = ''; + if (client != null) { + currencyId = (client as ClientEntity).settings.currencyId ?? + company.currencyId; + } viewModel.onChanged!(expense.rebuild((b) => b - ..clientId = client.id + ..clientId = client?.id ?? '' ..invoiceCurrencyId = currencyId)); }, onAddPressed: (completer) { From 1d479a8d6a9e208dec4373636fd2ab06fdac2ef1 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 29 Nov 2023 17:50:01 +0200 Subject: [PATCH 05/11] Bug: showing bottom filter a second time fails --- lib/ui/app/app_bottom_bar.dart | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/lib/ui/app/app_bottom_bar.dart b/lib/ui/app/app_bottom_bar.dart index a6214d53589..30f10cda8cd 100644 --- a/lib/ui/app/app_bottom_bar.dart +++ b/lib/ui/app/app_bottom_bar.dart @@ -143,8 +143,7 @@ class _AppBottomBarState extends State { if (closeBottomSheet() == kFilterStatePanel) { return; } - _filterStateController = - Scaffold.of(context).showBottomSheet((context) { + _filterStateController = Scaffold.of(context).showBottomSheet((context) { return StoreConnector>( converter: (Store store) => store.state.getListState(widget.entityType).stateFilters, @@ -185,8 +184,7 @@ class _AppBottomBarState extends State { return; } - _filterStatusController = - Scaffold.of(context).showBottomSheet((context) { + _filterStatusController = Scaffold.of(context).showBottomSheet((context) { return StoreConnector>( converter: (Store store) => store.state.getListState(widget.entityType).statusFilters, @@ -226,8 +224,7 @@ class _AppBottomBarState extends State { return; } - _sortController = - Scaffold.of(context).showBottomSheet((context) { + _sortController = Scaffold.of(context).showBottomSheet((context) { return StoreConnector( //distinct: true, converter: (Store store) => @@ -284,7 +281,7 @@ class _AppBottomBarState extends State { } _filterCustom1Controller = - Scaffold.of(context).showBottomSheet((context) { + Scaffold.of(context).showBottomSheet((context) { return CustomFieldSelector( customNumber: 1, entityType: widget.entityType, @@ -304,7 +301,7 @@ class _AppBottomBarState extends State { return; } _filterCustom2Controller = - Scaffold.of(context).showBottomSheet((context) { + Scaffold.of(context).showBottomSheet((context) { return CustomFieldSelector( customNumber: 2, entityType: widget.entityType, @@ -325,7 +322,7 @@ class _AppBottomBarState extends State { } _filterCustom3Controller = - Scaffold.of(context).showBottomSheet((context) { + Scaffold.of(context).showBottomSheet((context) { return CustomFieldSelector( customNumber: 3, entityType: widget.entityType, @@ -346,7 +343,7 @@ class _AppBottomBarState extends State { } _filterCustom4Controller = - Scaffold.of(context).showBottomSheet((context) { + Scaffold.of(context).showBottomSheet((context) { return CustomFieldSelector( customNumber: 4, entityType: widget.entityType, From 18bf826f9ef90918756f43913af9becf64e99a69 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 30 Nov 2023 16:21:22 +0200 Subject: [PATCH 06/11] Adjustments to Chrome extension banner --- lib/ui/task/task_screen.dart | 4 +++- lib/utils/i18n.dart | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/ui/task/task_screen.dart b/lib/ui/task/task_screen.dart index 14b91ebcc33..1f8f09e0899 100644 --- a/lib/ui/task/task_screen.dart +++ b/lib/ui/task/task_screen.dart @@ -115,7 +115,8 @@ class TaskScreen extends StatelessWidget { Expanded( child: IconText( text: localization.taskExtensionBanner, - icon: Icons.info_outline, + icon: MdiIcons.googleChrome, + style: TextStyle(color: Colors.white), ), ), TextButton( @@ -142,6 +143,7 @@ class TaskScreen extends StatelessWidget { store.dispatch(DismissTaskExtensionBanner()); }, icon: Icon(Icons.clear), + color: Colors.white, ), SizedBox(width: 12), ], diff --git a/lib/utils/i18n.dart b/lib/utils/i18n.dart index 75d49813b77..c26120530d6 100644 --- a/lib/utils/i18n.dart +++ b/lib/utils/i18n.dart @@ -26,7 +26,8 @@ mixin LocalizationsProvider on LocaleCodeAware { 'tax_summary_report': 'Tax Summary Report', 'user_sales_report': 'User Sales Report', 'run_template': 'Run Template', - 'task_extension_banner': 'Add the Chrome extension to manage your tasks', + 'task_extension_banner': + 'Install the Chrome extension to manage tasks in your browser', 'watch_video': 'Watch Video', 'view_extension': 'View Extension', 'reactivate_email': 'Reactivate Email', From 9cd377746ab8b79a481315e7cd008a9ea7bf28bb Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 30 Nov 2023 16:45:08 +0200 Subject: [PATCH 07/11] Add PayPal Platform gateway --- lib/constants.dart | 1 + lib/ui/company_gateway/edit/company_gateway_edit.dart | 1 + lib/ui/company_gateway/edit/company_gateway_edit_vm.dart | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/lib/constants.dart b/lib/constants.dart index 7732bc8510f..a747df2c4e0 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -488,6 +488,7 @@ const String kGatewayStripeConnect = 'd14dd26a47cecc30fdd65700bfb67b34'; const String kGatewayAuthorizeNet = '3b6621f970ab18887c4f6dca78d3f8bb'; const String kGatewayCheckoutCom = '3758e7f7c6f4cecf0f4f348b9a00f456'; const String kGatewayPayPalExpress = '38f2c48af60c7dd69e04248cbb24c36e'; +const String kGatewayPayPalPlatform = '80af24a6a691230bbec33e930ab40666'; const String kGatewayWePay = '8fdeed552015b3c7b44ed6c8ebd9e992'; const String kGatewayCustom = '54faab2ab6e3223dbe848b1686490baa'; diff --git a/lib/ui/company_gateway/edit/company_gateway_edit.dart b/lib/ui/company_gateway/edit/company_gateway_edit.dart index e3a006dc942..1df7333e65b 100644 --- a/lib/ui/company_gateway/edit/company_gateway_edit.dart +++ b/lib/ui/company_gateway/edit/company_gateway_edit.dart @@ -104,6 +104,7 @@ class _CompanyGatewayEditState extends State final connectGateways = [ kGatewayStripeConnect, kGatewayWePay, + kGatewayPayPalPlatform, ]; final disableSave = (connectGateways.contains(companyGateway.gatewayId) && diff --git a/lib/ui/company_gateway/edit/company_gateway_edit_vm.dart b/lib/ui/company_gateway/edit/company_gateway_edit_vm.dart index ebb0ac89fbc..f971ee0e914 100644 --- a/lib/ui/company_gateway/edit/company_gateway_edit_vm.dart +++ b/lib/ui/company_gateway/edit/company_gateway_edit_vm.dart @@ -153,6 +153,10 @@ class CompanyGatewayEditVM { launchUrl(Uri.parse( '${cleanApiUrl(credentials.url)}/wepay/signup/${response['hash']}')); break; + case kGatewayPayPalPlatform: + launchUrl(Uri.parse( + '${cleanApiUrl(credentials.url)}/paypal/signup/${response['hash']}')); + break; } }).catchError((dynamic error) { store.dispatch(StopSaving()); From ca758848489306572d681a664654da5044f6ff04 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 30 Nov 2023 18:05:48 +0200 Subject: [PATCH 08/11] Add paymentEmailAllContacts to settings model --- lib/data/models/settings_model.dart | 3 +++ lib/data/models/settings_model.g.dart | 32 +++++++++++++++++++++++---- lib/ui/settings/payment_settings.dart | 12 ++++++++++ lib/utils/i18n.dart | 16 ++++++++++++++ 4 files changed, 59 insertions(+), 4 deletions(-) diff --git a/lib/data/models/settings_model.dart b/lib/data/models/settings_model.dart index e7a0c3d0ef0..bd291a15198 100644 --- a/lib/data/models/settings_model.dart +++ b/lib/data/models/settings_model.dart @@ -811,6 +811,9 @@ abstract class SettingsEntity String? get classification; + @BuiltValueField(wireName: 'payment_email_all_contacts') + bool? get paymentEmailAllContacts; + bool get hasAddress => address1 != null && address1!.isNotEmpty; bool get hasLogo => companyLogo != null && companyLogo!.isNotEmpty; diff --git a/lib/data/models/settings_model.g.dart b/lib/data/models/settings_model.g.dart index 54822b1bfa8..9b46e5b180a 100644 --- a/lib/data/models/settings_model.g.dart +++ b/lib/data/models/settings_model.g.dart @@ -1571,6 +1571,13 @@ class _$SettingsEntitySerializer ..add(serializers.serialize(value, specifiedType: const FullType(String))); } + value = object.paymentEmailAllContacts; + if (value != null) { + result + ..add('payment_email_all_contacts') + ..add( + serializers.serialize(value, specifiedType: const FullType(bool))); + } return result; } @@ -2485,6 +2492,10 @@ class _$SettingsEntitySerializer result.classification = serializers.deserialize(value, specifiedType: const FullType(String)) as String?; break; + case 'payment_email_all_contacts': + result.paymentEmailAllContacts = serializers.deserialize(value, + specifiedType: const FullType(bool)) as bool?; + break; } } @@ -3010,6 +3021,8 @@ class _$SettingsEntity extends SettingsEntity { final String? defaultExpensePaymentTypeId; @override final String? classification; + @override + final bool? paymentEmailAllContacts; factory _$SettingsEntity([void Function(SettingsEntityBuilder)? updates]) => (new SettingsEntityBuilder()..update(updates))._build(); @@ -3237,7 +3250,8 @@ class _$SettingsEntity extends SettingsEntity { this.enableEInvoice, this.eInvoiceType, this.defaultExpensePaymentTypeId, - this.classification}) + this.classification, + this.paymentEmailAllContacts}) : super._(); @override @@ -3479,7 +3493,8 @@ class _$SettingsEntity extends SettingsEntity { enableEInvoice == other.enableEInvoice && eInvoiceType == other.eInvoiceType && defaultExpensePaymentTypeId == other.defaultExpensePaymentTypeId && - classification == other.classification; + classification == other.classification && + paymentEmailAllContacts == other.paymentEmailAllContacts; } int? __hashCode; @@ -3710,6 +3725,7 @@ class _$SettingsEntity extends SettingsEntity { _$hash = $jc(_$hash, eInvoiceType.hashCode); _$hash = $jc(_$hash, defaultExpensePaymentTypeId.hashCode); _$hash = $jc(_$hash, classification.hashCode); + _$hash = $jc(_$hash, paymentEmailAllContacts.hashCode); _$hash = $jf(_$hash); return __hashCode ??= _$hash; } @@ -3944,7 +3960,8 @@ class _$SettingsEntity extends SettingsEntity { ..add('enableEInvoice', enableEInvoice) ..add('eInvoiceType', eInvoiceType) ..add('defaultExpensePaymentTypeId', defaultExpensePaymentTypeId) - ..add('classification', classification)) + ..add('classification', classification) + ..add('paymentEmailAllContacts', paymentEmailAllContacts)) .toString(); } } @@ -5055,6 +5072,11 @@ class SettingsEntityBuilder set classification(String? classification) => _$this._classification = classification; + bool? _paymentEmailAllContacts; + bool? get paymentEmailAllContacts => _$this._paymentEmailAllContacts; + set paymentEmailAllContacts(bool? paymentEmailAllContacts) => + _$this._paymentEmailAllContacts = paymentEmailAllContacts; + SettingsEntityBuilder(); SettingsEntityBuilder get _$this { @@ -5283,6 +5305,7 @@ class SettingsEntityBuilder _eInvoiceType = $v.eInvoiceType; _defaultExpensePaymentTypeId = $v.defaultExpensePaymentTypeId; _classification = $v.classification; + _paymentEmailAllContacts = $v.paymentEmailAllContacts; _$v = null; } return this; @@ -5530,7 +5553,8 @@ class SettingsEntityBuilder enableEInvoice: enableEInvoice, eInvoiceType: eInvoiceType, defaultExpensePaymentTypeId: defaultExpensePaymentTypeId, - classification: classification); + classification: classification, + paymentEmailAllContacts: paymentEmailAllContacts); } catch (_) { late String _$failedField; try { diff --git a/lib/ui/settings/payment_settings.dart b/lib/ui/settings/payment_settings.dart index f0aaf137b45..4e1791dde29 100644 --- a/lib/ui/settings/payment_settings.dart +++ b/lib/ui/settings/payment_settings.dart @@ -295,6 +295,18 @@ class _PaymentSettingsState extends State { helpLabel: localization.markPaidPaymentEmailHelp, iconData: Icons.email, ), + if (!state.settingsUIState.isFiltered) SizedBox(height: 10), + BoolDropdownButton( + value: state.settingsUIState.isFiltered + ? settings.paymentEmailAllContacts + : settings.paymentEmailAllContacts ?? false, + onChanged: (value) => viewModel.onSettingsChanged(settings + .rebuild((b) => b..paymentEmailAllContacts = value)), + label: localization.sendEmailTo, + iconData: Icons.email, + enabledLabel: localization.primaryContact, + disabledLabel: localization.allContacts, + ), ], ) ], diff --git a/lib/utils/i18n.dart b/lib/utils/i18n.dart index c26120530d6..8e9a739e4dd 100644 --- a/lib/utils/i18n.dart +++ b/lib/utils/i18n.dart @@ -18,6 +18,9 @@ mixin LocalizationsProvider on LocaleCodeAware { static final Map> _localizedValues = { 'en': { // STARTER: lang key - do not remove comment + 'send_email_to': 'Send Email To', + 'primary_contact': 'Primary Contact', + 'all_contacts': 'All Contacts', 'insert_below': 'Insert Below', 'aged_receivable_detailed_report': 'Aged Receivable Detailed Report', 'aged_receivable_summary_report': 'Aged Receivable Summary Report', @@ -110953,6 +110956,19 @@ mixin LocalizationsProvider on LocaleCodeAware { _localizedValues[localeCode]!['insert_below'] ?? _localizedValues['en']!['insert_below']!; + String get primaryContact => + _localizedValues[localeCode]!['primary_contact'] ?? + _localizedValues['en']!['primary_contact']!; + + String get allContacts => + _localizedValues[localeCode]!['all_contacts'] ?? + _localizedValues['en']!['all_contacts']!; + + String get sendEmailTo => + _localizedValues[localeCode]!['send_email_to'] ?? + _localizedValues['en']!['send_email_to']!; + + // STARTER: lang field - do not remove comment String lookup(String? key) { From 00ffc3fc414db38e7f4788213de3c2cb96217a51 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 30 Nov 2023 18:10:58 +0200 Subject: [PATCH 09/11] Add paymentEmailAllContacts to settings model --- lib/ui/settings/payment_settings.dart | 2 +- lib/ui/settings/settings_list.dart | 1 + lib/utils/i18n.dart | 9 ++++----- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/ui/settings/payment_settings.dart b/lib/ui/settings/payment_settings.dart index 4e1791dde29..d1b76a870c4 100644 --- a/lib/ui/settings/payment_settings.dart +++ b/lib/ui/settings/payment_settings.dart @@ -302,7 +302,7 @@ class _PaymentSettingsState extends State { : settings.paymentEmailAllContacts ?? false, onChanged: (value) => viewModel.onSettingsChanged(settings .rebuild((b) => b..paymentEmailAllContacts = value)), - label: localization.sendEmailTo, + label: localization.sendEmailsTo, iconData: Icons.email, enabledLabel: localization.primaryContact, disabledLabel: localization.allContacts, diff --git a/lib/ui/settings/settings_list.dart b/lib/ui/settings/settings_list.dart index 1c95a9940dc..4a22cc3f062 100644 --- a/lib/ui/settings/settings_list.dart +++ b/lib/ui/settings/settings_list.dart @@ -422,6 +422,7 @@ class SettingsSearch extends StatelessWidget { 'allow_under_payment', 'auto_bill_standard_invoices#2023-01-17', 'client_initiated_payments#2023-03-20', + 'send_emails_to#2023-11-30', ] ], kSettingsTaxSettings: [ diff --git a/lib/utils/i18n.dart b/lib/utils/i18n.dart index 8e9a739e4dd..cf7de56f2fe 100644 --- a/lib/utils/i18n.dart +++ b/lib/utils/i18n.dart @@ -18,7 +18,7 @@ mixin LocalizationsProvider on LocaleCodeAware { static final Map> _localizedValues = { 'en': { // STARTER: lang key - do not remove comment - 'send_email_to': 'Send Email To', + 'send_emails_to': 'Send Emails To', 'primary_contact': 'Primary Contact', 'all_contacts': 'All Contacts', 'insert_below': 'Insert Below', @@ -110964,10 +110964,9 @@ mixin LocalizationsProvider on LocaleCodeAware { _localizedValues[localeCode]!['all_contacts'] ?? _localizedValues['en']!['all_contacts']!; - String get sendEmailTo => - _localizedValues[localeCode]!['send_email_to'] ?? - _localizedValues['en']!['send_email_to']!; - + String get sendEmailsTo => + _localizedValues[localeCode]!['send_emails_to'] ?? + _localizedValues['en']!['send_emails_to']!; // STARTER: lang field - do not remove comment From fe0678cbbf97aa2e7264675a82f12fcc57f8d433 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 30 Nov 2023 18:12:53 +0200 Subject: [PATCH 10/11] Disable Impeller on iOS --- ios/Runner/Info.plist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index df37f89767d..f9c521d614e 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -70,5 +70,7 @@ UIApplicationSupportsIndirectInputEvents + FLTEnableImpeller + From 78f50d33f0ad3d2eb53bf4fd927f276193e3c75a Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 30 Nov 2023 18:14:28 +0200 Subject: [PATCH 11/11] Update version --- .github/workflows/flatpak.yml | 2 +- flatpak/com.invoiceninja.InvoiceNinja.metainfo.xml | 1 + lib/constants.dart | 2 +- pubspec.foss.yaml | 2 +- pubspec.yaml | 2 +- snap/snapcraft.yaml | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index e49fded9e81..c6681226713 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -86,7 +86,7 @@ jobs: draft: false prerelease: false title: "Latest Release" - automatic_release_tag: "v5.0.142" + automatic_release_tag: "v5.0.143" files: | ${{ github.workspace }}/artifacts/Invoice-Ninja-Archive ${{ github.workspace }}/artifacts/Invoice-Ninja-Hash diff --git a/flatpak/com.invoiceninja.InvoiceNinja.metainfo.xml b/flatpak/com.invoiceninja.InvoiceNinja.metainfo.xml index 992653a24af..e0c4bd2238d 100644 --- a/flatpak/com.invoiceninja.InvoiceNinja.metainfo.xml +++ b/flatpak/com.invoiceninja.InvoiceNinja.metainfo.xml @@ -50,6 +50,7 @@ + diff --git a/lib/constants.dart b/lib/constants.dart index a747df2c4e0..c358aa92c45 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -4,7 +4,7 @@ class Constants { } // TODO remove version once #46609 is fixed -const String kClientVersion = '5.0.142'; +const String kClientVersion = '5.0.143'; const String kMinServerVersion = '5.0.4'; const String kAppName = 'Invoice Ninja'; diff --git a/pubspec.foss.yaml b/pubspec.foss.yaml index 260b9bb0bb5..1f238717fb4 100644 --- a/pubspec.foss.yaml +++ b/pubspec.foss.yaml @@ -1,6 +1,6 @@ name: invoiceninja_flutter description: Client for Invoice Ninja -version: 5.0.142+142 +version: 5.0.143+143 homepage: https://invoiceninja.com documentation: https://invoiceninja.github.io publish_to: none diff --git a/pubspec.yaml b/pubspec.yaml index 1d1284e6019..b8d90cc2437 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: invoiceninja_flutter description: Client for Invoice Ninja -version: 5.0.142+142 +version: 5.0.143+143 homepage: https://invoiceninja.com documentation: https://invoiceninja.github.io publish_to: none diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index de896e3aaea..605e1e9681f 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,5 +1,5 @@ name: invoiceninja -version: '5.0.142' +version: '5.0.143' summary: Create invoices, accept payments, track expenses & time tasks description: "### Note: if the app fails to run using `snap run invoiceninja` it may help to run `/snap/invoiceninja/current/bin/invoiceninja` instead