From 55f4f1b5f101d0f9874fe3d3406d53c6df931a40 Mon Sep 17 00:00:00 2001 From: Damyan Ivanov Date: Thu, 18 Feb 2021 19:42:40 +0200 Subject: [PATCH] add fallback flag to templates --- .../net.ktnx.mobileledger.db.DB/57.json | 348 ++++++++++++++++++ .../java/net/ktnx/mobileledger/db/DB.java | 2 +- .../ktnx/mobileledger/db/TemplateHeader.java | 9 + .../model/TemplateDetailsItem.java | 15 +- .../ui/templates/TemplateDetailsAdapter.java | 18 + .../utils/MobileLedgerDatabase.java | 2 +- .../res/layout/template_details_header.xml | 33 +- app/src/main/res/raw/create_db.sql | 2 +- app/src/main/res/raw/sql_57.sql | 23 ++ app/src/main/res/values-bg/strings.xml | 3 + app/src/main/res/values/strings.xml | 3 + 11 files changed, 453 insertions(+), 5 deletions(-) create mode 100644 app/schemas/net.ktnx.mobileledger.db.DB/57.json create mode 100644 app/src/main/res/raw/sql_57.sql diff --git a/app/schemas/net.ktnx.mobileledger.db.DB/57.json b/app/schemas/net.ktnx.mobileledger.db.DB/57.json new file mode 100644 index 00000000..68311f52 --- /dev/null +++ b/app/schemas/net.ktnx.mobileledger.db.DB/57.json @@ -0,0 +1,348 @@ +{ + "formatVersion": 1, + "database": { + "version": 57, + "identityHash": "5a5aa2f77594578d228d211d5e4406a6", + "entities": [ + { + "tableName": "templates", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `regular_expression` TEXT NOT NULL, `test_text` TEXT, `transaction_description` TEXT, `transaction_description_match_group` INTEGER, `transaction_comment` TEXT, `transaction_comment_match_group` INTEGER, `date_year` INTEGER, `date_year_match_group` INTEGER, `date_month` INTEGER, `date_month_match_group` INTEGER, `date_day` INTEGER, `date_day_match_group` INTEGER, `is_fallback` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "regularExpression", + "columnName": "regular_expression", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "testText", + "columnName": "test_text", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "transactionDescription", + "columnName": "transaction_description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "transactionDescriptionMatchGroup", + "columnName": "transaction_description_match_group", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "transactionComment", + "columnName": "transaction_comment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "transactionCommentMatchGroup", + "columnName": "transaction_comment_match_group", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "dateYear", + "columnName": "date_year", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "dateYearMatchGroup", + "columnName": "date_year_match_group", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "dateMonth", + "columnName": "date_month", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "dateMonthMatchGroup", + "columnName": "date_month_match_group", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "dateDay", + "columnName": "date_day", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "dateDayMatchGroup", + "columnName": "date_day_match_group", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "isFallback", + "columnName": "is_fallback", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "template_accounts", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `template_id` INTEGER NOT NULL, `acc` TEXT, `position` INTEGER NOT NULL, `acc_match_group` INTEGER, `currency` INTEGER, `currency_match_group` INTEGER, `amount` REAL, `amount_match_group` INTEGER, `comment` TEXT, `comment_match_group` INTEGER, `negate_amount` INTEGER, FOREIGN KEY(`template_id`) REFERENCES `templates`(`id`) ON UPDATE RESTRICT ON DELETE CASCADE , FOREIGN KEY(`currency`) REFERENCES `currencies`(`id`) ON UPDATE RESTRICT ON DELETE RESTRICT )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "templateId", + "columnName": "template_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "accountName", + "columnName": "acc", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "accountNameMatchGroup", + "columnName": "acc_match_group", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "currency", + "columnName": "currency", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "currencyMatchGroup", + "columnName": "currency_match_group", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "amount", + "columnName": "amount", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "amountMatchGroup", + "columnName": "amount_match_group", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "accountComment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "accountCommentMatchGroup", + "columnName": "comment_match_group", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "negateAmount", + "columnName": "negate_amount", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "fk_template_accounts_template", + "unique": false, + "columnNames": [ + "template_id" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `fk_template_accounts_template` ON `${TABLE_NAME}` (`template_id`)" + }, + { + "name": "fk_template_accounts_currency", + "unique": false, + "columnNames": [ + "currency" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `fk_template_accounts_currency` ON `${TABLE_NAME}` (`currency`)" + } + ], + "foreignKeys": [ + { + "table": "templates", + "onDelete": "CASCADE", + "onUpdate": "RESTRICT", + "columns": [ + "template_id" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "currencies", + "onDelete": "RESTRICT", + "onUpdate": "RESTRICT", + "columns": [ + "currency" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "currencies", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `position` TEXT NOT NULL, `has_gap` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "hasGap", + "columnName": "has_gap", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "accounts", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`level` INTEGER NOT NULL, `profile` TEXT NOT NULL, `name` TEXT NOT NULL, `name_upper` TEXT NOT NULL, `parent_name` TEXT, `expanded` INTEGER NOT NULL DEFAULT 1, `amounts_expanded` INTEGER NOT NULL DEFAULT 0, `generation` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`profile`, `name`))", + "fields": [ + { + "fieldPath": "level", + "columnName": "level", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "profile", + "columnName": "profile", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "nameUpper", + "columnName": "name_upper", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "parentName", + "columnName": "parent_name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "expanded", + "columnName": "expanded", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "amountsExpanded", + "columnName": "amounts_expanded", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "generation", + "columnName": "generation", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "columnNames": [ + "profile", + "name" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5a5aa2f77594578d228d211d5e4406a6')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/net/ktnx/mobileledger/db/DB.java b/app/src/main/java/net/ktnx/mobileledger/db/DB.java index d4e4d727..aa5d92d1 100644 --- a/app/src/main/java/net/ktnx/mobileledger/db/DB.java +++ b/app/src/main/java/net/ktnx/mobileledger/db/DB.java @@ -31,7 +31,7 @@ import net.ktnx.mobileledger.dao.TemplateAccountDAO; import net.ktnx.mobileledger.dao.TemplateHeaderDAO; import net.ktnx.mobileledger.utils.MobileLedgerDatabase; -@Database(version = 56, entities = {TemplateHeader.class, TemplateAccount.class, Currency.class, +@Database(version = 57, entities = {TemplateHeader.class, TemplateAccount.class, Currency.class, net.ktnx.mobileledger.db.Account.class }) abstract public class DB extends RoomDatabase { diff --git a/app/src/main/java/net/ktnx/mobileledger/db/TemplateHeader.java b/app/src/main/java/net/ktnx/mobileledger/db/TemplateHeader.java index 6f8e25df..b5afb89e 100644 --- a/app/src/main/java/net/ktnx/mobileledger/db/TemplateHeader.java +++ b/app/src/main/java/net/ktnx/mobileledger/db/TemplateHeader.java @@ -60,6 +60,8 @@ public class TemplateHeader extends TemplateBase { private Integer dateDay; @ColumnInfo(name = "date_day_match_group") private Integer dateDayMatchGroup; + @ColumnInfo(name = "is_fallback") + private boolean isFallback; public TemplateHeader(@NotNull Long id, @NonNull String name, @NonNull String regularExpression) { this.id = id; @@ -81,6 +83,13 @@ public class TemplateHeader extends TemplateBase { dateMonthMatchGroup = origin.dateMonthMatchGroup; dateDay = origin.dateDay; dateDayMatchGroup = origin.dateDayMatchGroup; + isFallback = origin.isFallback; + } + public boolean isFallback() { + return isFallback; + } + public void setFallback(boolean fallback) { + isFallback = fallback; } public String getTestText() { return testText; diff --git a/app/src/main/java/net/ktnx/mobileledger/model/TemplateDetailsItem.java b/app/src/main/java/net/ktnx/mobileledger/model/TemplateDetailsItem.java index 84e83d54..2eb3346d 100644 --- a/app/src/main/java/net/ktnx/mobileledger/model/TemplateDetailsItem.java +++ b/app/src/main/java/net/ktnx/mobileledger/model/TemplateDetailsItem.java @@ -98,6 +98,8 @@ abstract public class TemplateDetailsItem { else header.setDateYearMatchGroup(ph.getDateYearMatchGroup()); + header.setFallback(ph.isFallback()); + return header; } else if (p instanceof TemplateAccount) { @@ -446,6 +448,7 @@ abstract public class TemplateDetailsItem { private PossiblyMatchedValue dateMonth = PossiblyMatchedValue.withLiteralInt(null); private PossiblyMatchedValue dateDay = PossiblyMatchedValue.withLiteralInt(null); private SpannableString testMatch; + private boolean isFallback; private Header() { super(Type.HEADER); } @@ -463,12 +466,20 @@ abstract public class TemplateDetailsItem { dateYear = new PossiblyMatchedValue<>(origin.dateYear); dateMonth = new PossiblyMatchedValue<>(origin.dateMonth); dateDay = new PossiblyMatchedValue<>(origin.dateDay); + + isFallback = origin.isFallback; } private static StyleSpan capturedSpan() { return new StyleSpan(Typeface.BOLD); } private static UnderlineSpan matchedSpan() { return new UnderlineSpan(); } private static ForegroundColorSpan notMatchedSpan() { return new ForegroundColorSpan(Color.GRAY); } + public boolean isFallback() { + return isFallback; + } + public void setFallback(boolean fallback) { + this.isFallback = fallback; + } public String getName() { return name; } @@ -603,7 +614,7 @@ abstract public class TemplateDetailsItem { return Misc.equalStrings(name, o.name) && Misc.equalStrings(pattern, o.pattern) && Misc.equalStrings(testText, o.testText) && Misc.equalStrings(patternError, o.patternError) && - Objects.equals(testMatch, o.testMatch); + Objects.equals(testMatch, o.testMatch) && isFallback == o.isFallback; } public String getMatchGroupText(int group) { if (compiledPattern != null && testText != null) { @@ -673,6 +684,8 @@ abstract public class TemplateDetailsItem { else result.setDateDayMatchGroup(dateDay.getMatchGroup()); + result.setFallback(isFallback); + return result; } public SpannableString getTestMatch() { diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/templates/TemplateDetailsAdapter.java b/app/src/main/java/net/ktnx/mobileledger/ui/templates/TemplateDetailsAdapter.java index 73d986b6..50788940 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/templates/TemplateDetailsAdapter.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/templates/TemplateDetailsAdapter.java @@ -399,6 +399,19 @@ class TemplateDetailsAdapter extends RecyclerView.Adapter { + if (updatePropagationDisabled) + return; + + getItem().setFallback(isChecked); + b.templateIsFallbackText.setText(isChecked ? R.string.template_is_fallback_yes + : R.string.template_is_fallback_no); + }); + final View.OnClickListener fallbackLabelClickListener = + (view) -> b.templateIsFallbackSwitch.toggle(); + b.templateIsFallbackLabel.setOnClickListener(fallbackLabelClickListener); + b.templateIsFallbackText.setOnClickListener(fallbackLabelClickListener); } @NotNull private TemplateDetailsItem.Header getItem() { @@ -570,6 +583,11 @@ class TemplateDetailsAdapter extends RecyclerView.Adapter initComplete = new MutableLiveData<>(false); public static final String DB_NAME = "MoLe.db"; - private static final int LATEST_REVISION = 56; + private static final int LATEST_REVISION = 57; private static final String CREATE_DB_SQL = "create_db"; private final Application mContext; diff --git a/app/src/main/res/layout/template_details_header.xml b/app/src/main/res/layout/template_details_header.xml index a35f555a..43514d04 100644 --- a/app/src/main/res/layout/template_details_header.xml +++ b/app/src/main/res/layout/template_details_header.xml @@ -349,8 +349,9 @@ android:id="@+id/transaction_comment_layout" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/text_margin" app:endIconMode="clear_text" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintBottom_toTopOf="@id/template_is_fallback_label" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/template_transaction_comment_source" @@ -362,5 +363,35 @@ android:hint="@string/template_transaction_comment_hint" /> + + + + \ No newline at end of file diff --git a/app/src/main/res/raw/create_db.sql b/app/src/main/res/raw/create_db.sql index 3d206991..39965ed3 100644 --- a/app/src/main/res/raw/create_db.sql +++ b/app/src/main/res/raw/create_db.sql @@ -31,7 +31,7 @@ create table transaction_accounts(profile varchar not null, transaction_id integ create unique index un_transaction_accounts_order on transaction_accounts(profile, transaction_id, order_no); create table currencies(id integer not null primary key, name varchar not null, position varchar not null, has_gap integer not null); -CREATE TABLE templates (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT NOT NULL, regular_expression TEXT NOT NULL, test_text TEXT, transaction_description TEXT, transaction_description_match_group INTEGER, transaction_comment TEXT, transaction_comment_match_group INTEGER, date_year INTEGER, date_year_match_group INTEGER, date_month INTEGER, date_month_match_group INTEGER, date_day INTEGER, date_day_match_group INTEGER); +CREATE TABLE templates (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT NOT NULL, regular_expression TEXT NOT NULL, test_text TEXT, transaction_description TEXT, transaction_description_match_group INTEGER, transaction_comment TEXT, transaction_comment_match_group INTEGER, date_year INTEGER, date_year_match_group INTEGER, date_month INTEGER, date_month_match_group INTEGER, date_day INTEGER, date_day_match_group INTEGER, is_fallback INTEGER NOT NULL DEFAULT 0); CREATE TABLE template_accounts(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, template_id INTEGER NOT NULL, acc TEXT, position INTEGER NOT NULL, acc_match_group INTEGER, currency INTEGER, currency_match_group INTEGER, amount REAL, amount_match_group INTEGER, comment TEXT, comment_match_group INTEGER, negate_amount INTEGER, FOREIGN KEY(template_id) REFERENCES templates(id) ON UPDATE RESTRICT ON DELETE CASCADE, FOREIGN KEY(currency) REFERENCES currencies(id) ON UPDATE RESTRICT ON DELETE RESTRICT); create index fk_template_accounts_template on template_accounts(template_id); create index fk_template_accounts_currency on template_accounts(currency); diff --git a/app/src/main/res/raw/sql_57.sql b/app/src/main/res/raw/sql_57.sql new file mode 100644 index 00000000..45812bc5 --- /dev/null +++ b/app/src/main/res/raw/sql_57.sql @@ -0,0 +1,23 @@ +-- Copyright © 2021 Damyan Ivanov. +-- This file is part of MoLe. +-- MoLe is free software: you can distribute it and/or modify it +-- under the term of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your opinion), any later version. +-- +-- MoLe is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License terms for details. +-- +-- You should have received a copy of the GNU General Public License +-- along with MoLe. If not, see . + +-- add templates.is_fallback + +BEGIN TRANSACTION; + +alter table templates \ +add is_fallback integer default 0; + +COMMIT TRANSACTION; \ No newline at end of file diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 090b02fc..03806e8a 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -222,4 +222,7 @@ Без промяна на знака Обръщане на знака на сумата (от плюс на минус и от минус на плюс) Знак на сумата + Резервен макет + Макетът ще се предлага за избор само ако няма друг макет, който да пасва и да не е маркиран като резервен + Макетът не е резервен diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e7ad4b2f..5713de10 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -232,4 +232,7 @@ Sign will not be altered Amount sign will be changed (plus to minus; minus to plus) Change amount sign + Fallback template + Template will be offered for selection only when no templates match that aren\'t marked as fallback templates + Template is a primary, high priority one, not a catch-all -- 2.39.5