TorbatYar/backend/services/accounting/app/models/operational.py
Mortezakoohjani 7d66932da8 Complete Accounting sidebar modules with ops CRUD, BFF proxy, and treasury APIs.
Wire nested nav pages for phases 5.1-5.11 to real list/create endpoints, fix COA import connectivity via same-origin proxy, and add operational migration.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-24 16:10:06 +03:30

64 lines
2.9 KiB
Python

"""Phase ops — lightweight business documents for Sales/Purchase/Inventory UI."""
from __future__ import annotations
import uuid
from datetime import date
from decimal import Decimal
from sqlalchemy import Boolean, Date, Index, Numeric, String, Text, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column
from app.core.database import Base
from app.models.base import TenantMixin, TimestampMixin, UUIDPrimaryKeyMixin
from app.models.types import GUID
class BusinessDocument(Base, UUIDPrimaryKeyMixin, TenantMixin, TimestampMixin):
"""Generic operational document used by Sales / Purchase / Inventory screens."""
__tablename__ = "business_documents"
module: Mapped[str] = mapped_column(String(40), nullable=False)
doc_type: Mapped[str] = mapped_column(String(50), nullable=False)
number: Mapped[str] = mapped_column(String(50), nullable=False)
doc_date: Mapped[date] = mapped_column(Date, nullable=False)
party_name: Mapped[str | None] = mapped_column(String(255), nullable=True)
party_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
amount: Mapped[Decimal] = mapped_column(Numeric(18, 4), default=Decimal("0"), nullable=False)
status: Mapped[str] = mapped_column(String(30), default="draft", nullable=False)
description: Mapped[str | None] = mapped_column(Text, nullable=True)
meta_json: Mapped[str | None] = mapped_column(Text, nullable=True)
__table_args__ = (
UniqueConstraint("tenant_id", "module", "number", name="uq_biz_doc_tenant_module_number"),
Index("ix_biz_doc_tenant_module_type", "tenant_id", "module", "doc_type"),
)
class InventoryItem(Base, UUIDPrimaryKeyMixin, TenantMixin, TimestampMixin):
__tablename__ = "inventory_items"
code: Mapped[str] = mapped_column(String(50), nullable=False)
name: Mapped[str] = mapped_column(String(255), nullable=False)
item_type: Mapped[str] = mapped_column(String(30), default="goods", nullable=False)
unit: Mapped[str] = mapped_column(String(30), default="عدد", nullable=False)
quantity_on_hand: Mapped[Decimal] = mapped_column(Numeric(18, 4), default=Decimal("0"), nullable=False)
unit_cost: Mapped[Decimal] = mapped_column(Numeric(18, 4), default=Decimal("0"), nullable=False)
is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
__table_args__ = (
UniqueConstraint("tenant_id", "code", name="uq_inventory_item_tenant_code"),
)
class Warehouse(Base, UUIDPrimaryKeyMixin, TenantMixin, TimestampMixin):
__tablename__ = "warehouses"
code: Mapped[str] = mapped_column(String(50), nullable=False)
name: Mapped[str] = mapped_column(String(255), nullable=False)
is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
__table_args__ = (
UniqueConstraint("tenant_id", "code", name="uq_warehouse_tenant_code"),
)