forked from brmlab/brmbar-github
Merge code from deployed production version
This commit is contained in:
commit
5f9292fd02
15 changed files with 169 additions and 14 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
.*.sw?
|
||||
*~
|
||||
|
|
2
brmbar3/.gitignore
vendored
2
brmbar3/.gitignore
vendored
|
@ -1 +1,3 @@
|
|||
__pycache__
|
||||
*.log
|
||||
brmbar/*.pyc
|
||||
|
|
64
brmbar3/PURGE.txt
Normal file
64
brmbar3/PURGE.txt
Normal 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.
|
|
@ -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
8
brmbar3/USEFUL.txt
Normal 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
42
brmbar3/autostock.py
Executable 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()
|
||||
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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. *"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
15
brmbar3/crontab
Normal 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
3
brmbar3/dluhy.sh
Executable 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
6
brmbar3/log.sh
Executable 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
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue