from finance.models import Account, Payee, Category, CategoryGroup, CardStatement, InstallmentPlan from .base import DomainError, lock, money, save, write def normalized_name(value): if not isinstance(value, str) or not value.strip(): raise DomainError("invalid_name") return value.strip() @write("create_account") def create_account(*, name, kind, currency="BRL"): obj = save(Account(name=normalized_name(name), kind=kind, currency=currency)) return obj, ["name", "kind", "currency"] @write("create_payee") def create_payee(*, name): return save(Payee(name=normalized_name(name))), ["name"] @write("create_category") def create_category(*, name, kind, group_id=None): group = lock(CategoryGroup, group_id, active=True) if group_id is not None else None return save(Category(name=normalized_name(name), kind=kind, group=group)), ["name", "kind", "group"] @write("create_category_group") def create_category_group(*, name): return save(CategoryGroup(name=normalized_name(name))), ["name"] @write("archive") def archive(entity): if type(entity) not in (Account, Payee, Category, CategoryGroup): raise DomainError("invalid_reference") obj = lock(type(entity), entity.pk) obj.archived = True return save(obj), ["archived"] @write("create_statement") def create_statement(*, account_id, period_start, period_end, due_date, statement_balance=None): account = lock(Account, account_id, active=True) if account.kind != "CREDIT_CARD": raise DomainError("statement_requires_card") balance = None if statement_balance is None else money(statement_balance, allow_zero=True) obj = save(CardStatement(account=account, period_start=period_start, period_end=period_end, due_date=due_date, statement_balance=balance)) return obj, ["account", "period_start", "period_end", "due_date", "statement_balance"] @write("create_plan") def create_plan(*, account_id, description, total_installments): account = lock(Account, account_id, active=True) if not isinstance(total_installments, int) or isinstance(total_installments, bool) or total_installments < 1: raise DomainError("invalid_installment_count") obj = save(InstallmentPlan(account=account, description=description, total_installments=total_installments)) return obj, ["account", "description", "total_installments"]