170 lines
12 KiB
Python
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])
|