Merge code from deployed production version

This commit is contained in:
TMA 2025-03-30 20:58:03 +02:00
commit 5f9292fd02
15 changed files with 169 additions and 14 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
.*.sw?
*~

2
brmbar3/.gitignore vendored
View file

@ -1 +1,3 @@
__pycache__
*.log
brmbar/*.pyc

64
brmbar3/PURGE.txt Normal file
View file

@ -0,0 +1,64 @@
How to "reset" the database - drop all history and keep only accounts with non-zero balance.
Legend:
> - SQL commands
$ - shell commands
Run the (full) inventory.
Get number of the first inventory TX.
> select id from account_balances where id in (select id from accounts where currency not in (select distinct currency from
transaction_nicesplits where transaction >= NUMBER_HERE and currency != 1 and memo like '%Inventory fix%') and acctype = 'inventory') and crbalance != 0 \g 'vynulovat'
$ ./brmbar-cli.py inventory `cat vynulovat | while read x; do echo $x 0; done`
Backup the database
$ pg_dump brmbar > backup.sql
Dump "> SELECT * FROM account_balances;" to file N.
Dump inventory to file nastavit FIXME.
Drop all transactions:
> delete from transaction_splits;
> delete from transactions;
Restore inventory:
$ cat nastavit | while read acc p amt; do ./brmbar-cli.py inventory $acc `echo $amt | grep -oE "^[0-9-]+"`; done
Restore cash balance:
$ cat N | grep debt | tr -s " " |cut -d \| -f 2,4 | while read acc p amt; do ./brmbar-cli.py changecredit $acc `echo $amt | grep -oE "^[0-9-]+"`; done
Delete zero-balance accounts:
> delete from accounts where accounts.id not in (select id from account_balances);
Delete orphaned barcodes:
> delete from barcodes where barcodes.account not in (select id from account_balances);
Delete orphaned currencies and exchange rates:
> CREATE OR REPLACE VIEW "a_tmp" AS
SELECT ts.account AS id, accounts.name, accounts.acctype, accounts.currency AS fff, (- sum(CASE WHEN (ts.side = 'credit'::transaction_split_side) THEN (- ts.amount) ELSE ts.amount END)) AS crbalance FROM (transaction_splits ts LEFT JOIN accounts ON ((accounts.id = ts.account))) GROUP BY ts.account, accounts.name, accounts.id, accounts.acctype ORDER BY (- sum(CASE WHEN (ts.side = 'credit'::transaction_split_side) THEN (- ts.amount) ELSE ts.amount END));
> delete from exchange_rates where source not in (select fff from a_tmp);
> delete from currencies where id not in (select fff from a_tmp);
> DROP VIEW "a_tmp";
Drop obsolete exchange rates:
> delete from exchange_rates where
valid_since <> (SELECT max(valid_since)
FROM exchange_rates e
WHERE e.target = exchange_rates.target and e.source = exchange_rates.source)
Restore system accounts:
> INSERT INTO "accounts" ("name", "currency", "acctype", "active")
VALUES ('BrmBar Profits', '1', 'income', '1');
> INSERT INTO "accounts" ("name", "currency", "acctype", "active")
VALUES ('BrmBar Excess', '1', 'income', '1');
> INSERT INTO "accounts" ("name", "currency", "acctype", "active")
VALUES ('BrmBar Deficit', '1', 'expense', '1');
> INSERT INTO "accounts" ("name", "currency", "acctype", "active")
VALUES ('BrmBar Cash', '1', 'cash', '1');
Restart brmbar.

View file

@ -107,10 +107,9 @@ CREATE VIEW transaction_nicesplits AS
FROM transaction_splits AS ts LEFT JOIN accounts AS a ON a.id = ts.account
ORDER BY ts.id;
-- List transactions with summary information regarding their cash element
-- (except in case of transfers between cash and debt accounts, which will cancel out).
-- List transactions with summary information regarding their cash element.
CREATE VIEW transaction_cashsums AS
SELECT t.id AS id, t.time AS time, SUM(credit_cash) AS cash_credit, SUM(debit_cash) AS cash_debit, t.description AS description
SELECT t.id AS id, t.time AS time, SUM(credit_cash) AS cash_credit, SUM(debit_cash) AS cash_debit, a.name AS responsible, t.description AS description
FROM transactions AS t
LEFT JOIN (SELECT cts.amount AS credit_cash, cts.transaction AS cts_t
FROM transaction_nicesplits AS cts
@ -124,4 +123,5 @@ CREATE VIEW transaction_cashsums AS
WHERE a.currency = (SELECT currency FROM accounts WHERE name = 'BrmBar Cash')
AND a.acctype IN ('cash', 'debt')
AND dts.amount > 0) debit ON dts_t = t.id
GROUP BY t.id ORDER BY t.id;
LEFT JOIN accounts AS a ON a.id = t.responsible
GROUP BY t.id, a.name ORDER BY t.id DESC;

8
brmbar3/USEFUL.txt Normal file
View file

@ -0,0 +1,8 @@
Accounts with multiple barcodes:
SELECT accounts.name,barcodes.account,barcodes.barcode
FROM "barcodes"
join accounts on accounts.id = barcodes.account
where barcodes.account in (select a from (select count(*) as c, account as a from barcodes group by account) as dt where c > 1)
ORDER BY "account" DESC

42
brmbar3/autostock.py Executable file
View file

@ -0,0 +1,42 @@
#! /usr/bin/env python3
import argparse
import brmbar
import math
from brmbar import Database
def main():
parser = argparse.ArgumentParser(usage = "File format: EAN amount total_price name, e.g. 4001242002377 6 167.40 Chio Tortillas")
parser.add_argument("filename")
args = parser.parse_args()
db = Database.Database("dbname=brmbar")
shop = brmbar.Shop.new_with_defaults(db)
currency = shop.currency
# ...
total = 0
with open(args.filename) as fin:
for line in fin:
split = line.split(" ")
ean, amount, price_total, name = split[0], int(split[1]), float(split[2]), " ".join(split[3:])
name = name.strip()
price_buy = price_total / amount
acct = brmbar.Account.load_by_barcode(db, ean)
if not acct:
print("Creating account for EAN {} '{}'".format(ean, name))
invcurr = brmbar.Currency.create(db, name)
acct = brmbar.Account.create(db, name, invcurr, "inventory")
acct.add_barcode(ean)
price_sell = max(math.ceil(price_buy * 1.15), price_buy)
acct.currency.update_sell_rate(currency, price_sell)
acct.currency.update_buy_rate(currency, price_buy)
cash = shop.buy_for_cash(acct, amount)
total += cash
print("Increased by {}, take {} from cashbox".format(amount, cash))
print("Total is {}".format(total))
if __name__ == "__main__":
main()

View file

@ -97,6 +97,12 @@ def load_item(inp):
exit(1)
return acct
def load_item_by_barcode(inp):
acct = brmbar.Account.load_by_barcode(db, inp)
if acct.acctype != "inventory":
print("Bad EAN " + inp + " type " + acct.acctype, file=sys.stderr)
exit(1)
return acct
db = Database.Database("dbname=brmbar")
shop = brmbar.Shop.new_with_defaults(db)
@ -147,9 +153,9 @@ elif sys.argv[1] == "userlog":
acct = load_user(sys.argv[2])
timestamp = sys.argv[3]
res = db.execute_and_fetchall("SELECT transactions.time,transactions.description FROM transactions INNER JOIN accounts ON accounts.id=transactions.responsible WHERE accounts.name=%s and time > TIMESTAMP %s ORDER BY time", [acct.name,timestamp])
res = db.execute_and_fetchall("SELECT * FROM transaction_cashsums WHERE responsible=%s and time > TIMESTAMP %s ORDER BY time", [acct.name,timestamp])
for transaction in res:
print("{}\t{}\t".format(transaction[0],transaction[1]))
print('\t'.join([str(f) for f in transaction]))
elif sys.argv[1] == "iteminfo":
acct = load_item(sys.argv[2])
@ -245,16 +251,16 @@ elif sys.argv[1] == "consolidate":
else:
shop.consolidate()
elif sys.argv[1] == "restock":
elif sys.argv[1] in {"restock", "restock_ean"}:
if (len(sys.argv) != 4):
print ("Invalid number of parameters, check your parameters.")
else:
iacct = load_item(sys.argv[2])
iacct = (load_item if sys.argv[1] == "restock" else load_item_by_barcode)(sys.argv[2])
oldbal = iacct.balance()
amt = int(sys.argv[3])
cash = shop.buy_for_cash(iacct, amt);
print("Old amount {}, increased by {}, take {} from cashbox".format(oldbal, amt, cash))
else:
help()

View file

@ -39,6 +39,14 @@ class ShopAdapter(QtCore.QObject):
map["price"] = str(sell)
return map
def acct_inventory_map2(self, acct):
buy, sell = 666, 666
map = acct.__dict__.copy()
map["balance"] = "{:.0f}".format(666)
map["buy_price"] = str(buy)
map["price"] = str(sell)
return map
def acct_cash_map(self, acct):
map = acct.__dict__.copy()
return map
@ -164,7 +172,7 @@ class ShopAdapter(QtCore.QObject):
@QtCore.Slot('QVariant', result='QVariant')
def itemList(self, query):
alist = [ self.acct_inventory_map(a) for a in shop.account_list("inventory", like_str="%%"+query+"%%") ]
alist = [ self.acct_inventory_map2(a) for a in shop.account_list("inventory", like_str="%%"+query+"%%") ]
db.commit()
return alist

View file

@ -107,7 +107,7 @@ Item {
status_text.setStatus("Charged "+amount+"! "+username+"'s credit is "+balance+".", "#ffff7c")
} else {
balance = shop.withdrawCredit((amount*(-1)), userdbid)
status_text.setStatus("Withdrawn "+amount+"! "+username+"'s credit is "+balance+".", "#ffff7c")
status_text.setStatus("Withdrawn "+amount+"! "+username+"'s credit is "+balance+".", "#ffff7c")
}
}
loadPage("MainPage")

View file

@ -58,6 +58,6 @@ Item {
x: 65
y: 438
width: 1150
text: "* Mroze a Termixy najdes v lednici *"
text: "* Za uklid brmlabu vam nabijeme kredit. *"
}
}

View file

@ -106,7 +106,7 @@ Item {
if(amount>=0) {
balance = shop.withdrawCredit(amount, userdbid)
status_text.setStatus("Withdrawn "+amount+"! "+username+"'s credit is "+balance+".", "#ffff7c")
} else {
} else {
balance = shop.chargeCredit((amount*(-1)),userdbid)
status_text.setStatus("Charged "+amount+"! "+username+"'s credit is "+balance+".", "#ffff7c")
}

15
brmbar3/crontab Normal file
View file

@ -0,0 +1,15 @@
# cleanup bounty
*/5 * * * * ~/brmbar/brmbar3/uklid-watchdog.sh
0 0 * * 1 ~/brmbar/brmbar3/uklid-refill.sh
# overall summary
5 4 * * * ~/brmbar/brmbar3/daily-summary.sh | mail -s "daily brmbar summary" yyy@yyy
# debt track
5 0 * * * ~/brmbar/brmbar3/dluhy.sh 2>/dev/null
# per-user summary
1 0 * * * /home/brmlab/brmbar/brmbar3/log.sh yyy yyy@yyy
# backup
6 * * * * echo "SELECT * FROM account_balances;" | psql brmbar | gzip -9 | ssh -Tp 110 -i /home/brmlab/.ssh/id_ecdsa jenda@coralmyn.hrach.eu
16 1 * * * pg_dump brmbar | gzip -9 | ssh -Tp 110 -i /home/brmlab/.ssh/id_ecdsa jenda@coralmyn.hrach.eu

3
brmbar3/dluhy.sh Executable file
View file

@ -0,0 +1,3 @@
p1=`echo -n "brmbar - dluhy: "; echo "SELECT name, crbalance FROM account_balances WHERE acctype = 'debt' AND crbalance < -100 AND name NOT LIKE '%overflow%' AND name NOT LIKE 'sachyo' ORDER BY crbalance ASC" | psql brmbar | tail -n +3 | grep '|' | tr -s " " | sed -e "s/ |/:/g" -e "s/$/;/" | tr -d "\n"`
p2=`echo "SELECT sum(crbalance) FROM account_balances WHERE acctype = 'debt' AND crbalance < 0 AND name NOT LIKE '%overflow%' AND name NOT LIKE 'sachyo'" | psql brmbar | tail -n +3 | head -n 1 | tr -s " "`
echo "$p1 total$p2 Kc. https://www.elektro-obojky.cz/" | ssh -p 110 -i /home/brmlab/.ssh/id_rsa jenda@coralmyn.hrach.eu

6
brmbar3/log.sh Executable file
View file

@ -0,0 +1,6 @@
#!/bin/bash
p=`/home/brmlab/brmbar/brmbar3/brmbar-cli.py userlog "$1" yesterday`
if [ -n "$p" ]; then
echo "$p" | mail -s "brmbar report" "$2"
fi

View file

@ -13,6 +13,6 @@ if [ ! -z "$RES" ]; then
if [ -z "$WINNER" ]; then
WINNER="anonymous hunter"
fi
echo "Brmlab cleanup bounty was claimed by $WINNER! Thanks!"|ssh jenda@fry.hrach.eu
echo "Brmlab cleanup bounty was claimed by $WINNER! Thanks!"|ssh -p 110 jenda@coralmyn.hrach.eu
fi