Skip to content

Commit

Permalink
Credit limit field was added to 'accounts' table. It is used for calc…
Browse files Browse the repository at this point in the history
…ulations in Balances view.
  • Loading branch information
titov-vv committed Nov 12, 2024
1 parent e4307f5 commit deeb0d1
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 8 deletions.
10 changes: 7 additions & 3 deletions jal/db/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def __init__(self, account_id: int = 0, data: dict = None, search: bool = False,
"INSERT INTO accounts (name, active, investing, number, currency_id, organization_id, "
"country_id, precision) "
"VALUES(:name, 1, :investing, :number, :currency, :organization, "
"coalesce((SELECT id FROM countries WHERE code=:country), 0), :precision)",
"coalesce((SELECT id FROM countries WHERE code=:country), 0), :precision, 0)",
[(":name", data['name']), (":investing", data['investing']), (":number", data['number']),
(":currency", data['currency']), (":organization", data['organization']),
(":country", data['country']), (":precision", data['precision'])], commit=True)
Expand All @@ -48,6 +48,7 @@ def __init__(self, account_id: int = 0, data: dict = None, search: bool = False,
self._country = JalCountry(self._data['country_id']) if self._data is not None else JalCountry(0)
self._reconciled = int(self._data['reconciled_on']) if self._data is not None else 0
self._precision = int(self._data['precision']) if self._data is not None else Setup.DEFAULT_ACCOUNT_PRECISION
self._credit_limit = Decimal(self._data['credit']) if self._data is not None else Decimal('0')

def invalidate_cache(self):
self._fetch_data()
Expand Down Expand Up @@ -217,6 +218,9 @@ def reconcile(self, timestamp: int):
def precision(self) -> int:
return self._precision

def credit_limit(self) -> Decimal:
return self._credit_limit

def last_operation_date(self) -> int:
last_timestamp = self._read("SELECT MAX(o.timestamp) FROM operation_sequence AS o "
"LEFT JOIN accounts AS a ON o.account_id=a.id WHERE a.id=:account_id",
Expand Down Expand Up @@ -393,8 +397,8 @@ def __copy_similar_account(self, similar_id: int, data: dict) -> int:
else:
name = similar.name() + '.' + new_currency.symbol()
query = self._exec(
"INSERT INTO accounts (name, currency_id, active, investing, number, organization_id, country_id, precision) "
"SELECT :name, :currency, active, investing, number, organization_id, country_id, precision "
"INSERT INTO accounts (name, currency_id, active, investing, number, organization_id, country_id, precision, credit) "
"SELECT :name, :currency, active, investing, number, organization_id, country_id, precision, credit "
"FROM accounts WHERE id=:id", [(":id", similar.id()), (":name", name), (":currency", new_currency.id())])
return query.lastInsertId()

Expand Down
9 changes: 8 additions & 1 deletion jal/db/balances_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ def __init__(self, parent_view):
self._currency = 0
self._currency_name = ''
self._active_only = not JalSettings().getValue("ShowInactiveAccountBalances", False)
self._use_credit = JalSettings().getValue("UseAccountCreditLimit", True)
self._date = QDate.currentDate().endOfDay(Qt.UTC).toSecsSinceEpoch()
self.bold_font = QFont()
self.bold_font.setBold(True)
Expand Down Expand Up @@ -178,6 +179,12 @@ def showInactiveAccounts(self, state: bool):
JalSettings().setValue("ShowInactiveAccountBalances", state)
self.prepareData()

@Slot()
def useCreditLimits(self, state: bool):
self._use_credit = state
JalSettings().setValue("UseAccountCreditLimit", state)
self.prepareData()

def getAccountId(self, index):
if not index.isValid():
return 0
Expand All @@ -202,7 +209,7 @@ def prepareData(self):
"account_name": account.name(),
"currency": account.currency(),
"currency_name": JalAsset(account.currency()).symbol(),
"value": value,
"value": value + account.credit_limit() if self._use_credit else value,
"value_common": value * rate,
"unreconciled": (account.last_operation_date() - account.reconciled_at())/86400,
"active": account.is_active(),
Expand Down
6 changes: 4 additions & 2 deletions jal/jal_init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ CREATE TABLE accounts (
name TEXT (64) NOT NULL UNIQUE, -- human-readable name of the account
currency_id INTEGER REFERENCES assets (id) ON DELETE RESTRICT ON UPDATE CASCADE NOT NULL, -- accounting currency for the account
active INTEGER DEFAULT (1) NOT NULL ON CONFLICT REPLACE, -- 1 = account is active, 0 = inactive (hidden in UI)
investing INTEGER NOT NULL DEFAULT (0), -- 1 if account can hold investment assets, 0 otherwise
investing INTEGER DEFAULT (0) NOT NULL, -- 1 if account can hold investment assets, 0 otherwise
tag_id INTEGER REFERENCES tags (id) ON DELETE SET NULL ON UPDATE CASCADE, -- optional tag of the account
number TEXT (32), -- human-readable number of account (as a reference to bank/broker documents)
reconciled_on INTEGER DEFAULT (0) NOT NULL ON CONFLICT REPLACE, -- timestamp of last confirmed operation
organization_id INTEGER REFERENCES agents (id) ON DELETE SET DEFAULT ON UPDATE CASCADE NOT NULL DEFAULT (1), -- Bank/Broker that handles account
country_id INTEGER REFERENCES countries (id) ON DELETE SET DEFAULT ON UPDATE CASCADE DEFAULT (0) NOT NULL,-- Location of the account
precision INTEGER NOT NULL DEFAULT (2) -- number of digits after decimal points that is used by this account
precision INTEGER DEFAULT (2) NOT NULL, -- number of digits after decimal points that is used by this account
credit TEXT DEFAULT ('0') NOT NULL -- credit limit for the account
);
------------------------------------------------------------------------------------------------------------------------
-- tables to store information about Income/Spending transactions
Expand Down Expand Up @@ -651,6 +652,7 @@ INSERT INTO settings(name, value) VALUES('DlgViewState_Quotes', '');
INSERT INTO settings(name, value) VALUES('DlgGeometry_Base currency', '');
INSERT INTO settings(name, value) VALUES('DlgViewState_Base currency', '');
INSERT INTO settings(name, value) VALUES('ShowInactiveAccountBalances', 0);
INSERT INTO settings(name, value) VALUES('UseAccountCreditLimit', 1);

-- Initialize available languages
INSERT INTO languages (id, language) VALUES (1, 'en');
Expand Down
3 changes: 3 additions & 0 deletions jal/updates/jal_delta_59.sql
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
BEGIN TRANSACTION;
--------------------------------------------------------------------------------
ALTER TABLE accounts ADD COLUMN credit TEXT DEFAULT ('0') NOT NULL;
--------------------------------------------------------------------------------
INSERT OR REPLACE INTO settings(name, value) VALUES('ShowInactiveAccountBalances', 0);
INSERT OR REPLACE INTO settings(name, value) VALUES('UseAccountCreditLimit', 1);
--------------------------------------------------------------------------------
-- Set new DB schema version
UPDATE settings SET value=59 WHERE name='SchemaVersion';
Expand Down
7 changes: 7 additions & 0 deletions jal/widgets/operations_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,18 @@ def balances_context_menu(self, pos):
index = self.ui.BalancesTreeView.indexAt(pos)
account_id = self.balances_model.data(index, BalancesModel.ACCOUNT_ROLE) if index.isValid() else 0
contextMenu = QMenu(self.ui.BalancesTreeView)
# Create a menu item to toggle active/inactive accounts
actionToggleInactive = QAction(self.tr("Show inactive"), self)
actionToggleInactive.setCheckable(True)
actionToggleInactive.setChecked(JalSettings().getValue("ShowInactiveAccountBalances", False))
actionToggleInactive.toggled.connect(self.ui.BalancesTreeView.model().showInactiveAccounts)
contextMenu.addAction(actionToggleInactive)
# Create a menu item to show account balance with/without credit limit
actionUseCreditLimit = QAction(self.tr("Use credit limits"), self)
actionUseCreditLimit.setCheckable(True)
actionUseCreditLimit.setChecked(JalSettings().getValue("UseAccountCreditLimit", True))
actionUseCreditLimit.toggled.connect(self.ui.BalancesTreeView.model().useCreditLimits)
contextMenu.addAction(actionUseCreditLimit)
contextMenu.addSeparator()
actionBalanceHistory = QAction(JalIcon[JalIcon.CHART], self.tr("Balance history chart"), self)
actionBalanceHistory.triggered.connect(partial(self.show_balance_history_chart, account_id))
Expand Down
8 changes: 6 additions & 2 deletions jal/widgets/reference_dialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ def __init__(self, table, parent_view, **kwargs):
("reconciled_on", self.tr("Reconciled @")),
("organization_id", self.tr("Bank/Broker")),
("country_id", self.tr("Country")),
("precision", self.tr("Precision"))]
("precision", self.tr("Precision")),
("credit", self.tr("Credit limit"))]
self._sort_by = "name"
self._group_by = "tag_id"
self._hidden = ["id"]
Expand All @@ -42,7 +43,8 @@ def __init__(self, table, parent_view, **kwargs):
self._timestamp_delegate = None
self._bool_delegate = None
self._tag_delegate = None
self._default_values = {'active': 1, 'reconciled_on': 0, 'country_id': 0, 'precision': 2}
self._float_delegate = None
self._default_values = {'active': 1, 'reconciled_on': 0, 'country_id': 0, 'precision': 2, 'credit': '0'}
self.setRelation(self.fieldIndex("currency_id"), QSqlRelation("currencies", "id", "symbol"))
self.setRelation(self.fieldIndex("country_id"), QSqlRelation("countries", "id", "code"))

Expand Down Expand Up @@ -72,6 +74,8 @@ def configureView(self):
self._view.setItemDelegateForColumn(self.fieldIndex("investing"), self._bool_delegate)
self._tag_delegate = TagSelectorDelegate(self._view)
self._view.setItemDelegateForColumn(self.fieldIndex("tag_id"), self._tag_delegate)
self._float_delegate = FloatDelegate(2, parent=self._view)
self._view.setItemDelegateForColumn(self.fieldIndex("credit"), self._float_delegate)

def removeElement(self, index) -> bool:
reply = QMessageBox().warning(None, self.tr("Warning"), self.tr("All transactions related with this account will be deleted.\n"
Expand Down

0 comments on commit deeb0d1

Please sign in to comment.