From 2ff7165becd826dbaefc5102c3cc699c0eea8da6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Pant=C5=AF=C4=8Dek?= Date: Sat, 12 Jul 2025 15:55:06 +0200 Subject: [PATCH 01/19] gui: pass database configuration as command-line options --- brmbar3/brmbar-gui-qt4.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/brmbar3/brmbar-gui-qt4.py b/brmbar3/brmbar-gui-qt4.py index 9ca11d0..fca7f03 100755 --- a/brmbar3/brmbar-gui-qt4.py +++ b/brmbar3/brmbar-gui-qt4.py @@ -9,6 +9,8 @@ from brmbar import Database import brmbar +import argparse + # User credit balance limit; sale will fail when balance is below this limit. LIMIT_BALANCE = -200 # When below this credit balance, an alert hook script (see below) is run. @@ -224,6 +226,23 @@ class ShopAdapter(QtCore.QObject): db.commit() return balance +parser = argparse.ArgumentParser() +parser.add_argument("--dbname", help="Database name", type=str) +parser.add_argument("--dbuser", help="Database user", type=str) +parser.add_argument("--dbhost", help="Database host", type=str) +parser.add_argument("--dbpass", help="Database user password", type=str) +args = parser.parse_args() +argdbname = args.dbname +argdbuser = args.dbuser +argdbhost = args.dbhost +argdbpass = args.dbpass + +db = Database.Database( + "dbname={0} user={1} host={2} password={3}".format( + argdbname,argdbuser,argdbhost,argdbpass + ) +) + db = Database.Database("dbname=brmbar") shop = brmbar.Shop.new_with_defaults(db) currency = shop.currency From 4c65f7007901ae2d595814f7e7e11f59eb0f604a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Pant=C5=AF=C4=8Dek?= Date: Sat, 12 Jul 2025 15:57:41 +0200 Subject: [PATCH 02/19] gui: remove old db initialization --- brmbar3/brmbar-gui-qt4.py | 1 - 1 file changed, 1 deletion(-) diff --git a/brmbar3/brmbar-gui-qt4.py b/brmbar3/brmbar-gui-qt4.py index fca7f03..f6027dc 100755 --- a/brmbar3/brmbar-gui-qt4.py +++ b/brmbar3/brmbar-gui-qt4.py @@ -243,7 +243,6 @@ db = Database.Database( ) ) -db = Database.Database("dbname=brmbar") shop = brmbar.Shop.new_with_defaults(db) currency = shop.currency db.commit() From 70c46bd95093e7217bbc4da16d30bd189c54006f Mon Sep 17 00:00:00 2001 From: TMA Date: Sat, 26 Jul 2025 15:15:03 +0200 Subject: [PATCH 03/19] log all sql statements --- brmbar3/brmbar/Database.py | 1 + 1 file changed, 1 insertion(+) diff --git a/brmbar3/brmbar/Database.py b/brmbar3/brmbar/Database.py index b70687c..5b844dd 100644 --- a/brmbar3/brmbar/Database.py +++ b/brmbar3/brmbar/Database.py @@ -35,6 +35,7 @@ class Database: def _execute(self, cur, query, attrs, level=1): """execute a query, and in case of OperationalError (db restart) reconnect to database. Recurses with increasig pause between tries""" + logger.debug("SQL: (%s) @%s" % (query, time.strftime("%Y%m%d %a %I:%m %p"))) try: if attrs is None: cur.execute(query) From c04d4a1f8e6add5beb3236bc37c88b4310b14e60 Mon Sep 17 00:00:00 2001 From: TMA Date: Sat, 26 Jul 2025 15:50:10 +0200 Subject: [PATCH 04/19] 0024: propagate errors in find_*_rate --- brmbar3/schema/0024-find-rates-fix.sql | 89 ++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 brmbar3/schema/0024-find-rates-fix.sql diff --git a/brmbar3/schema/0024-find-rates-fix.sql b/brmbar3/schema/0024-find-rates-fix.sql new file mode 100644 index 0000000..8dae7d8 --- /dev/null +++ b/brmbar3/schema/0024-find-rates-fix.sql @@ -0,0 +1,89 @@ +-- +-- 0024-find-rates-fix.sql +-- +-- #23 - fix stored functions find_buy_rate and find_sell_rate +-- +-- ISC License +-- +-- Copyright 2023-2025 Brmlab, z.s. +-- TMA +-- +-- Permission to use, copy, modify, and/or distribute this software +-- for any purpose with or without fee is hereby granted, provided +-- that the above copyright notice and this permission notice appear +-- in all copies. +-- +-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +-- WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +-- WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +-- CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +-- NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +-- CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +-- + +-- To require fully-qualified names +SELECT pg_catalog.set_config('search_path', '', false); + +DO $upgrade_block$ +BEGIN + +IF brmbar_privileged.has_exact_schema_version(23) THEN + +CREATE OR REPLACE FUNCTION public.find_buy_rate( + IN i_item_currency_id public.accounts.id%TYPE, + IN i_other_currency_id public.accounts.id%TYPE +) RETURNS NUMERIC +LANGUAGE plpgsql +AS $$ +DECLARE + v_rate public.exchange_rates.rate%TYPE; + v_rate_dir public.exchange_rates.rate_dir%TYPE; +BEGIN + SELECT rate, rate_dir INTO STRICT v_rate, v_rate_dir FROM public.exchange_rates WHERE target = i_item_currency_id AND source = i_other_currency_id AND valid_since <= NOW() ORDER BY valid_since DESC LIMIT 1; + IF v_rate_dir = 'target_to_source'::public.exchange_rate_direction THEN + RETURN v_rate; + ELSE + RETURN 1/v_rate; + END IF; + /* propagate error +EXCEPTION + WHEN NO_DATA_FOUND THEN + RETURN -1; + */ +END; +$$; + +-- return negative number on rate not found +CREATE OR REPLACE FUNCTION public.find_sell_rate( + IN i_item_currency_id public.accounts.id%TYPE, + IN i_other_currency_id public.accounts.id%TYPE +) RETURNS NUMERIC +LANGUAGE plpgsql +AS $$ +DECLARE + v_rate public.exchange_rates.rate%TYPE; + v_rate_dir public.exchange_rates.rate_dir%TYPE; +BEGIN + SELECT rate, rate_dir INTO STRICT v_rate, v_rate_dir FROM public.exchange_rates WHERE target = i_other_currency_id AND source = i_item_currency_id AND valid_since <= NOW() ORDER BY valid_since DESC LIMIT 1; + IF v_rate_dir = 'source_to_target'::public.exchange_rate_direction THEN + RETURN v_rate; + ELSE + RETURN 1/v_rate; + END IF; + /* propagate error +EXCEPTION + WHEN NO_DATA_FOUND THEN + RETURN -1; + */ +END; +$$; + +PERFORM brmbar_privileged.upgrade_schema_version_to(24); +END IF; + +END; +$upgrade_block$; + +-- vim: set ft=plsql : From c17aa9966695955830846bb84db697f1f166a7ec Mon Sep 17 00:00:00 2001 From: TMA Date: Sat, 26 Jul 2025 16:02:47 +0200 Subject: [PATCH 05/19] 0024: drop old versions before installing new ones --- brmbar3/schema/0024-find-rates-fix.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/brmbar3/schema/0024-find-rates-fix.sql b/brmbar3/schema/0024-find-rates-fix.sql index 8dae7d8..a196873 100644 --- a/brmbar3/schema/0024-find-rates-fix.sql +++ b/brmbar3/schema/0024-find-rates-fix.sql @@ -31,6 +31,9 @@ BEGIN IF brmbar_privileged.has_exact_schema_version(23) THEN +DROP FUNCTION IF EXISTS public.find_buy_rate(integer,integer); +DROP FUNCTION IF EXISTS public.find_sell_rate(integer,integer); + CREATE OR REPLACE FUNCTION public.find_buy_rate( IN i_item_currency_id public.accounts.id%TYPE, IN i_other_currency_id public.accounts.id%TYPE From 9afef5bce272f41dc00e4b1d33cc70bd7cdac6ed Mon Sep 17 00:00:00 2001 From: TMA Date: Sat, 26 Jul 2025 16:57:30 +0200 Subject: [PATCH 06/19] maybe make something faster --- brmbar3/brmbar/Shop.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/brmbar3/brmbar/Shop.py b/brmbar3/brmbar/Shop.py index b32f5bb..a2ef1d1 100644 --- a/brmbar3/brmbar/Shop.py +++ b/brmbar3/brmbar/Shop.py @@ -198,12 +198,13 @@ class Shop: """list all accounts (people or items, as per acctype)""" accts = [] cur = self.db.execute_and_fetchall( - "SELECT id FROM accounts WHERE acctype = %s AND name ILIKE %s ORDER BY name ASC", + "SELECT a.id, a.name aname, a.currency, a.acctype, c.name cname FROM accounts a JOIN currencies c ON c.id=a.currency WHERE a.acctype = %s AND a.name ILIKE %s ORDER BY a.name ASC", [acctype, like_str], ) # FIXME: sanitize input like_str ^ for inventory in cur: - accts += [Account.load(self.db, id=inventory[0])] + curr = Currency(db=self.db, id=inventory[2], name=inventory[4]); + accts += [Account(self.db, id=inventory[0], name=inventory[1], currency=curr, acctype=inventory[3])] return accts def fix_inventory(self, item, amount): From 54c687edf3a5b64c11053a690eeed1f8875136d6 Mon Sep 17 00:00:00 2001 From: TMA Date: Sat, 26 Jul 2025 17:12:50 +0200 Subject: [PATCH 07/19] disable slowdown in management for now --- brmbar3/brmbar-gui-qt4.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/brmbar3/brmbar-gui-qt4.py b/brmbar3/brmbar-gui-qt4.py index cb8fa46..4eb668c 100755 --- a/brmbar3/brmbar-gui-qt4.py +++ b/brmbar3/brmbar-gui-qt4.py @@ -168,21 +168,25 @@ class ShopAdapter(QtCore.QObject): @QtCore.Slot(result='QVariant') def balance_cash(self): + return "N/A" balance = shop.cash.balance_str() db.commit() return balance @QtCore.Slot(result='QVariant') def balance_profit(self): + return "N/A" balance = shop.profits.balance_str() db.commit() return balance @QtCore.Slot(result='QVariant') def balance_inventory(self): + return "N/A" balance = shop.inventory_balance_str() db.commit() return balance @QtCore.Slot(result='QVariant') def balance_credit(self): + return "N/A" balance = shop.credit_negbalance_str() db.commit() return balance From 1d9a2e9facb5b35a996015feb10ee864f95b3f3a Mon Sep 17 00:00:00 2001 From: TMA Date: Sat, 26 Jul 2025 18:26:59 +0200 Subject: [PATCH 08/19] Fix buy rate updating --- brmbar3/brmbar/Currency.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brmbar3/brmbar/Currency.py b/brmbar3/brmbar/Currency.py index 3033287..61d6a75 100644 --- a/brmbar3/brmbar/Currency.py +++ b/brmbar3/brmbar/Currency.py @@ -130,5 +130,5 @@ class Currency: def update_buy_rate(self, source, rate): self.db.execute( "SELECT public.update_currency_buy_rate(%s, %s, %s)", - [source.id, self.id, rate], + [self.id, source.id, rate], ) From 2a19bd291f6bf1417290b7185d9a19ae8e9253ab Mon Sep 17 00:00:00 2001 From: TMA Date: Thu, 21 Aug 2025 16:46:33 +0200 Subject: [PATCH 09/19] typo fix --- brmbar3/schema/0024-find-rates-fix.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brmbar3/schema/0024-find-rates-fix.sql b/brmbar3/schema/0024-find-rates-fix.sql index a196873..70bab06 100644 --- a/brmbar3/schema/0024-find-rates-fix.sql +++ b/brmbar3/schema/0024-find-rates-fix.sql @@ -1,7 +1,7 @@ -- -- 0024-find-rates-fix.sql -- --- #23 - fix stored functions find_buy_rate and find_sell_rate +-- #24 - fix stored functions find_buy_rate and find_sell_rate -- -- ISC License -- From 38a4a3def1372eb88dc34278b9375a0d5167250b Mon Sep 17 00:00:00 2001 From: TMA Date: Thu, 21 Aug 2025 16:47:45 +0200 Subject: [PATCH 10/19] 0025: account class loader procedure --- brmbar3/schema/0025-load-account.sql | 109 +++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 brmbar3/schema/0025-load-account.sql diff --git a/brmbar3/schema/0025-load-account.sql b/brmbar3/schema/0025-load-account.sql new file mode 100644 index 0000000..046328c --- /dev/null +++ b/brmbar3/schema/0025-load-account.sql @@ -0,0 +1,109 @@ +-- +-- 0025-load-account.sql +-- +-- #25 - stored procedures for account loading +-- +-- ISC License +-- +-- Copyright 2023-2025 Brmlab, z.s. +-- TMA +-- +-- Permission to use, copy, modify, and/or distribute this software +-- for any purpose with or without fee is hereby granted, provided +-- that the above copyright notice and this permission notice appear +-- in all copies. +-- +-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +-- WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +-- WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +-- CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +-- NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +-- CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +-- + +-- To require fully-qualified names +SELECT pg_catalog.set_config('search_path', '', false); + +DO $upgrade_block$ +BEGIN + +IF brmbar_privileged.has_exact_schema_version(24) THEN + +SELECT COUNT(1) INTO v + FROM pg_catalog.pg_type typ + INNER JOIN pg_catalog.pg_namespace nsp + ON nsp.oid = typ.typnamespace + WHERE nsp.nspname = 'brmbar_privileged' + AND typ.typname='account_class_initialization_data_type'; + +IF v>0 THEN + RAISE NOTICE 'Changing type account_class_initialization_data_type'; + DROP TYPE brmbar_privileged.account_class_initialization_data_type CASCADE; +ELSE + RAISE NOTICE 'Creating type account_class_initialization_data_type'; +END IF; + +SELECT COUNT(1) INTO v + FROM pg_catalog.pg_type typ + INNER JOIN pg_catalog.pg_namespace nsp + ON nsp.oid = typ.typnamespace + WHERE nsp.nspname = 'brmbar_privileged' + AND typ.typname='account_load_type'; + +IF v>0 THEN + RAISE NOTICE 'Changing type account_load_type'; + DROP TYPE brmbar_privileged.account_load_type CASCADE; +ELSE + RAISE NOTICE 'Creating type account_load_type'; +END IF; + +CREATE TYPE brmbar_privileged.account_load_type + AS ENUM ('by_id', 'by_barcode'); + +CREATE TYPE brmbar_privileged.account_class_initialization_data_type +AS ( + account_id INTEGER, --public.accounts.id%TYPE, + account_name TEXT, --public.accounts.id%TYPE, + account_acctype brmbar_privileged.accounts_type, + currency_id INTEGER, --public.currencies.id%TYPE, + currency_name TEXT +); + +CREATE OR REPLACE FUNCTION public.account_class_initialization_data( + load_by brmbar_privileged.account_load_type, + i_id INTEGER, + i_barcode TEXT) +RETURNS brmbar_privileged.account_class_initialization_data_type +LANGUAGE plpgsql +AS +$$ +DECLARE + rv brmbar_privileged.account_class_initialization_data_type; +BEGIN + IF load_by = 'by_id' THEN + SELECT a.id, a.name, a.acctype, c.id, c.name + INTO STRICT rv.account_id, rv.account_name, rv.account_acctype, rv.currency_id, rv.currency_name + FROM public.accounts a JOIN public.currencies c ON a.currency = c.id + WHERE a.id = i_id; + ELSE -- by_barcode + SELECT a.id, a.name, a.acctype, c.id, c.name + INTO STRICT rv.account_id, rv.account_name, rv.account_acctype, rv.currency_id, rv.currency_name + FROM public.accounts a JOIN public.currencies c ON a.currency = c.id JOIN public.barcodes b ON b.account = a.id + WHERE b.barcode = i_barcode; + END IF; + + RETURN rv; +END; +$$; + + + +PERFORM brmbar_privileged.upgrade_schema_version_to(25); +END IF; + +END; +$upgrade_block$; + +-- vim: set ft=plsql : From 89fb60bab51ab2510d070f3eb150c338b1908924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Pant=C5=AF=C4=8Dek?= Date: Thu, 21 Aug 2025 16:49:44 +0200 Subject: [PATCH 11/19] Use account loading stored procedure for Account construction. --- brmbar3/brmbar/Account.py | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/brmbar3/brmbar/Account.py b/brmbar3/brmbar/Account.py index 3a25170..f1310da 100644 --- a/brmbar3/brmbar/Account.py +++ b/brmbar3/brmbar/Account.py @@ -20,24 +20,22 @@ class Account: @classmethod def load_by_barcode(cls, db, barcode): logger.debug("load_by_barcode: '%s'", barcode) - res = db.execute_and_fetch( - "SELECT account FROM barcodes WHERE barcode = %s", [barcode] - ) - if res is None: - return None - id = res[0] - return cls.load(db, id=id) + account_id, account_name, account_acctype, currency_id, currency_name = db_execute_and_fetch( + "SELECT account_id, account_name, account_acctype, currency_id, currency_name + FROM public.account_class_initialization_data('by_barcode', NULL, %s)", + [barcode]) + currency = Currency(db, currency_id, currency_name) + return cls(db, account_id, account_name, currency, account_acctype) @classmethod def load(cls, db, id=None): """Constructor for existing account""" - if id is None: - raise NameError("Account.load(): Specify id") - name, currid, acctype = db.execute_and_fetch( - "SELECT name, currency, acctype FROM accounts WHERE id = %s", [id] - ) - currency = Currency.load(db, id=currid) - return cls(db, name=name, id=id, currency=currency, acctype=acctype) + account_id, account_name, account_acctype, currency_id, currency_name = db_execute_and_fetch( + "SELECT account_id, account_name, account_acctype, currency_id, currency_name + FROM public.account_class_initialization_data('by_id', %s, NULL)", + [id]) + currency = Currency(db, currency_id, currency_name) + return cls(db, account_id, account_name, currency, account_acctype) @classmethod def create(cls, db, name, currency, acctype): From c2ddab9ce824f677319c17d7bc581ca47a678cf9 Mon Sep 17 00:00:00 2001 From: TMA Date: Thu, 21 Aug 2025 16:54:56 +0200 Subject: [PATCH 12/19] 0025: declare v --- brmbar3/schema/0025-load-account.sql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/brmbar3/schema/0025-load-account.sql b/brmbar3/schema/0025-load-account.sql index 046328c..6a83fec 100644 --- a/brmbar3/schema/0025-load-account.sql +++ b/brmbar3/schema/0025-load-account.sql @@ -27,6 +27,8 @@ SELECT pg_catalog.set_config('search_path', '', false); DO $upgrade_block$ +DECLARE + v INTEGER; BEGIN IF brmbar_privileged.has_exact_schema_version(24) THEN @@ -93,7 +95,7 @@ BEGIN FROM public.accounts a JOIN public.currencies c ON a.currency = c.id JOIN public.barcodes b ON b.account = a.id WHERE b.barcode = i_barcode; END IF; - + -- RETURN rv; END; $$; From 1e324c092060c82ed8637d8ef60b0a0c4b42025f Mon Sep 17 00:00:00 2001 From: TMA Date: Thu, 21 Aug 2025 16:58:59 +0200 Subject: [PATCH 13/19] 0025: it's public.account_type --- brmbar3/schema/0025-load-account.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brmbar3/schema/0025-load-account.sql b/brmbar3/schema/0025-load-account.sql index 6a83fec..efc2a8d 100644 --- a/brmbar3/schema/0025-load-account.sql +++ b/brmbar3/schema/0025-load-account.sql @@ -68,7 +68,7 @@ CREATE TYPE brmbar_privileged.account_class_initialization_data_type AS ( account_id INTEGER, --public.accounts.id%TYPE, account_name TEXT, --public.accounts.id%TYPE, - account_acctype brmbar_privileged.accounts_type, + account_acctype public.accounts_type, currency_id INTEGER, --public.currencies.id%TYPE, currency_name TEXT ); From 57f36dd2f502934e5c0349dc7f066ed2bef0ae7f Mon Sep 17 00:00:00 2001 From: TMA Date: Thu, 21 Aug 2025 17:01:57 +0200 Subject: [PATCH 14/19] 0025: it's public.account_type, FRFR --- brmbar3/schema/0025-load-account.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brmbar3/schema/0025-load-account.sql b/brmbar3/schema/0025-load-account.sql index efc2a8d..3076e0b 100644 --- a/brmbar3/schema/0025-load-account.sql +++ b/brmbar3/schema/0025-load-account.sql @@ -68,7 +68,7 @@ CREATE TYPE brmbar_privileged.account_class_initialization_data_type AS ( account_id INTEGER, --public.accounts.id%TYPE, account_name TEXT, --public.accounts.id%TYPE, - account_acctype public.accounts_type, + account_acctype public.account_type, currency_id INTEGER, --public.currencies.id%TYPE, currency_name TEXT ); From dd8c93e967436affdb9fbc1f52fbad7c4eae9874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Pant=C5=AF=C4=8Dek?= Date: Thu, 21 Aug 2025 17:10:03 +0200 Subject: [PATCH 15/19] Fix string literal. --- brmbar3/brmbar/Account.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/brmbar3/brmbar/Account.py b/brmbar3/brmbar/Account.py index f1310da..b5b69a4 100644 --- a/brmbar3/brmbar/Account.py +++ b/brmbar3/brmbar/Account.py @@ -21,8 +21,7 @@ class Account: def load_by_barcode(cls, db, barcode): logger.debug("load_by_barcode: '%s'", barcode) account_id, account_name, account_acctype, currency_id, currency_name = db_execute_and_fetch( - "SELECT account_id, account_name, account_acctype, currency_id, currency_name - FROM public.account_class_initialization_data('by_barcode', NULL, %s)", + "SELECT account_id, account_name, account_acctype, currency_id, currency_name FROM public.account_class_initialization_data('by_barcode', NULL, %s)", [barcode]) currency = Currency(db, currency_id, currency_name) return cls(db, account_id, account_name, currency, account_acctype) @@ -31,8 +30,7 @@ class Account: def load(cls, db, id=None): """Constructor for existing account""" account_id, account_name, account_acctype, currency_id, currency_name = db_execute_and_fetch( - "SELECT account_id, account_name, account_acctype, currency_id, currency_name - FROM public.account_class_initialization_data('by_id', %s, NULL)", + "SELECT account_id, account_name, account_acctype, currency_id, currency_name FROM public.account_class_initialization_data('by_id', %s, NULL)", [id]) currency = Currency(db, currency_id, currency_name) return cls(db, account_id, account_name, currency, account_acctype) From e604e0000b0bcb188ba96078096a70697deb2951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Pant=C5=AF=C4=8Dek?= Date: Thu, 21 Aug 2025 17:12:14 +0200 Subject: [PATCH 16/19] Fix db. --- brmbar3/brmbar/Account.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/brmbar3/brmbar/Account.py b/brmbar3/brmbar/Account.py index b5b69a4..2499d05 100644 --- a/brmbar3/brmbar/Account.py +++ b/brmbar3/brmbar/Account.py @@ -20,7 +20,7 @@ class Account: @classmethod def load_by_barcode(cls, db, barcode): logger.debug("load_by_barcode: '%s'", barcode) - account_id, account_name, account_acctype, currency_id, currency_name = db_execute_and_fetch( + account_id, account_name, account_acctype, currency_id, currency_name = db.execute_and_fetch( "SELECT account_id, account_name, account_acctype, currency_id, currency_name FROM public.account_class_initialization_data('by_barcode', NULL, %s)", [barcode]) currency = Currency(db, currency_id, currency_name) @@ -29,7 +29,7 @@ class Account: @classmethod def load(cls, db, id=None): """Constructor for existing account""" - account_id, account_name, account_acctype, currency_id, currency_name = db_execute_and_fetch( + account_id, account_name, account_acctype, currency_id, currency_name = db.execute_and_fetch( "SELECT account_id, account_name, account_acctype, currency_id, currency_name FROM public.account_class_initialization_data('by_id', %s, NULL)", [id]) currency = Currency(db, currency_id, currency_name) From aee3a1d24f1ae93b24fc2b110d28916684396bf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Pant=C5=AF=C4=8Dek?= Date: Thu, 21 Aug 2025 17:12:22 +0200 Subject: [PATCH 17/19] Fix db 2. --- brmbar3/brmbar/Account.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/brmbar3/brmbar/Account.py b/brmbar3/brmbar/Account.py index 2499d05..e54ea8d 100644 --- a/brmbar3/brmbar/Account.py +++ b/brmbar3/brmbar/Account.py @@ -20,7 +20,7 @@ class Account: @classmethod def load_by_barcode(cls, db, barcode): logger.debug("load_by_barcode: '%s'", barcode) - account_id, account_name, account_acctype, currency_id, currency_name = db.execute_and_fetch( + account_id, account_name, account_acctype, currency_id, currency_name = self.db.execute_and_fetch( "SELECT account_id, account_name, account_acctype, currency_id, currency_name FROM public.account_class_initialization_data('by_barcode', NULL, %s)", [barcode]) currency = Currency(db, currency_id, currency_name) @@ -29,7 +29,7 @@ class Account: @classmethod def load(cls, db, id=None): """Constructor for existing account""" - account_id, account_name, account_acctype, currency_id, currency_name = db.execute_and_fetch( + account_id, account_name, account_acctype, currency_id, currency_name = self.db.execute_and_fetch( "SELECT account_id, account_name, account_acctype, currency_id, currency_name FROM public.account_class_initialization_data('by_id', %s, NULL)", [id]) currency = Currency(db, currency_id, currency_name) From 92deae67753fa935fb367ea3d459424cab485f2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Pant=C5=AF=C4=8Dek?= Date: Thu, 21 Aug 2025 17:13:30 +0200 Subject: [PATCH 18/19] Fix db 3. --- brmbar3/brmbar/Account.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/brmbar3/brmbar/Account.py b/brmbar3/brmbar/Account.py index e54ea8d..2499d05 100644 --- a/brmbar3/brmbar/Account.py +++ b/brmbar3/brmbar/Account.py @@ -20,7 +20,7 @@ class Account: @classmethod def load_by_barcode(cls, db, barcode): logger.debug("load_by_barcode: '%s'", barcode) - account_id, account_name, account_acctype, currency_id, currency_name = self.db.execute_and_fetch( + account_id, account_name, account_acctype, currency_id, currency_name = db.execute_and_fetch( "SELECT account_id, account_name, account_acctype, currency_id, currency_name FROM public.account_class_initialization_data('by_barcode', NULL, %s)", [barcode]) currency = Currency(db, currency_id, currency_name) @@ -29,7 +29,7 @@ class Account: @classmethod def load(cls, db, id=None): """Constructor for existing account""" - account_id, account_name, account_acctype, currency_id, currency_name = self.db.execute_and_fetch( + account_id, account_name, account_acctype, currency_id, currency_name = db.execute_and_fetch( "SELECT account_id, account_name, account_acctype, currency_id, currency_name FROM public.account_class_initialization_data('by_id', %s, NULL)", [id]) currency = Currency(db, currency_id, currency_name) From f6128ecc4a9d2f487843cbc70e074188b981b380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Pant=C5=AF=C4=8Dek?= Date: Thu, 28 Aug 2025 16:58:33 +0200 Subject: [PATCH 19/19] Currency.py: remove unused methods - rates2, convert --- brmbar3/brmbar/Currency.py | 51 -------------------------------------- 1 file changed, 51 deletions(-) diff --git a/brmbar3/brmbar/Currency.py b/brmbar3/brmbar/Currency.py index 61d6a75..fba3059 100644 --- a/brmbar3/brmbar/Currency.py +++ b/brmbar3/brmbar/Currency.py @@ -67,57 +67,6 @@ class Currency: return (buy, sell) - def rates2(self, other): - # the original code for compare testing - res = self.db.execute_and_fetch( - "SELECT rate, rate_dir FROM exchange_rates WHERE target = %s AND source = %s AND valid_since <= NOW() ORDER BY valid_since DESC LIMIT 1", - [self.id, other.id], - ) - if res is None: - raise NameError( - "Currency.rate(): Unknown conversion " - + other.name() - + " to " - + self.name() - ) - buy_rate, buy_rate_dir = res - buy = buy_rate if buy_rate_dir == "target_to_source" else 1 / buy_rate - - res = self.db.execute_and_fetch( - "SELECT rate, rate_dir FROM exchange_rates WHERE target = %s AND source = %s AND valid_since <= NOW() ORDER BY valid_since DESC LIMIT 1", - [other.id, self.id], - ) - if res is None: - raise NameError( - "Currency.rate(): Unknown conversion " - + self.name() - + " to " - + other.name() - ) - sell_rate, sell_rate_dir = res - sell = sell_rate if sell_rate_dir == "source_to_target" else 1 / sell_rate - - return (buy, sell) - - def convert(self, amount, target): - res = self.db.execute_and_fetch( - "SELECT rate, rate_dir FROM exchange_rates WHERE target = %s AND source = %s AND valid_since <= NOW() ORDER BY valid_since DESC LIMIT 1", - [target.id, self.id], - ) - if res is None: - raise NameError( - "Currency.convert(): Unknown conversion " - + self.name() - + " to " - + target.name() - ) - rate, rate_dir = res - if rate_dir == "source_to_target": - resamount = amount * rate - else: - resamount = amount / rate - return resamount - def str(self, amount): return "{:.2f} {}".format(amount, self.name)