]> git.ktnx.net Git - mobile-ledger.git/commitdiff
add fallback flag to templates
authorDamyan Ivanov <dam+mobileledger@ktnx.net>
Thu, 18 Feb 2021 17:42:40 +0000 (19:42 +0200)
committerDamyan Ivanov <dam+mobileledger@ktnx.net>
Thu, 18 Feb 2021 17:42:40 +0000 (19:42 +0200)
app/schemas/net.ktnx.mobileledger.db.DB/57.json [new file with mode: 0644]
app/src/main/java/net/ktnx/mobileledger/db/DB.java
app/src/main/java/net/ktnx/mobileledger/db/TemplateHeader.java
app/src/main/java/net/ktnx/mobileledger/model/TemplateDetailsItem.java
app/src/main/java/net/ktnx/mobileledger/ui/templates/TemplateDetailsAdapter.java
app/src/main/java/net/ktnx/mobileledger/utils/MobileLedgerDatabase.java
app/src/main/res/layout/template_details_header.xml
app/src/main/res/raw/create_db.sql
app/src/main/res/raw/sql_57.sql [new file with mode: 0644]
app/src/main/res/values-bg/strings.xml
app/src/main/res/values/strings.xml

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 (file)
index 0000000..68311f5
--- /dev/null
@@ -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
index d4e4d7273aaf3519231e12d9f5127e130e3c196f..aa5d92d140da3555a465e25ebf948f8d8d27fb75 100644 (file)
@@ -31,7 +31,7 @@ import net.ktnx.mobileledger.dao.TemplateAccountDAO;
 import net.ktnx.mobileledger.dao.TemplateHeaderDAO;
 import net.ktnx.mobileledger.utils.MobileLedgerDatabase;
 
 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 {
                                     net.ktnx.mobileledger.db.Account.class
 })
 abstract public class DB extends RoomDatabase {
index 6f8e25df384725c28569a9a56a6c54215763c1f4..b5afb89eef9814b09fe497fd29beb44f4528a1da 100644 (file)
@@ -60,6 +60,8 @@ public class TemplateHeader extends TemplateBase {
     private Integer dateDay;
     @ColumnInfo(name = "date_day_match_group")
     private Integer dateDayMatchGroup;
     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;
     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;
         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;
     }
     public String getTestText() {
         return testText;
index 84e83d54a314a10275554b9322fd08ebceee4914..2eb3346df313e6c9ae040e84e05aa594d1856064 100644 (file)
@@ -98,6 +98,8 @@ abstract public class TemplateDetailsItem {
             else
                 header.setDateYearMatchGroup(ph.getDateYearMatchGroup());
 
             else
                 header.setDateYearMatchGroup(ph.getDateYearMatchGroup());
 
+            header.setFallback(ph.isFallback());
+
             return header;
         }
         else if (p instanceof TemplateAccount) {
             return header;
         }
         else if (p instanceof TemplateAccount) {
@@ -446,6 +448,7 @@ abstract public class TemplateDetailsItem {
         private PossiblyMatchedValue<Integer> dateMonth = PossiblyMatchedValue.withLiteralInt(null);
         private PossiblyMatchedValue<Integer> dateDay = PossiblyMatchedValue.withLiteralInt(null);
         private SpannableString testMatch;
         private PossiblyMatchedValue<Integer> dateMonth = PossiblyMatchedValue.withLiteralInt(null);
         private PossiblyMatchedValue<Integer> dateDay = PossiblyMatchedValue.withLiteralInt(null);
         private SpannableString testMatch;
+        private boolean isFallback;
         private Header() {
             super(Type.HEADER);
         }
         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);
             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);
         }
         }
         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;
         }
         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) &&
             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) {
         }
         public String getMatchGroupText(int group) {
             if (compiledPattern != null && testText != null) {
@@ -673,6 +684,8 @@ abstract public class TemplateDetailsItem {
             else
                 result.setDateDayMatchGroup(dateDay.getMatchGroup());
 
             else
                 result.setDateDayMatchGroup(dateDay.getMatchGroup());
 
+            result.setFallback(isFallback);
+
             return result;
         }
         public SpannableString getTestMatch() {
             return result;
         }
         public SpannableString getTestMatch() {
index 73d986b66e6f496bb0f003a4f86fccb22f469a00..50788940932104b286a968cce672139006c1a818 100644 (file)
@@ -399,6 +399,19 @@ class TemplateDetailsAdapter extends RecyclerView.Adapter<TemplateDetailsAdapter
                 }
             };
             b.transactionComment.addTextChangedListener(transactionCommentWatcher);
                 }
             };
             b.transactionComment.addTextChangedListener(transactionCommentWatcher);
+
+            b.templateIsFallbackSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
+                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() {
         }
         @NotNull
         private TemplateDetailsItem.Header getItem() {
@@ -570,6 +583,11 @@ class TemplateDetailsAdapter extends RecyclerView.Adapter<TemplateDetailsAdapter
 
                 b.templateDetailsHeadScanQrButton.setOnClickListener(this::scanTestQR);
 
 
                 b.templateDetailsHeadScanQrButton.setOnClickListener(this::scanTestQR);
 
+                b.templateIsFallbackSwitch.setChecked(header.isFallback());
+                b.templateIsFallbackText.setText(
+                        header.isFallback() ? R.string.template_is_fallback_yes
+                                            : R.string.template_is_fallback_no);
+
                 checkPatternError(header);
             }
             finally {
                 checkPatternError(header);
             }
             finally {
index b3c719e9560486b559bd14aa3f7122f63774ec64..0ddaa1dc0fc2da4cb5f3c1f9a2dd9fa5684b37f1 100644 (file)
@@ -40,7 +40,7 @@ import static net.ktnx.mobileledger.utils.Logger.debug;
 public class MobileLedgerDatabase extends SQLiteOpenHelper {
     public static final MutableLiveData<Boolean> initComplete = new MutableLiveData<>(false);
     public static final String DB_NAME = "MoLe.db";
 public class MobileLedgerDatabase extends SQLiteOpenHelper {
     public static final MutableLiveData<Boolean> 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;
 
     private static final String CREATE_DB_SQL = "create_db";
     private final Application mContext;
 
index a35f555a0efaccf6f9331eeb505803df16619b36..43514d04f812c2a6f7da86eb05685dc886927d19 100644 (file)
         android:id="@+id/transaction_comment_layout"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         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: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"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@id/template_transaction_comment_source"
             android:hint="@string/template_transaction_comment_hint"
             />
     </com.google.android.material.textfield.TextInputLayout>
             android:hint="@string/template_transaction_comment_hint"
             />
     </com.google.android.material.textfield.TextInputLayout>
+    <TextView
+        android:id="@+id/template_is_fallback_label"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:text="@string/template_is_fallback_label"
+        android:textAppearance="?attr/textAppearanceListItem"
+        app:layout_constraintBottom_toTopOf="@+id/template_is_fallback_text"
+        app:layout_constraintEnd_toStartOf="@id/template_is_fallback_switch"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/transaction_comment_layout"
+        />
+    <TextView
+        android:id="@+id/template_is_fallback_text"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:textAppearance="?attr/textAppearanceListItemSecondary"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/template_is_fallback_switch"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/template_is_fallback_label"
+        />
+    <com.google.android.material.switchmaterial.SwitchMaterial
+        android:id="@+id/template_is_fallback_switch"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintBottom_toBottomOf="@id/template_is_fallback_text"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="@id/template_is_fallback_label"
+        />
+
 
 </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
 
 </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
index 3d206991d8618e1f5d4145742831249323d61914..39965ed3a3963033d83dc3c1fc59c4796fb82c45 100644 (file)
@@ -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 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);
 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 (file)
index 0000000..45812bc
--- /dev/null
@@ -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 <https://www.gnu.org/licenses/>.
+
+-- add templates.is_fallback
+
+BEGIN TRANSACTION;
+
+alter table templates                   \
+add is_fallback integer default 0;
+
+COMMIT TRANSACTION;
\ No newline at end of file
index 090b02fc404c92dce80c8a74cb3aed8a50794a3b..03806e8a080b8063eb059714b9439b1594535ebc 100644 (file)
     <string name="template_account_keep_amount_sign">Без промяна на знака</string>
     <string name="template_account_change_amount_sign">Обръщане на знака на сумата (от плюс на минус и от минус на плюс)</string>
     <string name="template_account_negate_amount_label">Знак на сумата</string>
     <string name="template_account_keep_amount_sign">Без промяна на знака</string>
     <string name="template_account_change_amount_sign">Обръщане на знака на сумата (от плюс на минус и от минус на плюс)</string>
     <string name="template_account_negate_amount_label">Знак на сумата</string>
+    <string name="template_is_fallback_label">Резервен макет</string>
+    <string name="template_is_fallback_yes">Макетът ще се предлага за избор само ако няма друг макет, който да пасва и да не е маркиран като резервен</string>
+    <string name="template_is_fallback_no">Макетът не е резервен</string>
 </resources>
 </resources>
index e7ad4b2f25fb0eca6c36f5d85b140912361f476f..5713de103fe022eb8fb0d04e54a6251f893d74f3 100644 (file)
     <string name="template_account_keep_amount_sign">Sign will not be altered</string>
     <string name="template_account_change_amount_sign">Amount sign will be changed (plus to minus; minus to plus)</string>
     <string name="template_account_negate_amount_label">Change amount sign</string>
     <string name="template_account_keep_amount_sign">Sign will not be altered</string>
     <string name="template_account_change_amount_sign">Amount sign will be changed (plus to minus; minus to plus)</string>
     <string name="template_account_negate_amount_label">Change amount sign</string>
+    <string name="template_is_fallback_label">Fallback template</string>
+    <string name="template_is_fallback_yes">Template will be offered for selection only when no templates match that aren\'t marked as fallback templates</string>
+    <string name="template_is_fallback_no">Template is a primary, high priority one, not a catch-all</string>
 </resources>
 </resources>