From d8e1cca2a45d7d8173ddff69d11ddc96a654eab6 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Sun, 20 Nov 2022 17:44:37 +0200 Subject: [PATCH] Transaction rules --- lib/data/models/company_model.dart | 8 ++++- lib/data/models/company_model.g.dart | 29 ++++++++++++++++++- lib/data/models/serializers.g.dart | 4 +++ lib/data/models/transaction_rule_model.dart | 9 +++--- lib/main.dart | 4 ++- lib/redux/app/app_state.dart | 3 +- .../transaction_rule_selectors.dart | 19 +----------- lib/ui/app/menu_drawer.dart | 7 ----- .../edit/transaction_rule_edit.dart | 10 +++---- lib/utils/i18n.dart | 2 +- lib/utils/icons.dart | 2 ++ starter.sh | 2 +- 12 files changed, 58 insertions(+), 41 deletions(-) diff --git a/lib/data/models/company_model.dart b/lib/data/models/company_model.dart index 7fd8a85a5..7240b0cbb 100644 --- a/lib/data/models/company_model.dart +++ b/lib/data/models/company_model.dart @@ -147,6 +147,7 @@ abstract class CompanyEntity extends Object purchaseOrders: BuiltList(), bankAccounts: BuiltList(), transactions: BuiltList(), + transactionRules: BuiltList(), ); } @@ -336,6 +337,9 @@ abstract class CompanyEntity extends Object @BuiltValueField(wireName: 'bank_transactions') BuiltList get transactions; + @BuiltValueField(wireName: 'bank_transaction_rules') + BuiltList get transactionRules; + BuiltList get tasks; BuiltList get projects; @@ -605,6 +609,7 @@ abstract class CompanyEntity extends Object ..purchaseOrders.clear() ..bankAccounts.clear() ..transactions.clear() + ..transactionRules.clear() ..credits.clear() ..tasks.clear() ..projects.clear() @@ -692,7 +697,8 @@ abstract class CompanyEntity extends Object ..clientRegistrationFields.replace(BuiltList()) ..purchaseOrders.replace(BuiltList()) ..bankAccounts.replace(BuiltList()) - ..transactions.replace(BuiltList()); + ..transactions.replace(BuiltList()) + ..transactionRules.replace(BuiltList()); static Serializer get serializer => _$companyEntitySerializer; } diff --git a/lib/data/models/company_model.g.dart b/lib/data/models/company_model.g.dart index 94f3ce515..7f2ac34d7 100644 --- a/lib/data/models/company_model.g.dart +++ b/lib/data/models/company_model.g.dart @@ -242,6 +242,10 @@ class _$CompanyEntitySerializer implements StructuredSerializer { serializers.serialize(object.transactions, specifiedType: const FullType( BuiltList, const [const FullType(TransactionEntity)])), + 'bank_transaction_rules', + serializers.serialize(object.transactionRules, + specifiedType: const FullType( + BuiltList, const [const FullType(TransactionRuleEntity)])), 'tasks', serializers.serialize(object.tasks, specifiedType: @@ -692,6 +696,12 @@ class _$CompanyEntitySerializer implements StructuredSerializer { BuiltList, const [const FullType(TransactionEntity)])) as BuiltList); break; + case 'bank_transaction_rules': + result.transactionRules.replace(serializers.deserialize(value, + specifiedType: const FullType( + BuiltList, const [const FullType(TransactionRuleEntity)])) + as BuiltList); + break; case 'tasks': result.tasks.replace(serializers.deserialize(value, specifiedType: const FullType( @@ -1666,6 +1676,8 @@ class _$CompanyEntity extends CompanyEntity { @override final BuiltList transactions; @override + final BuiltList transactionRules; + @override final BuiltList tasks; @override final BuiltList projects; @@ -1808,6 +1820,7 @@ class _$CompanyEntity extends CompanyEntity { this.purchaseOrders, this.bankAccounts, this.transactions, + this.transactionRules, this.tasks, this.projects, this.expenses, @@ -1964,6 +1977,8 @@ class _$CompanyEntity extends CompanyEntity { bankAccounts, 'CompanyEntity', 'bankAccounts'); BuiltValueNullFieldError.checkNotNull( transactions, 'CompanyEntity', 'transactions'); + BuiltValueNullFieldError.checkNotNull( + transactionRules, 'CompanyEntity', 'transactionRules'); BuiltValueNullFieldError.checkNotNull(tasks, 'CompanyEntity', 'tasks'); BuiltValueNullFieldError.checkNotNull( projects, 'CompanyEntity', 'projects'); @@ -2100,6 +2115,7 @@ class _$CompanyEntity extends CompanyEntity { purchaseOrders == other.purchaseOrders && bankAccounts == other.bankAccounts && transactions == other.transactions && + transactionRules == other.transactionRules && tasks == other.tasks && projects == other.projects && expenses == other.expenses && @@ -2161,7 +2177,7 @@ class _$CompanyEntity extends CompanyEntity { $jc( $jc( $jc( - $jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, enableCustomSurchargeTaxes1.hashCode), enableCustomSurchargeTaxes2.hashCode), enableCustomSurchargeTaxes3.hashCode), enableCustomSurchargeTaxes4.hashCode), sizeId.hashCode), industryId.hashCode), subdomain.hashCode), portalMode.hashCode), portalDomain.hashCode), updateProducts.hashCode), convertProductExchangeRate.hashCode), convertRateToClient.hashCode), fillProducts.hashCode), enableProductCost.hashCode), enableProductQuantity.hashCode), enableProductDiscount.hashCode), defaultTaskIsDateBased.hashCode), defaultQuantity.hashCode), showProductDetails.hashCode), clientCanRegister.hashCode), isLarge.hashCode), isDisabled.hashCode), enableShopApi.hashCode), companyKey.hashCode), firstDayOfWeek.hashCode), firstMonthOfYear.hashCode), numberOfInvoiceTaxRates.hashCode), numberOfItemTaxRates.hashCode), numberOfExpenseTaxRates.hashCode), expenseInclusiveTaxes.hashCode), sessionTimeout.hashCode), passwordTimeout.hashCode), oauthPasswordRequired.hashCode), markdownEnabled.hashCode), markdownEmailEnabled.hashCode), useCommaAsDecimalPlace.hashCode), reportIncludeDrafts.hashCode), reportIncludeDeleted.hashCode), useQuoteTermsOnConversion.hashCode), enableApplyingPayments.hashCode), trackInventory.hashCode), stockNotificationThreshold.hashCode), stockNotification.hashCode), groups.hashCode), activities.hashCode), taxRates.hashCode), taskStatuses.hashCode), taskStatusMap.hashCode), companyGateways.hashCode), expenseCategories.hashCode), users.hashCode), clients.hashCode), products.hashCode), invoices.hashCode), recurringInvoices.hashCode), recurringExpenses.hashCode), payments.hashCode), quotes.hashCode), credits.hashCode), purchaseOrders.hashCode), bankAccounts.hashCode), transactions.hashCode), tasks.hashCode), projects.hashCode), expenses.hashCode), vendors.hashCode), designs.hashCode), documents.hashCode), tokens.hashCode), webhooks.hashCode), subscriptions.hashCode), paymentTerms.hashCode), systemLogs.hashCode), clientRegistrationFields.hashCode), customFields.hashCode), slackWebhookUrl.hashCode), googleAnalyticsKey.hashCode), markExpensesInvoiceable.hashCode), markExpensesPaid.hashCode), invoiceExpenseDocuments.hashCode), invoiceTaskDocuments.hashCode), + $jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, enableCustomSurchargeTaxes1.hashCode), enableCustomSurchargeTaxes2.hashCode), enableCustomSurchargeTaxes3.hashCode), enableCustomSurchargeTaxes4.hashCode), sizeId.hashCode), industryId.hashCode), subdomain.hashCode), portalMode.hashCode), portalDomain.hashCode), updateProducts.hashCode), convertProductExchangeRate.hashCode), convertRateToClient.hashCode), fillProducts.hashCode), enableProductCost.hashCode), enableProductQuantity.hashCode), enableProductDiscount.hashCode), defaultTaskIsDateBased.hashCode), defaultQuantity.hashCode), showProductDetails.hashCode), clientCanRegister.hashCode), isLarge.hashCode), isDisabled.hashCode), enableShopApi.hashCode), companyKey.hashCode), firstDayOfWeek.hashCode), firstMonthOfYear.hashCode), numberOfInvoiceTaxRates.hashCode), numberOfItemTaxRates.hashCode), numberOfExpenseTaxRates.hashCode), expenseInclusiveTaxes.hashCode), sessionTimeout.hashCode), passwordTimeout.hashCode), oauthPasswordRequired.hashCode), markdownEnabled.hashCode), markdownEmailEnabled.hashCode), useCommaAsDecimalPlace.hashCode), reportIncludeDrafts.hashCode), reportIncludeDeleted.hashCode), useQuoteTermsOnConversion.hashCode), enableApplyingPayments.hashCode), trackInventory.hashCode), stockNotificationThreshold.hashCode), stockNotification.hashCode), groups.hashCode), activities.hashCode), taxRates.hashCode), taskStatuses.hashCode), taskStatusMap.hashCode), companyGateways.hashCode), expenseCategories.hashCode), users.hashCode), clients.hashCode), products.hashCode), invoices.hashCode), recurringInvoices.hashCode), recurringExpenses.hashCode), payments.hashCode), quotes.hashCode), credits.hashCode), purchaseOrders.hashCode), bankAccounts.hashCode), transactions.hashCode), transactionRules.hashCode), tasks.hashCode), projects.hashCode), expenses.hashCode), vendors.hashCode), designs.hashCode), documents.hashCode), tokens.hashCode), webhooks.hashCode), subscriptions.hashCode), paymentTerms.hashCode), systemLogs.hashCode), clientRegistrationFields.hashCode), customFields.hashCode), slackWebhookUrl.hashCode), googleAnalyticsKey.hashCode), markExpensesInvoiceable.hashCode), markExpensesPaid.hashCode), invoiceExpenseDocuments.hashCode), invoiceTaskDocuments.hashCode), invoiceTaskTimelog.hashCode), invoiceTaskDatelog.hashCode), invoiceTaskProject.hashCode), @@ -2248,6 +2264,7 @@ class _$CompanyEntity extends CompanyEntity { ..add('purchaseOrders', purchaseOrders) ..add('bankAccounts', bankAccounts) ..add('transactions', transactions) + ..add('transactionRules', transactionRules) ..add('tasks', tasks) ..add('projects', projects) ..add('expenses', expenses) @@ -2609,6 +2626,12 @@ class CompanyEntityBuilder set transactions(ListBuilder transactions) => _$this._transactions = transactions; + ListBuilder _transactionRules; + ListBuilder get transactionRules => + _$this._transactionRules ??= new ListBuilder(); + set transactionRules(ListBuilder transactionRules) => + _$this._transactionRules = transactionRules; + ListBuilder _tasks; ListBuilder get tasks => _$this._tasks ??= new ListBuilder(); @@ -2872,6 +2895,7 @@ class CompanyEntityBuilder _purchaseOrders = $v.purchaseOrders.toBuilder(); _bankAccounts = $v.bankAccounts.toBuilder(); _transactions = $v.transactions.toBuilder(); + _transactionRules = $v.transactionRules.toBuilder(); _tasks = $v.tasks.toBuilder(); _projects = $v.projects.toBuilder(); _expenses = $v.expenses.toBuilder(); @@ -3008,6 +3032,7 @@ class CompanyEntityBuilder purchaseOrders: purchaseOrders.build(), bankAccounts: bankAccounts.build(), transactions: transactions.build(), + transactionRules: transactionRules.build(), tasks: tasks.build(), projects: projects.build(), expenses: expenses.build(), @@ -3087,6 +3112,8 @@ class CompanyEntityBuilder bankAccounts.build(); _$failedField = 'transactions'; transactions.build(); + _$failedField = 'transactionRules'; + transactionRules.build(); _$failedField = 'tasks'; tasks.build(); _$failedField = 'projects'; diff --git a/lib/data/models/serializers.g.dart b/lib/data/models/serializers.g.dart index a868f747f..a1cf0a339 100644 --- a/lib/data/models/serializers.g.dart +++ b/lib/data/models/serializers.g.dart @@ -434,6 +434,10 @@ Serializers _$serializers = (new Serializers().toBuilder() ..addBuilderFactory( const FullType(BuiltList, const [const FullType(TransactionEntity)]), () => new ListBuilder()) + ..addBuilderFactory( + const FullType( + BuiltList, const [const FullType(TransactionRuleEntity)]), + () => new ListBuilder()) ..addBuilderFactory( const FullType(BuiltList, const [const FullType(TaskEntity)]), () => new ListBuilder()) diff --git a/lib/data/models/transaction_rule_model.dart b/lib/data/models/transaction_rule_model.dart index 25f990d40..deb1e03fd 100644 --- a/lib/data/models/transaction_rule_model.dart +++ b/lib/data/models/transaction_rule_model.dart @@ -63,8 +63,7 @@ abstract class TransactionRuleEntity extends Object createdUserId: '', assignedUserId: '', archivedAt: 0, - // STARTER: constructor - do not remove comment - transaction_rules: '', + name: '', ); } @@ -110,8 +109,10 @@ abstract class TransactionRuleEntity extends Object switch (sortField) { // STARTER: sort switch - do not remove comment - case TransactionRuleFields.transaction_rules: - response = transactionRuleA.name.compareTo(transactionRuleB.name); + case TransactionRuleFields.name: + response = transactionRuleA.name + .toLowerCase() + .compareTo(transactionRuleB.name.toLowerCase()); break; default: diff --git a/lib/main.dart b/lib/main.dart index 97f226665..de53dd9c6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -56,6 +56,7 @@ import 'package:invoiceninja_flutter/redux/webhook/webhook_middleware.dart'; import 'package:invoiceninja_flutter/redux/transaction/transaction_middleware.dart'; import 'package:invoiceninja_flutter/redux/bank_account/bank_account_middleware.dart'; import 'package:invoiceninja_flutter/redux/purchase_order/purchase_order_middleware.dart'; +import 'package:invoiceninja_flutter/redux/transaction_rule/transaction_rule_middleware.dart'; import 'package:window_manager/window_manager.dart'; // STARTER: import - do not remove comment @@ -63,7 +64,8 @@ import 'package:invoiceninja_flutter/utils/web_stub.dart' if (dart.library.html) 'package:invoiceninja_flutter/utils/web.dart'; // https://github.com/dart-lang/io/issues/83#issuecomment-940617222 -const isrgRootX1 = '''-----BEGIN CERTIFICATE----- +const isrgRootX1 = + '''-----BEGIN CERTIFICATE----- MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 diff --git a/lib/redux/app/app_state.dart b/lib/redux/app/app_state.dart index af92684d2..9019fda52 100644 --- a/lib/redux/app/app_state.dart +++ b/lib/redux/app/app_state.dart @@ -722,8 +722,7 @@ abstract class AppState implements Built { return creditUIState.editing.isChanged == true; // STARTER: has changes - do not remove comment case TransactionRuleEditScreen.route: - return hastransactionRuleUIState.editing.isChanged == true; - + return transactionRuleUIState.editing.isChanged == true; case TransactionEditScreen.route: return transactionUIState.editing.isChanged == true; case PurchaseOrderEditScreen.route: diff --git a/lib/redux/transaction_rule/transaction_rule_selectors.dart b/lib/redux/transaction_rule/transaction_rule_selectors.dart index 4e7ae0fe3..bacc5e784 100644 --- a/lib/redux/transaction_rule/transaction_rule_selectors.dart +++ b/lib/redux/transaction_rule/transaction_rule_selectors.dart @@ -53,7 +53,7 @@ List filteredTransactionRulesSelector( BuiltList transactionRuleList, ListUIState transactionRuleListState) { final filterEntityId = selectionState.filterEntityId; - final filterEntityType = selectionState.filterEntityType; + //final filterEntityType = selectionState.filterEntityType; final list = transactionRuleList.where((transactionRuleId) { final transactionRule = transactionRuleMap[transactionRuleId]; @@ -64,23 +64,6 @@ List filteredTransactionRulesSelector( if (!transactionRule.matchesStates(transactionRuleListState.stateFilters)) { return false; } - if (transactionRuleListState.custom1Filters.isNotEmpty && - !transactionRuleListState.custom1Filters - .contains(transactionRule.customValue1)) { - return false; - } else if (transactionRuleListState.custom2Filters.isNotEmpty && - !transactionRuleListState.custom2Filters - .contains(transactionRule.customValue2)) { - return false; - } else if (transactionRuleListState.custom3Filters.isNotEmpty && - !transactionRuleListState.custom3Filters - .contains(transactionRule.customValue3)) { - return false; - } else if (transactionRuleListState.custom4Filters.isNotEmpty && - !transactionRuleListState.custom4Filters - .contains(transactionRule.customValue4)) { - return false; - } return transactionRule.matchesFilter(transactionRuleListState.filter); }).toList(); diff --git a/lib/ui/app/menu_drawer.dart b/lib/ui/app/menu_drawer.dart index 279da9c9d..f0d142864 100644 --- a/lib/ui/app/menu_drawer.dart +++ b/lib/ui/app/menu_drawer.dart @@ -648,13 +648,6 @@ class _MenuDrawerState extends State { iconTooltip: localization.newExpense, ), // STARTER: menu - do not remove comment - DrawerTile( - company: company, - entityType: EntityType.transactionRule, - icon: getEntityIcon(EntityType.transactionRule), - title: localization.transactionRules, - ), - DrawerTile( company: company, entityType: EntityType.recurringExpense, diff --git a/lib/ui/transaction_rule/edit/transaction_rule_edit.dart b/lib/ui/transaction_rule/edit/transaction_rule_edit.dart index 34756956a..ee508e645 100644 --- a/lib/ui/transaction_rule/edit/transaction_rule_edit.dart +++ b/lib/ui/transaction_rule/edit/transaction_rule_edit.dart @@ -24,7 +24,7 @@ class _TransactionRuleEditState extends State { final _debouncer = Debouncer(); // STARTER: controllers - do not remove comment - final _transaction_rulesController = TextEditingController(); + final _nameController = TextEditingController(); List _controllers = []; @@ -32,14 +32,14 @@ class _TransactionRuleEditState extends State { void didChangeDependencies() { _controllers = [ // STARTER: array - do not remove comment - _transaction_rulesController, + _nameController, ]; _controllers.forEach((controller) => controller.removeListener(_onChanged)); final transactionRule = widget.viewModel.transactionRule; // STARTER: read value - do not remove comment - _transaction_rulesController.text = transaction_rule.transaction_rules; + _nameController.text = transactionRule.name; _controllers.forEach((controller) => controller.addListener(_onChanged)); @@ -60,7 +60,7 @@ class _TransactionRuleEditState extends State { _debouncer.run(() { final transactionRule = widget.viewModel.transactionRule.rebuild((b) => b // STARTER: set value - do not remove comment - ..transaction_rules = _transaction_rulesController.text.trim()); + ..name = _nameController.text.trim()); if (transactionRule != widget.viewModel.transactionRule) { widget.viewModel.onChanged(transactionRule); } @@ -96,7 +96,7 @@ class _TransactionRuleEditState extends State { children: [ // STARTER: widgets - do not remove comment TextFormField( - controller: _transaction_rulesController, + controller: _nameController, autocorrect: false, decoration: InputDecoration( labelText: 'Transaction_rules', diff --git a/lib/utils/i18n.dart b/lib/utils/i18n.dart index 574164c37..2cae222ad 100644 --- a/lib/utils/i18n.dart +++ b/lib/utils/i18n.dart @@ -90495,7 +90495,7 @@ mixin LocalizationsProvider on LocaleCodeAware { String get searchTransactionRule => _localizedValues[localeCode]['search_transaction_rule'] ?? _localizedValues['en']['search_transaction_rule']; - String get searchTransactionRule => + String get searchTransactionRules => _localizedValues[localeCode]['search_transaction_rules'] ?? _localizedValues['en']['search_transaction_rules']; diff --git a/lib/utils/icons.dart b/lib/utils/icons.dart index 1ff701353..1f8a23641 100644 --- a/lib/utils/icons.dart +++ b/lib/utils/icons.dart @@ -174,6 +174,8 @@ IconData getEntityIcon(EntityType entityType) { return MdiIcons.bankTransfer; case EntityType.bankAccount: return MdiIcons.bank; + case EntityType.transactionRule: + return Icons.rule_folder; default: return MdiIcons.crosshairsQuestion; } diff --git a/starter.sh b/starter.sh index 3a81a1ccb..192bcb0c0 100644 --- a/starter.sh +++ b/starter.sh @@ -214,7 +214,7 @@ else echo "app_state: has changes" comment="STARTER: has changes - do not remove comment" - code="case ${Module}EditScreen.route: return has${module_camel}UIState.editing.isChanged == true;${lineBreak}" + code="case ${Module}EditScreen.route: return ${module_camel}UIState.editing.isChanged == true;${lineBreak}" sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/redux/app/app_state.dart for (( idx=${#fieldsArray[@]}-1 ; idx>=0 ; idx-- )) ; do