You've already forked double-entry-accounting
Initial project
This commit is contained in:
106
accounting/models.py
Normal file
106
accounting/models.py
Normal file
@@ -0,0 +1,106 @@
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import sessionmaker, relationship
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
class Account(Base):
|
||||
__tablename__ = 'accounts'
|
||||
|
||||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
name = sa.Column(sa.String(100), nullable=False)
|
||||
account_type = sa.Column(sa.String(50), nullable=False) # Asset, Liability, Equity, Revenue, Expense
|
||||
code = sa.Column(sa.String(20), unique=True, nullable=False)
|
||||
parent_id = sa.Column(sa.Integer, sa.ForeignKey('accounts.id'))
|
||||
balance = sa.Column(sa.Numeric(15, 2), default=0)
|
||||
|
||||
parent = relationship('Account', remote_side=[id])
|
||||
entries = relationship('JournalEntryLine', back_populates='account')
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Account(code={self.code}, name={self.name}, type={self.account_type})>"
|
||||
|
||||
|
||||
class JournalEntry(Base):
|
||||
__tablename__ = 'journal_entries'
|
||||
|
||||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
date = sa.Column(sa.Date, nullable=False)
|
||||
reference = sa.Column(sa.String(100))
|
||||
description = sa.Column(sa.String(200))
|
||||
created_at = sa.Column(sa.DateTime, server_default=sa.func.now())
|
||||
|
||||
lines = relationship('JournalEntryLine', back_populates='journal_entry')
|
||||
|
||||
|
||||
class JournalEntryLine(Base):
|
||||
__tablename__ = 'journal_entry_lines'
|
||||
|
||||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
journal_entry_id = sa.Column(sa.Integer, sa.ForeignKey('journal_entries.id'), nullable=False)
|
||||
account_id = sa.Column(sa.Integer, sa.ForeignKey('accounts.id'), nullable=False)
|
||||
amount = sa.Column(sa.Numeric(15, 2), nullable=False)
|
||||
is_debit = sa.Column(sa.Boolean, nullable=False) # True for debit, False for credit
|
||||
|
||||
journal_entry = relationship('JournalEntry', back_populates='lines')
|
||||
account = relationship('Account', back_populates='entries')
|
||||
|
||||
|
||||
class BankAccount(Base):
|
||||
__tablename__ = 'bank_accounts'
|
||||
|
||||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
name = sa.Column(sa.String(100), nullable=False)
|
||||
account_number = sa.Column(sa.String(50))
|
||||
bank_name = sa.Column(sa.String(100))
|
||||
currency = sa.Column(sa.String(3), default='USD')
|
||||
ledger_account_id = sa.Column(sa.Integer, sa.ForeignKey('accounts.id'))
|
||||
|
||||
ledger_account = relationship('Account')
|
||||
transactions = relationship('BankTransaction', back_populates='bank_account')
|
||||
|
||||
|
||||
class BankTransaction(Base):
|
||||
__tablename__ = 'bank_transactions'
|
||||
|
||||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
bank_account_id = sa.Column(sa.Integer, sa.ForeignKey('bank_accounts.id'), nullable=False)
|
||||
date = sa.Column(sa.Date, nullable=False)
|
||||
amount = sa.Column(sa.Numeric(15, 2), nullable=False)
|
||||
description = sa.Column(sa.String(200))
|
||||
reference = sa.Column(sa.String(100))
|
||||
status = sa.Column(sa.String(20), default='unreconciled') # unreconciled, reconciled
|
||||
journal_entry_id = sa.Column(sa.Integer, sa.ForeignKey('journal_entries.id'))
|
||||
|
||||
bank_account = relationship('BankAccount', back_populates='transactions')
|
||||
journal_entry = relationship('JournalEntry')
|
||||
|
||||
|
||||
class ReconciliationReport(Base):
|
||||
__tablename__ = 'reconciliation_reports'
|
||||
|
||||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
bank_account_id = sa.Column(sa.Integer, sa.ForeignKey('bank_accounts.id'), nullable=False)
|
||||
start_date = sa.Column(sa.Date, nullable=False)
|
||||
end_date = sa.Column(sa.Date, nullable=False)
|
||||
created_at = sa.Column(sa.DateTime, server_default=sa.func.now())
|
||||
status = sa.Column(sa.String(20), default='draft') # draft, completed
|
||||
|
||||
bank_account = relationship('BankAccount')
|
||||
matches = relationship('ReconciliationMatch', back_populates='report')
|
||||
|
||||
|
||||
class ReconciliationMatch(Base):
|
||||
__tablename__ = 'reconciliation_matches'
|
||||
|
||||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
report_id = sa.Column(sa.Integer, sa.ForeignKey('reconciliation_reports.id'), nullable=False)
|
||||
transaction_id = sa.Column(sa.Integer, sa.ForeignKey('bank_transactions.id'), nullable=False)
|
||||
journal_entry_id = sa.Column(sa.Integer, sa.ForeignKey('journal_entries.id'), nullable=False)
|
||||
match_score = sa.Column(sa.Numeric(5, 2)) # 0-100 score for match quality
|
||||
notes = sa.Column(sa.String(200))
|
||||
|
||||
report = relationship('ReconciliationReport', back_populates='matches')
|
||||
transaction = relationship('BankTransaction')
|
||||
journal_entry = relationship('JournalEntry')
|
||||
Reference in New Issue
Block a user