brmbar-github/brmbar3/brmbar/Account.py
Petr Baudis 3a81c9fec2 Rewrite brmbar v3 in Python because Perl has lousy Qt bindings
Complete 1:1 reimplementation of existing Perl codebase.
2012-09-05 01:31:05 +02:00

80 lines
2.8 KiB
Python

from .Currency import Currency
import psycopg2
from contextlib import closing
class Account:
""" BrmBar Account
Both users and items are accounts. So is the money box, etc.
Each account has a currency."""
def __init__(self, db, id, name, currency, acctype):
self.db = db
self.id = id
self.name = name
self.currency = currency
self.acctype = acctype
@classmethod
def load_by_barcode(cls, db, barcode):
with closing(db.cursor()) as cur:
cur.execute("SELECT account FROM barcodes WHERE barcode = %s", [barcode])
res = cur.fetchone()
if res is None:
return None
id = res[0]
return cls.load(db, id = id)
@classmethod
def load(cls, db, id = None, name = None):
""" Constructor for existing account """
if id is not None:
with closing(db.cursor()) as cur:
cur.execute("SELECT name FROM accounts WHERE id = %s", [id])
name = cur.fetchone()[0]
elif name is not None:
with closing(db.cursor()) as cur:
cur.execute("SELECT id FROM accounts WHERE name = %s", [name])
id = cur.fetchone()[0]
else:
raise NameError("Account.load(): Specify either id or name")
with closing(db.cursor()) as cur:
cur.execute("SELECT currency, acctype FROM accounts WHERE id = %s", [id])
currid, acctype = cur.fetchone()
currency = Currency.load(db, id = currid)
return cls(db, name = name, id = id, currency = currency, acctype = acctype)
@classmethod
def create(cls, db, name, currency, acctype):
""" Constructor for new account """
with closing(db.cursor()) as cur:
cur.execute("INSERT INTO accounts (name, currency, acctype) VALUES (?, ?, ?) RETURNING id", [name, currency, acctype])
id = cur.fetchone()[0]
return cls(db, name = name, id = id, currency = currency, acctype = acctype)
def balance(self):
with closing(self.db.cursor()) as cur:
cur.execute("SELECT SUM(amount) FROM transaction_splits WHERE account = %s AND side = %s", [self.id, 'debit'])
debit = cur.fetchone()[0] or 0
cur.execute("SELECT SUM(amount) FROM transaction_splits WHERE account = %s AND side = %s", [self.id, 'credit'])
credit = cur.fetchone()[0] or 0
return debit - credit
def balance_str(self):
return self.currency.str(self.balance())
def negbalance_str(self):
return self.currency.str(-self.balance())
def debit(self, transaction, amount, memo):
return self._transaction_split(transaction, 'debit', amount, memo)
def credit(self, transaction, amount, memo):
return self._transaction_split(transaction, 'credit', amount, memo)
def _transaction_split(self, transaction, side, amount, memo):
""" Common part of credit() and debit(). """
with closing(self.db.cursor()) as cur:
cur.execute("INSERT INTO transaction_splits (transaction, side, account, amount, memo) VALUES (%s, %s, %s, %s, %s)", [transaction, side, self.id, amount, memo])