Files
arrr-erp/alembic/versions/20260822_bank_to_tally_phase11.py
2026-08-22 19:59:40 +05:30

82 lines
5.8 KiB
Python

"""Phase 11 Bank to Tally + multi-bank contra.
Revision ID: 20260822_bank_to_tally_p11
Revises: 20260822_purchase_posting_p10
"""
from alembic import op
import sqlalchemy as sa
revision = "20260822_bank_to_tally_p11"
down_revision = "20260822_purchase_posting_p10"
branch_labels = None
depends_on = None
def upgrade():
op.create_table(
"accounting_bank_transactions",
sa.Column("id", sa.Integer(), primary_key=True),
sa.Column("tenant_id", sa.Integer(), sa.ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False),
sa.Column("client_id", sa.Integer(), sa.ForeignKey("clients.id", ondelete="CASCADE"), nullable=False),
sa.Column("source_job_id", sa.String(32), sa.ForeignKey("bank_statement_analysis_jobs.id", ondelete="SET NULL"), nullable=True),
sa.Column("fingerprint", sa.String(80), nullable=False),
sa.Column("statement_id", sa.String(40), nullable=False, server_default=""),
sa.Column("bank_name", sa.String(160), nullable=False, server_default=""),
sa.Column("account_number", sa.String(100), nullable=False, server_default=""),
sa.Column("customer_name", sa.String(255), nullable=False, server_default=""),
sa.Column("transaction_date", sa.String(20), nullable=False, server_default=""),
sa.Column("value_date", sa.String(20), nullable=False, server_default=""),
sa.Column("narration", sa.Text(), nullable=False, server_default=""),
sa.Column("reference_no", sa.String(180), nullable=False, server_default=""),
sa.Column("transfer_reference", sa.String(180), nullable=False, server_default=""),
sa.Column("direction", sa.String(10), nullable=False, server_default=""),
sa.Column("debit", sa.Float(), nullable=False, server_default="0"),
sa.Column("credit", sa.Float(), nullable=False, server_default="0"),
sa.Column("amount", sa.Float(), nullable=False, server_default="0"),
sa.Column("auto_party", sa.String(255), nullable=False, server_default=""),
sa.Column("analyzer_category", sa.String(255), nullable=False, server_default=""),
sa.Column("analyzer_nature", sa.String(160), nullable=False, server_default=""),
sa.Column("analyzer_ledger", sa.String(255), nullable=False, server_default=""),
sa.Column("contra_pair_id", sa.String(60), nullable=False, server_default=""),
sa.Column("contra_counter_bank", sa.String(160), nullable=False, server_default=""),
sa.Column("contra_counter_account", sa.String(100), nullable=False, server_default=""),
sa.Column("contra_confidence", sa.Float(), nullable=False, server_default="0"),
sa.Column("contra_reason", sa.Text(), nullable=True),
sa.Column("tally_guid", sa.String(120), nullable=False, server_default=""),
sa.Column("suggested_nature_id", sa.Integer(), sa.ForeignKey("accounting_natures.id", ondelete="SET NULL"), nullable=True),
sa.Column("suggested_ledger_name", sa.String(255), nullable=False, server_default=""),
sa.Column("suggested_confidence", sa.Integer(), nullable=False, server_default="0"),
sa.Column("suggestion_reason_json", sa.Text(), nullable=True),
sa.Column("suggested_voucher_type", sa.String(20), nullable=False, server_default=""),
sa.Column("review_status", sa.String(20), nullable=False, server_default="pending"),
sa.Column("final_nature_id", sa.Integer(), sa.ForeignKey("accounting_natures.id", ondelete="SET NULL"), nullable=True),
sa.Column("final_ledger_name", sa.String(255), nullable=False, server_default=""),
sa.Column("final_party_ledger_name", sa.String(255), nullable=False, server_default=""),
sa.Column("final_bank_ledger_name", sa.String(255), nullable=False, server_default=""),
sa.Column("final_other_bank_ledger_name", sa.String(255), nullable=False, server_default=""),
sa.Column("final_voucher_type", sa.String(20), nullable=False, server_default=""),
sa.Column("review_note", sa.Text(), nullable=True),
sa.Column("reviewed_by_user_id", sa.Integer(), sa.ForeignKey("users.id", ondelete="SET NULL"), nullable=True),
sa.Column("reviewed_at_utc", sa.DateTime(timezone=True), nullable=True),
sa.Column("workstation_agent_id", sa.Integer(), sa.ForeignKey("erp_workstation_agents.id", ondelete="SET NULL"), nullable=True),
sa.Column("preflight_job_id", sa.Integer(), sa.ForeignKey("erp_agent_jobs.id", ondelete="SET NULL"), nullable=True),
sa.Column("posting_job_id", sa.Integer(), sa.ForeignKey("erp_agent_jobs.id", ondelete="SET NULL"), nullable=True),
sa.Column("preflight_result_json", sa.Text(), nullable=True),
sa.Column("posting_result_json", sa.Text(), nullable=True),
sa.Column("posting_status", sa.String(30), nullable=False, server_default="not_started"),
sa.Column("last_error", sa.Text(), nullable=True),
sa.Column("tally_voucher_id", sa.String(120), nullable=False, server_default=""),
sa.Column("tally_voucher_number", sa.String(160), nullable=False, server_default=""),
sa.Column("posted_by_user_id", sa.Integer(), sa.ForeignKey("users.id", ondelete="SET NULL"), nullable=True),
sa.Column("posted_at_utc", sa.DateTime(timezone=True), nullable=True),
sa.Column("created_at_utc", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
sa.Column("updated_at_utc", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
sa.UniqueConstraint("tenant_id", "client_id", "fingerprint", name="uq_accounting_bank_tx_fingerprint"),
)
for name in ("tenant_id","client_id","source_job_id","fingerprint","transaction_date","contra_pair_id","review_status","posting_status","created_at_utc"):
op.create_index(f"ix_accounting_bank_transactions_{name}", "accounting_bank_transactions", [name])
def downgrade():
op.drop_table("accounting_bank_transactions")