321 lines
23 KiB
Python
321 lines
23 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import date, datetime, timezone
|
|
from decimal import Decimal
|
|
|
|
from sqlalchemy import Boolean, Date, DateTime, ForeignKey, Integer, Numeric, String, Text, UniqueConstraint
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
|
|
from app.core.db.common import CommonBase
|
|
|
|
|
|
class BillingSettings(CommonBase):
|
|
__tablename__ = "billing_settings"
|
|
__table_args__ = (
|
|
UniqueConstraint("tenant_id", "branch_id", name="uq_billing_settings_tenant_branch"),
|
|
)
|
|
|
|
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)
|
|
|
|
invoice_prefix: Mapped[str] = mapped_column(String(40), nullable=False, default="INV")
|
|
next_invoice_no: Mapped[int] = mapped_column(Integer, nullable=False, default=1)
|
|
padding: Mapped[int] = mapped_column(Integer, nullable=False, default=4)
|
|
default_gst_rate: Mapped[Decimal] = mapped_column(Numeric(5, 2), nullable=False, default=Decimal("18.00"))
|
|
default_tax_type: Mapped[str] = mapped_column(String(20), nullable=False, default="CGST_SGST")
|
|
|
|
legal_name: Mapped[str | None] = mapped_column(String(200), nullable=True)
|
|
gstin: Mapped[str | None] = mapped_column(String(20), nullable=True)
|
|
pan: Mapped[str | None] = mapped_column(String(10), nullable=True)
|
|
state_code: Mapped[str | None] = mapped_column(String(2), nullable=True)
|
|
billing_address: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
contact_email: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
|
contact_mobile: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
|
website_url: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
|
|
|
invoice_title: Mapped[str | None] = mapped_column(String(80), nullable=True)
|
|
invoice_number_format: Mapped[str | None] = mapped_column(String(120), nullable=True)
|
|
default_due_days: Mapped[int] = mapped_column(Integer, nullable=False, default=15)
|
|
default_sac_code: Mapped[str | None] = mapped_column(String(20), nullable=True)
|
|
|
|
bank_name: Mapped[str | None] = mapped_column(String(200), nullable=True)
|
|
bank_account_name: Mapped[str | None] = mapped_column(String(200), nullable=True)
|
|
bank_account_number: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
|
bank_ifsc: Mapped[str | None] = mapped_column(String(20), nullable=True)
|
|
upi_id: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
|
bank_details: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
|
|
payumoney_enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
|
payumoney_mode: Mapped[str] = mapped_column(String(20), nullable=False, default="TEST")
|
|
payumoney_merchant_key: Mapped[str | None] = mapped_column(String(120), nullable=True)
|
|
payumoney_merchant_salt: Mapped[str | None] = mapped_column(String(200), nullable=True)
|
|
payumoney_merchant_id: Mapped[str | None] = mapped_column(String(120), nullable=True)
|
|
payumoney_product_info: Mapped[str | None] = mapped_column(String(200), nullable=True)
|
|
|
|
cashfree_enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
|
cashfree_mode: Mapped[str] = mapped_column(String(20), nullable=False, default="TEST")
|
|
cashfree_client_id: Mapped[str | None] = mapped_column(String(180), nullable=True)
|
|
cashfree_client_secret: Mapped[str | None] = mapped_column(String(240), nullable=True)
|
|
cashfree_api_version: Mapped[str] = mapped_column(String(20), nullable=False, default="2023-08-01")
|
|
cashfree_order_note: Mapped[str | None] = mapped_column(String(250), nullable=True)
|
|
|
|
authorised_signatory_name: Mapped[str | None] = mapped_column(String(200), nullable=True)
|
|
declaration: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
terms: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
footer_note: Mapped[str | None] = mapped_column(Text, 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)
|
|
|
|
|
|
class BillingInvoiceGenerationBatch(CommonBase):
|
|
__tablename__ = "billing_invoice_generation_batches"
|
|
|
|
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)
|
|
|
|
billing_period_from: Mapped[date] = mapped_column(Date, nullable=False, index=True)
|
|
billing_period_to: Mapped[date] = mapped_column(Date, nullable=False, index=True)
|
|
financial_year: Mapped[str | None] = mapped_column(String(20), nullable=True, index=True)
|
|
frequency: Mapped[str | None] = mapped_column(String(20), nullable=True, index=True)
|
|
status: Mapped[str] = mapped_column(String(20), nullable=False, default="DRAFT_CREATED", index=True)
|
|
|
|
selected_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
|
|
created_invoice_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
|
|
skipped_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
|
|
error_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
|
|
remarks: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
|
|
generated_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id"), nullable=True)
|
|
generated_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
|
|
|
|
invoices = relationship("BillingInvoice", back_populates="generation_batch")
|
|
|
|
|
|
class BillingInvoice(CommonBase):
|
|
__tablename__ = "billing_invoices"
|
|
__table_args__ = (
|
|
UniqueConstraint("tenant_id", "invoice_no", name="uq_billing_invoices_tenant_invoice_no"),
|
|
)
|
|
|
|
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="RESTRICT"), nullable=False, index=True)
|
|
engagement_id: Mapped[int | None] = mapped_column(ForeignKey("client_service_subscriptions.id", ondelete="SET NULL"), nullable=True, index=True)
|
|
generation_batch_id: Mapped[int | None] = mapped_column(ForeignKey("billing_invoice_generation_batches.id", ondelete="SET NULL"), nullable=True, index=True)
|
|
|
|
invoice_no: Mapped[str] = mapped_column(String(60), nullable=False, index=True)
|
|
invoice_date: Mapped[date] = mapped_column(Date, nullable=False, default=date.today, index=True)
|
|
due_date: Mapped[date | None] = mapped_column(Date, nullable=True, index=True)
|
|
billing_period_from: Mapped[date | None] = mapped_column(Date, nullable=True)
|
|
billing_period_to: Mapped[date | None] = mapped_column(Date, nullable=True)
|
|
financial_year: Mapped[str | None] = mapped_column(String(20), nullable=True, index=True)
|
|
|
|
invoice_title: Mapped[str | None] = mapped_column(String(80), nullable=True)
|
|
place_of_supply: Mapped[str | None] = mapped_column(String(120), nullable=True)
|
|
reverse_charge: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
|
|
|
client_legal_name: Mapped[str | None] = mapped_column(String(200), nullable=True)
|
|
client_trade_name: Mapped[str | None] = mapped_column(String(200), nullable=True)
|
|
client_gstin: Mapped[str | None] = mapped_column(String(20), nullable=True)
|
|
client_pan: Mapped[str | None] = mapped_column(String(20), nullable=True)
|
|
client_billing_address: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
client_state: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
|
client_state_code: Mapped[str | None] = mapped_column(String(2), nullable=True)
|
|
client_email: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
|
client_mobile: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
|
|
|
tax_type: Mapped[str] = mapped_column(String(20), nullable=False, default="CGST_SGST")
|
|
subtotal: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
discount_amount: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
taxable_amount: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
cgst_amount: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
sgst_amount: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
igst_amount: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
round_off: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
total_amount: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
amount_received: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
tds_deducted: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
bank_charges: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
balance_amount: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
amount_in_words: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
|
|
|
status: Mapped[str] = mapped_column(String(20), nullable=False, default="DRAFT", index=True)
|
|
notes: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
terms: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
|
|
created_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id"), nullable=True)
|
|
approved_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id"), nullable=True)
|
|
posted_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), 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", foreign_keys=[engagement_id])
|
|
generation_batch = relationship("BillingInvoiceGenerationBatch", back_populates="invoices")
|
|
lines = relationship("BillingInvoiceLine", back_populates="invoice", cascade="all, delete-orphan", order_by="BillingInvoiceLine.sort_order.asc()")
|
|
payments = relationship("BillingPayment", back_populates="invoice", cascade="all, delete-orphan", order_by="BillingPayment.payment_date.desc(), BillingPayment.id.desc()")
|
|
online_transactions = relationship("BillingOnlinePaymentTransaction", back_populates="invoice", cascade="all, delete-orphan", order_by="BillingOnlinePaymentTransaction.created_at_utc.desc(), BillingOnlinePaymentTransaction.id.desc()")
|
|
|
|
|
|
class BillingPayment(CommonBase):
|
|
__tablename__ = "billing_payments"
|
|
__table_args__ = (
|
|
UniqueConstraint("tenant_id", "receipt_no", name="uq_billing_payments_tenant_receipt_no"),
|
|
)
|
|
|
|
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)
|
|
invoice_id: Mapped[int] = mapped_column(ForeignKey("billing_invoices.id", ondelete="CASCADE"), nullable=False, index=True)
|
|
client_id: Mapped[int] = mapped_column(ForeignKey("clients.id", ondelete="RESTRICT"), nullable=False, index=True)
|
|
|
|
receipt_no: Mapped[str] = mapped_column(String(60), nullable=False, index=True)
|
|
receipt_date: Mapped[date] = mapped_column(Date, nullable=False, default=date.today, index=True)
|
|
payment_date: Mapped[date] = mapped_column(Date, nullable=False, default=date.today, index=True)
|
|
financial_year: Mapped[str | None] = mapped_column(String(20), nullable=True, index=True)
|
|
amount_received: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
tds_deducted: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
bank_charges: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
mode: Mapped[str] = mapped_column(String(30), nullable=False, default="BANK")
|
|
reference_no: Mapped[str | None] = mapped_column(String(120), nullable=True)
|
|
payment_gateway: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
|
gateway_transaction_id: Mapped[str | None] = mapped_column(String(120), nullable=True)
|
|
remarks: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
status: Mapped[str] = mapped_column(String(20), nullable=False, default="RECEIVED", index=True)
|
|
|
|
created_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id"), 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)
|
|
|
|
invoice = relationship("BillingInvoice", back_populates="payments")
|
|
client = relationship("Client")
|
|
|
|
|
|
class BillingOnlinePaymentTransaction(CommonBase):
|
|
__tablename__ = "billing_online_payment_transactions"
|
|
__table_args__ = (
|
|
UniqueConstraint("tenant_id", "txnid", name="uq_billing_online_payment_tenant_txnid"),
|
|
)
|
|
|
|
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)
|
|
invoice_id: Mapped[int] = mapped_column(ForeignKey("billing_invoices.id", ondelete="CASCADE"), nullable=False, index=True)
|
|
client_id: Mapped[int] = mapped_column(ForeignKey("clients.id", ondelete="RESTRICT"), nullable=False, index=True)
|
|
|
|
provider: Mapped[str] = mapped_column(String(40), nullable=False, default="PAYUMONEY", index=True)
|
|
mode: Mapped[str] = mapped_column(String(20), nullable=False, default="TEST")
|
|
txnid: Mapped[str] = mapped_column(String(80), nullable=False, index=True)
|
|
amount: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
productinfo: Mapped[str | None] = mapped_column(String(250), nullable=True)
|
|
firstname: Mapped[str | None] = mapped_column(String(120), nullable=True)
|
|
email: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
|
phone: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
|
|
|
payu_payment_id: Mapped[str | None] = mapped_column(String(120), nullable=True, index=True)
|
|
cashfree_order_id: Mapped[str | None] = mapped_column(String(120), nullable=True, index=True)
|
|
cashfree_cf_order_id: Mapped[str | None] = mapped_column(String(120), nullable=True, index=True)
|
|
cashfree_payment_session_id: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
|
cashfree_payment_id: Mapped[str | None] = mapped_column(String(120), nullable=True, index=True)
|
|
webhook_event_id: Mapped[str | None] = mapped_column(String(120), nullable=True, index=True)
|
|
bank_ref_num: Mapped[str | None] = mapped_column(String(120), nullable=True)
|
|
mihpayid: Mapped[str | None] = mapped_column(String(120), nullable=True)
|
|
status: Mapped[str] = mapped_column(String(30), nullable=False, default="INITIATED", index=True)
|
|
gateway_status: Mapped[str | None] = mapped_column(String(80), nullable=True)
|
|
response_hash: Mapped[str | None] = mapped_column(String(200), nullable=True)
|
|
raw_response: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
receipt_payment_id: Mapped[int | None] = mapped_column(ForeignKey("billing_payments.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)
|
|
completed_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
|
|
invoice = relationship("BillingInvoice", back_populates="online_transactions")
|
|
client = relationship("Client")
|
|
receipt_payment = relationship("BillingPayment", foreign_keys=[receipt_payment_id])
|
|
|
|
|
|
class BillingInvoiceLine(CommonBase):
|
|
__tablename__ = "billing_invoice_lines"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
|
invoice_id: Mapped[int] = mapped_column(ForeignKey("billing_invoices.id", ondelete="CASCADE"), nullable=False, index=True)
|
|
service_id: Mapped[int | None] = mapped_column(ForeignKey("service_catalogues.id", ondelete="SET NULL"), nullable=True, index=True)
|
|
engagement_id: Mapped[int | None] = mapped_column(ForeignKey("client_service_subscriptions.id", ondelete="SET NULL"), nullable=True, index=True)
|
|
fee_group_id: Mapped[int | None] = mapped_column(ForeignKey("billing_fee_groups.id", ondelete="SET NULL"), nullable=True, index=True)
|
|
|
|
description: Mapped[str] = mapped_column(String(500), nullable=False)
|
|
sac_code: Mapped[str | None] = mapped_column(String(20), nullable=True)
|
|
billing_period_from: Mapped[date | None] = mapped_column(Date, nullable=True)
|
|
billing_period_to: Mapped[date | None] = mapped_column(Date, nullable=True)
|
|
quantity: Mapped[Decimal] = mapped_column(Numeric(12, 2), nullable=False, default=Decimal("1.00"))
|
|
rate: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
discount_amount: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
taxable_amount: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
gst_rate: Mapped[Decimal] = mapped_column(Numeric(5, 2), nullable=False, default=Decimal("18.00"))
|
|
cgst_amount: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
sgst_amount: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
igst_amount: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
line_total: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
sort_order: Mapped[int] = mapped_column(Integer, nullable=False, default=1)
|
|
|
|
invoice = relationship("BillingInvoice", back_populates="lines")
|
|
service = relationship("ServiceCatalogue")
|
|
|
|
|
|
class BillingFeeGroup(CommonBase):
|
|
__tablename__ = "billing_fee_groups"
|
|
__table_args__ = (
|
|
UniqueConstraint("tenant_id", "group_code", name="uq_billing_fee_groups_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)
|
|
partner_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True, index=True)
|
|
|
|
group_code: Mapped[str] = mapped_column(String(80), nullable=False, index=True)
|
|
group_name: Mapped[str] = mapped_column(String(200), nullable=False)
|
|
billing_mode: Mapped[str] = mapped_column(String(20), nullable=False, default="PACKAGE")
|
|
frequency: Mapped[str] = mapped_column(String(20), nullable=False, default="Monthly")
|
|
fee_amount: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
gst_rate: Mapped[Decimal] = mapped_column(Numeric(5, 2), nullable=False, default=Decimal("18.00"))
|
|
tax_type: Mapped[str] = mapped_column(String(20), nullable=False, default="CGST_SGST")
|
|
effective_from: Mapped[date | None] = mapped_column(Date, nullable=True)
|
|
effective_to: Mapped[date | None] = mapped_column(Date, nullable=True)
|
|
auto_generate: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
|
is_active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True, index=True)
|
|
notes: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
|
|
created_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id"), nullable=True)
|
|
updated_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id"), 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")
|
|
services = relationship("BillingFeeGroupService", back_populates="fee_group", cascade="all, delete-orphan", order_by="BillingFeeGroupService.sort_order.asc()")
|
|
|
|
|
|
class BillingFeeGroupService(CommonBase):
|
|
__tablename__ = "billing_fee_group_services"
|
|
__table_args__ = (
|
|
UniqueConstraint("fee_group_id", "service_id", name="uq_billing_fee_group_services_group_service"),
|
|
)
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
|
fee_group_id: Mapped[int] = mapped_column(ForeignKey("billing_fee_groups.id", ondelete="CASCADE"), nullable=False, index=True)
|
|
service_id: Mapped[int] = mapped_column(ForeignKey("service_catalogues.id", ondelete="RESTRICT"), nullable=False, index=True)
|
|
line_description: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
|
allocation_type: Mapped[str] = mapped_column(String(20), nullable=False, default="Included")
|
|
line_amount: Mapped[Decimal] = mapped_column(Numeric(14, 2), nullable=False, default=Decimal("0.00"))
|
|
percentage: Mapped[Decimal | None] = mapped_column(Numeric(5, 2), nullable=True)
|
|
sort_order: Mapped[int] = mapped_column(Integer, nullable=False, default=1)
|
|
|
|
fee_group = relationship("BillingFeeGroup", back_populates="services")
|
|
service = relationship("ServiceCatalogue")
|