Skip to content

Instantly share code, notes, and snippets.

@MaxMorais
Last active December 15, 2016 23:52
Show Gist options
  • Save MaxMorais/f902b4987d8f43cc3a13082fbff3f15e to your computer and use it in GitHub Desktop.
Save MaxMorais/f902b4987d8f43cc3a13082fbff3f15e to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
# Copyright (c) 2015, MaxMorais and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
import re
import uuid
from pfc.controllers.model.model import get_model
from pfc.controllers.model.database import db
from pfc.controllers.money import Currency, Money
class Account(get_model('Account', True)):
@classmethod
def find_or_create(cls, account):
existing_account = cls.select(cls.name).order_by(cls.status, 'ASC').filter(
(cls.account_key == account.account_key) &
(cls.account_number == cls.last4(account.account_number)) &
(cls.account_type) == cls.account_type) &
(cls.account_status != 'Deleted') &
(cls.financial_institution == account.financial_institution))
if existing_account:
return existing_account
else:
account.save()
return account
@classmethod
def find_account(cls, account_number, account_type, financial_institution):
return cls.for_user.filter(
(cls.account_number == account_number) &
(cls.account_type == account_type) &
(cls.financial_institution == financial_institution) &
(cls.account_type.visible == True))[0]
@classmethod
def find_account_by_account_number_hash(cls, account_number_hash, account_type, financial_institution):
return cls.for_user.filter(
(cls.account_number_hash == account_number_hash) &
(cls.account_type == account_type) &
(cls.financial_institution == financial_institution) &
(cls.account_type.visible == True))[0]
@staticmethod
def last4(acct_number, regex=None):
acct_number = re.sub('\W', '', acct_number) # always strip non-word characters
if regex:
m = re.match(regex, acct_number)
if m and not m.groups() or len(m.groups) < 2:
raise ValueError('Regex provided, but no groupings specified')
return "".join(m.groups()[-6:])
return acct_number[-4:]
def safe_delete(self):
self.db_set('status', 'Deleted')
db(db.Transactions.account == self.name).update(status = 'Deleted')
@property
def internal_id(self):
if self.financial_institution:
return self.financial_institution.internal_id
@property
def balance(self):
if not self.has_balance():
return None
return self.calculate_balance()
def calculate_balance(self):
if not self.has_balance:
return None
most_recent = db(
(db.Transaction.account == self.name) &
(db.Transaction.status == 'Active')
).select().order_by(
db.Transaction.date_posted.desc,
db.Transaction.sequence,
db.Transaction.created.desc
)
if self.manual_account and most_recent:
new_balance = most_recent[0].calculate_balance()
else:
last_balance = self.last_balance(True)
new_balance = (last_balance and last_balance.balance) or 0.0
return new_balance
@property
def money_balance(self):
if not self.has_balance:
return None
return Currency(self.currency, self.balance)
@property
def cash_account(self):
return self.account_type == 'CASH'
@property
def bookerage_account(self):
return self.account_type == 'BOOKERAGE'
@property
def investiment_account(self):
return self.account_type == 'INVESTIMENT'
@property
def manual_account(self):
return self.account_type in ['CASH', 'MANUAL']
@property
def has_balance(self):
return self.account_type.has_balance
@property
def editable_balance(self):
return self.has_balance and (self.manual_account or self.financial_institution.bad_balance)
@property
def has_uploads(self):
return self.account_type.has_uploads
@classmethod
def generate_guid(cls):
guid = uuid.uuid1()
while cls.exists(cls.account_guid == guid.hex):
guid = uuid.uuid1()
self.guid = guid.hex
@classmethod
def generate_id_for_user(cls):
max_id = cls.find(cls.id_for_user.max())[0].get(cls.id_for_user.max(), 1)
return max_id
def generate_account_name(self):
if not self.account_name:
self.account_name = self.financial_institution.financial_institution_name
if self.account_type:
self.account_name += ' - {0}'.format(self.account_type.type_name)
def truncate_account_number(self):
if self.account_number:
self.account_number = self.last4(account_number)
def before_insert(self):
self.generate_guid()
self.generate_id_for_user()
self.generate_account_name()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment