Files
arrr-erp/app/modules/notice_cases/models.py
T
2026-06-20 15:01:44 +05:30

170 lines
12 KiB
Python

from __future__ import annotations
from datetime import date, datetime, timezone
from sqlalchemy import Boolean, Date, DateTime, ForeignKey, Integer, String, Text, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.core.db.common import CommonBase
class NoticeCase(CommonBase):
"""Department notice / case / appeal master.
A case is intentionally kept separate from engagements because GST/Income Tax/ROC
proceedings can continue across years, have independent due dates, and may later
be linked to one or more engagements/tasks.
"""
__tablename__ = "notice_cases"
__table_args__ = (
UniqueConstraint("tenant_id", "case_code", name="uq_notice_cases_tenant_code"),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True)
branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
client_id: Mapped[int] = mapped_column(ForeignKey("clients.id", ondelete="CASCADE"), nullable=False, index=True)
engagement_id: Mapped[int | None] = mapped_column(ForeignKey("client_service_subscriptions.id", ondelete="SET NULL"), nullable=True, index=True)
case_code: Mapped[str] = mapped_column(String(80), nullable=False, index=True)
department: Mapped[str] = mapped_column(String(40), nullable=False, index=True)
case_type: Mapped[str] = mapped_column(String(50), nullable=False, index=True)
title: Mapped[str] = mapped_column(String(255), nullable=False)
reference_no: Mapped[str | None] = mapped_column(String(150), nullable=True, index=True)
din_ack_no: Mapped[str | None] = mapped_column(String(150), nullable=True, index=True)
notice_date: Mapped[date | None] = mapped_column(Date, nullable=True, index=True)
due_date: Mapped[date | None] = mapped_column(Date, nullable=True, index=True)
financial_year: Mapped[str | None] = mapped_column(String(9), nullable=True, index=True)
assessment_year: Mapped[str | None] = mapped_column(String(9), nullable=True, index=True)
period_label: Mapped[str | None] = mapped_column(String(60), nullable=True, index=True)
status: Mapped[str] = mapped_column(String(40), nullable=False, default="open", index=True)
priority: Mapped[str] = mapped_column(String(20), nullable=False, default="normal", index=True)
issue_summary: Mapped[str | None] = mapped_column(Text, nullable=True)
remarks: Mapped[str | None] = mapped_column(Text, nullable=True)
assigned_partner_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True, index=True)
assigned_manager_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True, index=True)
assigned_staff_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True, index=True)
is_archived: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, index=True)
archived_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
archived_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
created_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
updated_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
created_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
updated_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc), nullable=False)
client = relationship("Client")
engagement = relationship("ClientServiceSubscription")
assigned_partner = relationship("User", foreign_keys=[assigned_partner_user_id])
assigned_manager = relationship("User", foreign_keys=[assigned_manager_user_id])
assigned_staff = relationship("User", foreign_keys=[assigned_staff_user_id])
events = relationship("NoticeCaseEvent", back_populates="case", cascade="all, delete-orphan", passive_deletes=True, order_by="NoticeCaseEvent.event_date.desc(), NoticeCaseEvent.id.desc()")
hearings = relationship("NoticeCaseHearing", back_populates="case", cascade="all, delete-orphan", passive_deletes=True, order_by="NoticeCaseHearing.hearing_date.asc(), NoticeCaseHearing.id.asc()")
orders = relationship("NoticeCaseOrder", back_populates="case", cascade="all, delete-orphan", passive_deletes=True, order_by="NoticeCaseOrder.order_date.desc(), NoticeCaseOrder.id.desc()")
documents = relationship("NoticeCaseDocument", back_populates="case", cascade="all, delete-orphan", passive_deletes=True, order_by="NoticeCaseDocument.uploaded_at_utc.desc()")
class NoticeCaseEvent(CommonBase):
__tablename__ = "notice_case_events"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True)
branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
case_id: Mapped[int] = mapped_column(ForeignKey("notice_cases.id", ondelete="CASCADE"), nullable=False, index=True)
event_type: Mapped[str] = mapped_column(String(60), nullable=False, index=True)
event_date: Mapped[date] = mapped_column(Date, nullable=False, index=True)
description: Mapped[str] = mapped_column(Text, nullable=False)
next_due_date: Mapped[date | None] = mapped_column(Date, nullable=True, index=True)
created_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True, index=True)
created_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
case = relationship("NoticeCase", back_populates="events")
created_by = relationship("User")
class NoticeCaseHearing(CommonBase):
__tablename__ = "notice_case_hearings"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True)
branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
case_id: Mapped[int] = mapped_column(ForeignKey("notice_cases.id", ondelete="CASCADE"), nullable=False, index=True)
hearing_date: Mapped[date] = mapped_column(Date, nullable=False, index=True)
hearing_time: Mapped[str | None] = mapped_column(String(20), nullable=True)
venue_or_mode: Mapped[str | None] = mapped_column(String(200), nullable=True)
officer_name: Mapped[str | None] = mapped_column(String(150), nullable=True)
agenda: Mapped[str | None] = mapped_column(Text, nullable=True)
outcome: Mapped[str | None] = mapped_column(Text, nullable=True)
status: Mapped[str] = mapped_column(String(30), nullable=False, default="scheduled", index=True)
created_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True, index=True)
created_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
updated_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc), nullable=False)
case = relationship("NoticeCase", back_populates="hearings")
created_by = relationship("User")
class NoticeCaseOrder(CommonBase):
__tablename__ = "notice_case_orders"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True)
branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
case_id: Mapped[int] = mapped_column(ForeignKey("notice_cases.id", ondelete="CASCADE"), nullable=False, index=True)
order_type: Mapped[str] = mapped_column(String(60), nullable=False, index=True)
order_no: Mapped[str | None] = mapped_column(String(150), nullable=True, index=True)
order_date: Mapped[date] = mapped_column(Date, nullable=False, index=True)
demand_amount: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
tax_amount: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
interest_amount: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
penalty_amount: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
summary: Mapped[str | None] = mapped_column(Text, nullable=True)
appeal_due_date: Mapped[date | None] = mapped_column(Date, nullable=True, index=True)
appeal_filed: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, index=True)
created_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True, index=True)
created_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
case = relationship("NoticeCase", back_populates="orders")
created_by = relationship("User")
class NoticeCaseDocument(CommonBase):
__tablename__ = "notice_case_documents"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True)
branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
case_id: Mapped[int] = mapped_column(ForeignKey("notice_cases.id", ondelete="CASCADE"), nullable=False, index=True)
event_id: Mapped[int | None] = mapped_column(ForeignKey("notice_case_events.id", ondelete="SET NULL"), nullable=True, index=True)
document_type: Mapped[str] = mapped_column(String(80), nullable=False, default="GENERAL", index=True)
title: Mapped[str] = mapped_column(String(255), nullable=False)
description: Mapped[str | None] = mapped_column(Text, nullable=True)
original_filename: Mapped[str] = mapped_column(String(255), nullable=False)
stored_filename: Mapped[str] = mapped_column(String(255), nullable=False)
content_type: Mapped[str | None] = mapped_column(String(150), nullable=True)
file_size_bytes: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
local_relative_path: Mapped[str] = mapped_column(String(1000), nullable=False)
version_no: Mapped[int] = mapped_column(Integer, nullable=False, default=1)
status: Mapped[str] = mapped_column(String(30), nullable=False, default="active", index=True)
is_deleted: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, index=True)
deleted_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
deleted_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
uploaded_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
uploaded_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
case = relationship("NoticeCase", back_populates="documents")
event = relationship("NoticeCaseEvent")
uploaded_by = relationship("User", foreign_keys=[uploaded_by_user_id])