Separate client service subscriptions from engagement instances
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
"""add persistent client service subscription master
|
||||
|
||||
Revision ID: 20260805_client_service_plan_master
|
||||
Revises: 20260805_task_instance_period_label
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import inspect
|
||||
|
||||
revision="20260805_client_service_plan_master"
|
||||
down_revision="20260805_task_instance_period_label"
|
||||
branch_labels=None
|
||||
depends_on=None
|
||||
|
||||
def upgrade():
|
||||
bind=op.get_bind(); insp=inspect(bind); tables=set(insp.get_table_names())
|
||||
if "client_service_plans" not in tables:
|
||||
op.create_table("client_service_plans",
|
||||
sa.Column("id",sa.Integer(),primary_key=True),sa.Column("tenant_id",sa.Integer(),sa.ForeignKey("tenants.id",ondelete="CASCADE"),nullable=False),sa.Column("branch_id",sa.Integer(),sa.ForeignKey("branches.id",ondelete="SET NULL")),sa.Column("client_id",sa.Integer(),sa.ForeignKey("clients.id",ondelete="CASCADE"),nullable=False),sa.Column("service_catalogue_id",sa.Integer(),sa.ForeignKey("service_catalogues.id",ondelete="CASCADE"),nullable=False),sa.Column("firm_service_selection_id",sa.Integer(),sa.ForeignKey("firm_service_selections.id",ondelete="SET NULL")),sa.Column("default_partner_user_id",sa.Integer(),sa.ForeignKey("users.id")),sa.Column("default_performing_partner_user_id",sa.Integer(),sa.ForeignKey("users.id")),sa.Column("default_manager_user_id",sa.Integer(),sa.ForeignKey("users.id")),sa.Column("default_staff_user_id",sa.Integer(),sa.ForeignKey("users.id")),sa.Column("default_review_partner_user_id",sa.Integer(),sa.ForeignKey("users.id")),sa.Column("recurrence_type",sa.String(30),nullable=False,server_default="one_time"),sa.Column("effective_from",sa.Date()),sa.Column("effective_to",sa.Date()),sa.Column("auto_generate_periods",sa.Boolean(),nullable=False,server_default=sa.text("false")),sa.Column("status",sa.String(30),nullable=False,server_default="active"),sa.Column("is_active",sa.Boolean(),nullable=False,server_default=sa.text("true")),sa.Column("remarks",sa.Text()),sa.Column("created_by_user_id",sa.Integer(),sa.ForeignKey("users.id")),sa.Column("updated_by_user_id",sa.Integer(),sa.ForeignKey("users.id")),sa.Column("created_at_utc",sa.DateTime(timezone=True),nullable=False,server_default=sa.text("CURRENT_TIMESTAMP")),sa.Column("updated_at_utc",sa.DateTime(timezone=True),nullable=False,server_default=sa.text("CURRENT_TIMESTAMP")),sa.UniqueConstraint("tenant_id","client_id","service_catalogue_id",name="uq_csp_tenant_client_service"))
|
||||
for col in ("tenant_id","branch_id","client_id","service_catalogue_id","default_partner_user_id","default_performing_partner_user_id","default_manager_user_id","default_staff_user_id","default_review_partner_user_id","recurrence_type","status","is_active"):
|
||||
op.create_index(f"ix_csp_{col}","client_service_plans",[col])
|
||||
cols={c["name"] for c in inspect(bind).get_columns("client_service_subscriptions")}
|
||||
if "service_plan_id" not in cols:
|
||||
op.add_column("client_service_subscriptions",sa.Column("service_plan_id",sa.Integer(),nullable=True))
|
||||
op.create_foreign_key("fk_css_service_plan","client_service_subscriptions","client_service_plans",["service_plan_id"],["id"],ondelete="SET NULL")
|
||||
op.create_index("ix_css_service_plan_id","client_service_subscriptions",["service_plan_id"])
|
||||
op.execute(sa.text("""INSERT INTO client_service_plans (tenant_id,branch_id,client_id,service_catalogue_id,firm_service_selection_id,default_partner_user_id,default_performing_partner_user_id,default_manager_user_id,default_staff_user_id,default_review_partner_user_id,recurrence_type,status,is_active,remarks,created_by_user_id,updated_by_user_id) SELECT DISTINCT ON (s.tenant_id,s.client_id,s.service_catalogue_id) s.tenant_id,s.branch_id,s.client_id,s.service_catalogue_id,s.firm_service_selection_id,s.assigned_partner_user_id,s.performing_partner_user_id,s.assigned_manager_user_id,s.assigned_staff_user_id,s.review_partner_user_id,COALESCE(c.recurrence_type,'one_time'),'active',true,s.remarks,s.created_by_user_id,s.updated_by_user_id FROM client_service_subscriptions s JOIN service_catalogues c ON c.id=s.service_catalogue_id LEFT JOIN client_service_plans p ON p.tenant_id=s.tenant_id AND p.client_id=s.client_id AND p.service_catalogue_id=s.service_catalogue_id WHERE p.id IS NULL ORDER BY s.tenant_id,s.client_id,s.service_catalogue_id,s.id DESC"""))
|
||||
op.execute(sa.text("""UPDATE client_service_subscriptions s SET service_plan_id=p.id FROM client_service_plans p WHERE s.service_plan_id IS NULL AND p.tenant_id=s.tenant_id AND p.client_id=s.client_id AND p.service_catalogue_id=s.service_catalogue_id"""))
|
||||
|
||||
def downgrade():
|
||||
bind=op.get_bind(); cols={c["name"] for c in inspect(bind).get_columns("client_service_subscriptions")}
|
||||
if "service_plan_id" in cols:
|
||||
op.drop_index("ix_css_service_plan_id",table_name="client_service_subscriptions")
|
||||
op.drop_constraint("fk_css_service_plan","client_service_subscriptions",type_="foreignkey")
|
||||
op.drop_column("client_service_subscriptions","service_plan_id")
|
||||
if "client_service_plans" in inspect(bind).get_table_names(): op.drop_table("client_service_plans")
|
||||
Reference in New Issue
Block a user