web/penny/common/transactions/create.py
from flask import current_app
from nene import db
from nene.transaction import get_tx_hash
from nene.memc import Memcache
class CreateTransactionError(StandardError):
pass
class CreateTransaction:
def __init__(
self,
date,
memo,
bankaccount,
user,
account=None,
fitid=None,
debit=0,
credit=0,
paypalid=None,
parent=None,
):
self.date = date
self.debit = debit
self.credit = credit
self.memo = memo
self.bankaccount = bankaccount
self.user = user
self.account = account
self.fitid = fitid
self.paypalid = paypalid
self.parent = parent
# Check if bankaccount is a DB object and if so pass in the id
# attribute to get_tx_hash(). If bankaccount is not a DB object,
# dont pass it through to get_tx_hash() as it defaults to False.
if hasattr(self.bankaccount, "id"):
self.tx_hash = get_tx_hash(
self.date,
self.debit,
self.credit,
self.memo,
self.fitid,
self.paypalid,
self.bankaccount.id,
)
else:
self.tx_hash = get_tx_hash(
self.date, self.debit, self.credit, self.memo, self.fitid, self.paypalid
)
def create(self):
# confirm bankaccount is owned by the user.
if self.bankaccount:
if self.bankaccount.user != self.user:
raise CreateTransaction(
"user does not own bankaccount; user={}, bankaccount={}".format(
self.user.id, self.bankaccount.id
)
)
# account is optional though if submitted check that the account
# exists and it is owned by the user.
if self.account and self.account.user != self.user:
raise CreateTransactionError(
"user does not own account or account doest not exist; "
"user={}, account={}".format(self.user.id, self.account.id)
)
self.transaction = None
try:
self.transaction = db.Transaction.get(
db.Transaction.hash == self.tx_hash, db.Transaction.user == self.user
)
except db.Transaction.DoesNotExist:
self.transaction = db.Transaction(
date=self.date,
debit=self.debit,
credit=self.credit,
memo=self.memo,
bankaccount=self.bankaccount,
account=self.account,
hash=self.tx_hash,
fitid=self.fitid,
paypalid=self.paypalid,
user=self.user,
parent=self.parent,
)
self.transaction.save()
else:
# A transaction which shares the same hash exists. If the
# account is different update it else consider it a
# duplicate. Log this for now though in the future something
# should be done with duplicates such as creating a report
# or providing the opportunity to import it.
# trac@48: Handle duplicate transactions.
if self.account and self.account != self.transaction.account:
self.transaction.account = self.account.id
self.transaction.save()
mc = Memcache()
mc.delete("transaction.{}".format(self.transaction.id))
else:
# I'm not convinced this is being reached and logged.
# XXX: investigate if this is being logged.
current_app.logger.info(
"duplicate transaction found on import; "
"transaction={transaction}, user={user}".format(
transaction.self.transaction.id, user=self.user.id
)
)
finally:
return self.transaction