monopyly 1.5.1__py3-none-any.whl → 1.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. monopyly/CHANGELOG.md +27 -0
  2. monopyly/README.md +3 -3
  3. monopyly/__init__.py +22 -27
  4. monopyly/_version.py +2 -2
  5. monopyly/auth/blueprint.py +2 -0
  6. monopyly/auth/routes.py +2 -3
  7. monopyly/banking/accounts.py +7 -7
  8. monopyly/banking/actions.py +20 -17
  9. monopyly/banking/banks.py +1 -1
  10. monopyly/banking/blueprint.py +2 -0
  11. monopyly/banking/filters.py +6 -6
  12. monopyly/banking/forms.py +3 -5
  13. monopyly/banking/routes.py +72 -10
  14. monopyly/banking/transactions.py +15 -7
  15. monopyly/common/forms/__init__.py +8 -0
  16. monopyly/common/forms/_forms.py +1 -2
  17. monopyly/common/forms/fields.py +0 -2
  18. monopyly/common/forms/utils.py +1 -1
  19. monopyly/common/transactions.py +89 -14
  20. monopyly/core/actions.py +2 -8
  21. monopyly/core/blueprint.py +2 -0
  22. monopyly/core/filters.py +0 -2
  23. monopyly/core/routes.py +1 -1
  24. monopyly/credit/accounts.py +1 -1
  25. monopyly/credit/actions.py +4 -5
  26. monopyly/credit/blueprint.py +2 -0
  27. monopyly/credit/cards.py +7 -3
  28. monopyly/credit/forms.py +3 -5
  29. monopyly/credit/routes.py +65 -87
  30. monopyly/credit/statements.py +1 -1
  31. monopyly/credit/transactions/__init__.py +2 -0
  32. monopyly/credit/transactions/_transactions.py +18 -8
  33. monopyly/credit/transactions/activity/__init__.py +6 -0
  34. monopyly/credit/transactions/activity/parser.py +0 -1
  35. monopyly/credit/transactions/activity/reconciliation.py +25 -4
  36. monopyly/database/__init__.py +1 -59
  37. monopyly/database/models.py +198 -276
  38. monopyly/database/preloads.sql +6 -1
  39. monopyly/scripts/screenshot_application.py +100 -0
  40. monopyly/static/chartist-1.5.0.min.js +8 -0
  41. monopyly/static/css/style.css +35 -14
  42. monopyly/static/img/about/bank-account-details.png +0 -0
  43. monopyly/static/img/about/bank-account-summaries.png +0 -0
  44. monopyly/static/img/about/bank-accounts.png +0 -0
  45. monopyly/static/img/about/credit-account-details.png +0 -0
  46. monopyly/static/img/about/credit-statement-details.png +0 -0
  47. monopyly/static/img/about/credit-transactions.png +0 -0
  48. monopyly/static/img/about/homepage-user.png +0 -0
  49. monopyly/static/img/about/homepage.png +0 -0
  50. monopyly/static/jquery-3.7.1.min.js +2 -0
  51. monopyly/static/js/add-transfer.js +8 -9
  52. monopyly/static/js/bind-tag-actions.js +6 -0
  53. monopyly/static/js/create-balance-chart.js +2 -2
  54. monopyly/static/js/create-category-chart.js +1 -1
  55. monopyly/static/js/load-more-transactions.js +27 -0
  56. monopyly/static/js/modules/expand-transaction.js +7 -6
  57. monopyly/static/js/modules/update-display-ajax.js +20 -1
  58. monopyly/static/js/update-transactions-display.js +8 -2
  59. monopyly/templates/banking/account_page.html +15 -16
  60. monopyly/templates/banking/account_summaries.html +2 -2
  61. monopyly/templates/banking/account_summary.html +1 -1
  62. monopyly/templates/banking/accounts_page.html +2 -2
  63. monopyly/templates/banking/transactions_table/table.html +3 -0
  64. monopyly/templates/banking/transactions_table/transactions.html +0 -1
  65. monopyly/templates/common/tag_tree.html +25 -0
  66. monopyly/templates/{credit → common}/tags_page.html +7 -3
  67. monopyly/templates/common/transactions_table/linked_bank_transaction.html +2 -2
  68. monopyly/templates/common/transactions_table/table.html +6 -0
  69. monopyly/templates/common/transactions_table/transactions.html +9 -15
  70. monopyly/templates/core/index.html +112 -101
  71. monopyly/templates/core/profile.html +1 -1
  72. monopyly/templates/credit/statement_page.html +2 -2
  73. monopyly/templates/credit/statement_reconciliation/statement_reconciliation_inquiry.html +1 -1
  74. monopyly/templates/credit/statement_reconciliation/statement_reconciliation_page.html +3 -3
  75. monopyly/templates/credit/statement_summary.html +2 -2
  76. monopyly/templates/credit/transaction_submission_page.html +3 -3
  77. monopyly/templates/credit/transactions_page.html +19 -3
  78. monopyly/templates/credit/transactions_table/condensed_row_content.html +2 -3
  79. monopyly/templates/credit/transactions_table/expanded_row_content.html +5 -5
  80. monopyly/templates/credit/transactions_table/table.html +3 -0
  81. monopyly/templates/credit/transactions_table/transactions.html +0 -1
  82. monopyly/templates/layout.html +9 -4
  83. {monopyly-1.5.1.dist-info → monopyly-1.6.0.dist-info}/METADATA +12 -13
  84. {monopyly-1.5.1.dist-info → monopyly-1.6.0.dist-info}/RECORD +88 -87
  85. monopyly-1.6.0.dist-info/entry_points.txt +3 -0
  86. monopyly/cli/apps.py +0 -108
  87. monopyly/cli/launch.py +0 -135
  88. monopyly/config/__init__.py +0 -1
  89. monopyly/config/default_settings.py +0 -56
  90. monopyly/config/settings.py +0 -59
  91. monopyly/static/jquery-3.7.0.min.js +0 -2
  92. monopyly/templates/credit/tag_tree/subtag_tree.html +0 -22
  93. monopyly/templates/credit/tag_tree/tag_tree.html +0 -13
  94. monopyly-1.5.1.dist-info/entry_points.txt +0 -2
  95. {monopyly-1.5.1.dist-info → monopyly-1.6.0.dist-info}/WHEEL +0 -0
  96. {monopyly-1.5.1.dist-info → monopyly-1.6.0.dist-info}/licenses/COPYING +0 -0
  97. {monopyly-1.5.1.dist-info → monopyly-1.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -113,9 +113,11 @@ class _Matchmaker(ABC):
113
113
 
114
114
  def includes_activity(self, activity):
115
115
  for value in self.values():
116
- if activity == value:
117
- return True
118
- elif isinstance(value, TransactionActivityGroup) and activity in value:
116
+ same_activity = activity == value
117
+ same_group = (
118
+ isinstance(value, TransactionActivityGroup) and activity in value
119
+ )
120
+ if same_activity or same_group:
119
121
  return True
120
122
  return False
121
123
 
@@ -222,7 +224,26 @@ class _Matchmaker(ABC):
222
224
  field : str
223
225
  The string of text to be tokenized.
224
226
  """
225
- return set(wordpunct_tokenize(field.replace("'", "").casefold()))
227
+ replacements = [
228
+ # Remove disruptive punctuation
229
+ ("1-800", "1800"),
230
+ ("-", " "),
231
+ (".", " "),
232
+ (",", " "),
233
+ ("(", " "),
234
+ (")", " "),
235
+ ("'", ""),
236
+ # Standardize characters
237
+ ("&", "and"),
238
+ ("é", "e"),
239
+ ]
240
+ for original, replacement in replacements:
241
+ field = field.replace(original, replacement)
242
+ tokens = set(wordpunct_tokenize(field.replace("'", "").casefold()))
243
+ removals = ["and", "the", "of"]
244
+ for word in removals:
245
+ tokens.discard(word)
246
+ return tokens
226
247
 
227
248
  def _compute_transaction_activity_similarity_score(
228
249
  self, merchant_tokens, notes_tokens, activity_tokens
@@ -2,17 +2,10 @@
2
2
  Expose commonly used database functionality to the rest of the package.
3
3
  """
4
4
 
5
- import sqlite3
6
5
  from pathlib import Path
7
6
 
8
- import click
7
+ from dry_foundation.database import SQLAlchemy as _SQLAlchemy
9
8
  from flask import current_app
10
- from flask.cli import with_appcontext
11
- from fuisce.database import SQLAlchemy as _SQLAlchemy
12
-
13
- from ..core.actions import get_timestamp
14
-
15
- BASE_DB_NAME = f"monopyly.sqlite"
16
9
 
17
10
 
18
11
  class SQLAlchemy(_SQLAlchemy):
@@ -48,54 +41,3 @@ class SQLAlchemy(_SQLAlchemy):
48
41
  raw_conn.close()
49
42
  # Top level initialization does not overwrite tables, so it goes at the end
50
43
  super().initialize(app)
51
-
52
-
53
- SQLAlchemy.create_default_interface(echo_engine=False)
54
-
55
-
56
- @click.command("init-db")
57
- @with_appcontext
58
- def init_db_command():
59
- """Initialize the database from the command line (if it does not exist)."""
60
- db_path = current_app.config["DATABASE"]
61
- if not db_path.is_file():
62
- current_app.db.initialize(current_app)
63
- click.echo(f"Initialized the database ('{db_path}')")
64
- preload_path = current_app.config.get("PRELOAD_DATA_PATH")
65
- if preload_path:
66
- click.echo(f"Prepopulated the database using '{preload_path}'")
67
- else:
68
- click.echo(f"Database exists, using '{db_path}'")
69
-
70
-
71
- @click.command("back-up-db")
72
- @with_appcontext
73
- def back_up_db_command():
74
- """Back up the database from the command line."""
75
- timestamp = get_timestamp()
76
- # Connect to the database
77
- db = sqlite3.connect(current_app.config["DATABASE"])
78
- # Create and connect to the backup database
79
- backup_db_dir_path = Path(current_app.instance_path) / "db_backups"
80
- backup_db_dir_path.mkdir(exist_ok=True, parents=True)
81
- backup_db_path = backup_db_dir_path / f"backup_{timestamp}.sqlite"
82
- backup_db = sqlite3.connect(backup_db_path)
83
- # Back up the database and print status
84
- back_up_db(db, backup_db)
85
- click.echo(f"Backup complete ({timestamp})")
86
-
87
-
88
- def back_up_db(db, backup_db):
89
- """Create a backup of the database."""
90
- # Backup the database
91
- with backup_db:
92
- db.backup(backup_db)
93
- # Close the connections
94
- backup_db.close()
95
- db.close()
96
-
97
-
98
- def register_db_cli_commands(app):
99
- """Register database CLI commands with the app."""
100
- app.cli.add_command(init_db_command)
101
- app.cli.add_command(back_up_db_command)