DFiP_Budget_planing/api/alembic/versions/0001_initial_schema.py
2026-06-30 11:52:39 +03:00

1038 lines
34 KiB
Python

"""initial schema — tables and sequences
Revision ID: 0001
Revises:
Create Date: 2026-06-22
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
revision = "0001"
down_revision = None
branch_labels = None
depends_on = None
def create_table_if_not_exists(table_name, *columns, **kwargs):
conn = op.get_bind()
inspector = sa.inspect(conn)
if table_name not in inspector.get_table_names(schema="v3"):
op.create_table(table_name, *columns, **kwargs)
return True
return False
def create_index_if_not_exists(index_name, table_name, columns, **kwargs):
conn = op.get_bind()
inspector = sa.inspect(conn)
existing_indexes = inspector.get_indexes(table_name, schema="v3")
if not any(idx['name'] == index_name for idx in existing_indexes):
op.create_index(index_name, table_name, columns, **kwargs)
return True
return False
def create_check_constraint_if_not_exists(
constraint_name,
table_name,
condition,
schema=None,
):
conn = op.get_bind()
inspector = sa.inspect(conn)
existing_constraints = inspector.get_check_constraints(
table_name,
schema=schema,
)
constraint_exists = any(
c['name'] == constraint_name
for c in existing_constraints
)
if not constraint_exists:
op.create_check_constraint(
constraint_name,
table_name,
condition,
schema=schema,
)
return True
else:
return False
def create_unique_constraint_if_not_exists(
constraint_name,
table_name,
columns,
schema=None,
):
conn = op.get_bind()
inspector = sa.inspect(conn)
existing_constraints = inspector.get_unique_constraints(
table_name,
schema=schema,
)
constraint_exists = any(
c['name'] == constraint_name
for c in existing_constraints
)
if not constraint_exists:
op.create_unique_constraint(
constraint_name,
table_name,
columns,
schema=schema,
)
return True
else:
return False
def upgrade() -> None:
op.execute("CREATE SCHEMA IF NOT EXISTS v3")
create_table_if_not_exists(
'allocation',
sa.Column('line_id', sa.Integer(),
primary_key=True),
sa.Column('internal_order', sa.String()),
sa.Column('property_object', sa.String()),
sa.Column('contract_ref', sa.String()),
sa.Column('allocation_purpose', sa.String()),
schema='v3',
)
create_table_if_not_exists(
'app_user',
sa.Column('id', sa.Integer(),
primary_key=True),
sa.Column('email', sa.String(),
nullable=False),
sa.Column('username', sa.String(),
nullable=False),
sa.Column('hashed_password', sa.String(),
nullable=False),
sa.Column('full_name', sa.String()),
sa.Column('role_id', sa.Integer(),
nullable=False),
sa.Column('is_active', sa.Boolean(),
nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True),
nullable=False,
server_default=sa.func.now()),
sa.Column('updated_at', sa.DateTime(timezone=True)),
schema='v3',
)
create_index_if_not_exists(
'ix_v4_app_user_active', 'app_user', ['is_active'],
schema='v3',
postgresql_where='is_active',
)
create_index_if_not_exists(
'ix_v4_app_user_role', 'app_user', ['role_id'],
schema='v3',
)
create_table_if_not_exists(
'audit_log',
sa.Column('id', sa.BigInteger(),
primary_key=True,
autoincrement=True),
sa.Column('user_id', sa.Integer()),
sa.Column('org_unit_id', sa.Integer()),
sa.Column('task_id', sa.Integer()),
sa.Column('form_id', sa.Integer()),
sa.Column('event_dt', sa.DateTime(timezone=True),
nullable=False,
server_default=sa.func.now()),
sa.Column('event', sa.String(),
nullable=False),
sa.Column('event_type', sa.String(),
nullable=False),
sa.Column('event_data', sa.JSON()),
schema='v3',
)
create_index_if_not_exists(
'ix_v3_audit_log_form', 'audit_log', ['form_id'],
schema='v3',
postgresql_where='form_id IS NOT NULL',
)
create_index_if_not_exists(
'ix_v3_audit_log_event', 'audit_log', ['event'],
schema='v3',
)
create_index_if_not_exists(
'ix_v4_audit_log_dt', 'audit_log', ['event_dt'],
postgresql_ops={'event_dt': 'DESC'},
schema='v3',
)
create_index_if_not_exists(
'ix_v4_audit_log_event', 'audit_log', ['event'],
schema='v3',
)
create_index_if_not_exists(
'ix_v4_audit_log_form', 'audit_log', ['form_id'],
schema='v3',
postgresql_where='form_id IS NOT NULL',
)
create_index_if_not_exists(
'ix_v3_audit_log_user', 'audit_log', ['user_id'],
schema='v3',
)
create_index_if_not_exists(
'ix_v4_audit_log_user', 'audit_log', ['user_id'],
schema='v3',
)
create_index_if_not_exists(
'ix_v3_audit_log_dt', 'audit_log', ['event_dt'],
postgresql_ops={'event_dt': 'DESC'},
schema='v3',
)
create_table_if_not_exists(
'booking',
sa.Column('id', sa.Integer(),
primary_key=True),
sa.Column('line_id', sa.Integer(),
nullable=False),
sa.Column('quarter', sa.SmallInteger(),
nullable=False),
sa.Column('source', sa.String(),
nullable=False),
sa.Column('booked_amount_ckk', sa.Numeric()),
sa.Column('booked_amount_contract', sa.Numeric()),
schema='v3',
)
create_check_constraint_if_not_exists(
'ck_v3_booking_quarter', 'booking',
sa.text('quarter BETWEEN 1 AND 4'),
schema='v3',
)
create_check_constraint_if_not_exists(
'ck_v3_booking_source', 'booking',
sa.text("source IN ('CKK','CONTRACT')"),
schema='v3',
)
create_index_if_not_exists(
'ix_v3_booking_line', 'booking', ['line_id'],
schema='v3',
)
create_table_if_not_exists(
'budget_form',
sa.Column('id', sa.Integer(),
primary_key=True),
sa.Column('form_type_code', sa.String(),
nullable=False),
sa.Column('year', sa.Integer()),
sa.Column('created_by', sa.Integer()),
sa.Column('created_at', sa.DateTime(),
server_default=sa.func.now()
),
sa.Column('updated_by', sa.Integer()),
sa.Column('updated_at', sa.DateTime(),
server_default=sa.func.now(),
onupdate=sa.func.now(),
),
sa.Column('org_unit_id', sa.Integer()),
schema='v3',
)
create_table_if_not_exists(
'budget_line',
sa.Column('id', sa.Integer(),
primary_key=True),
sa.Column('budget_form_id', sa.Integer(),
nullable=False),
sa.Column('expense_item_id', sa.Integer()),
sa.Column('name', sa.String()),
sa.Column('internal_order', sa.String()),
sa.Column('vsp_id', sa.Integer()),
sa.Column('project_id', sa.Integer()),
sa.Column('justification', sa.String()),
sa.Column('created_by', sa.Integer()),
sa.Column('created_at', sa.DateTime()),
sa.Column('updated_by', sa.Integer()),
sa.Column('updated_at', sa.DateTime()),
sa.Column('direction', sa.String()),
schema='v3',
)
create_index_if_not_exists(
'ix_v3_budget_line_vsp', 'budget_line', ['vsp_id'],
schema='v3',
)
create_index_if_not_exists(
'ix_v3_budget_line_form_item', 'budget_line', ['budget_form_id', 'expense_item_id'],
schema='v3',
)
create_table_if_not_exists(
'budget_line_quarter',
sa.Column('line_id', sa.Integer(),
primary_key=True),
sa.Column('quarter', sa.SmallInteger(),
primary_key=True),
sa.Column('adj_current', sa.Numeric()),
sa.Column('adj_ssp', sa.Numeric()),
sa.Column('adj_rf', sa.Numeric()),
sa.Column('adj_reserve', sa.Numeric()),
sa.Column('adj_comment', sa.String()),
sa.Column('target_change', sa.Numeric()),
sa.Column('base_plan_correction', sa.Numeric()),
sa.Column('base_plan_correction_comment', sa.String()),
sa.Column('payment_date', sa.Date()),
sa.Column('payment_amount', sa.Numeric()),
sa.Column('payment_amount_ho', sa.Numeric()),
sa.Column('payment_amount_rf', sa.Numeric()),
sa.Column('payment_comment', sa.String()),
sa.Column('payment_act', sa.String()),
sa.Column('actual_m1', sa.Numeric()),
sa.Column('actual_m2', sa.Numeric()),
sa.Column('actual_m3', sa.Numeric()),
sa.Column('actual_spod', sa.Numeric()),
sa.Column('transfer_to_q2', sa.Numeric()),
sa.Column('transfer_to_q3', sa.Numeric()),
sa.Column('transfer_to_q4', sa.Numeric()),
sa.Column('transfer_to_economy', sa.Numeric()),
sa.Column('transfer_delay_acts', sa.Numeric()),
sa.Column('transfer_delay_procurement', sa.Numeric()),
sa.Column('transfer_economy_rf', sa.Numeric()),
sa.Column('transfer_next_comment', sa.String()),
sa.Column('transfer_far_comment', sa.String()),
sa.Column('booking_amount', sa.Numeric()),
sa.Column('plan_revision_eco_change', sa.Numeric()),
sa.Column('plan_revision_item_adj', sa.Numeric()),
sa.Column('plan_revision_increase', sa.Numeric()),
sa.Column('plan_revision_sequester', sa.Numeric()),
sa.Column('plan_revision_comment', sa.String()),
schema='v3',
)
create_check_constraint_if_not_exists(
'chk_budget_line_quarter_quarter', 'budget_line_quarter',
sa.text('quarter >= 1 AND quarter <= 4'),
schema='v3',
)
create_table_if_not_exists(
'ckk',
sa.Column('line_id', sa.Integer(),
primary_key=True),
sa.Column('ceiling_amount', sa.Numeric()),
sa.Column('expenses_q1', sa.Numeric()),
sa.Column('expenses_q2', sa.Numeric()),
sa.Column('expenses_q3', sa.Numeric()),
sa.Column('expenses_q4', sa.Numeric()),
sa.Column('expenses_next_year_q1', sa.Numeric()),
sa.Column('expenses_next_year_q2', sa.Numeric()),
sa.Column('expenses_next_year_q3', sa.Numeric()),
sa.Column('expenses_next_year_q4', sa.Numeric()),
sa.Column('rf_schedule', sa.String()),
sa.Column('delivery_deadline', sa.String()),
sa.Column('procurement_plan', sa.String()),
sa.Column('procurement_method', sa.String()),
sa.Column('comment', sa.String()),
schema='v3',
)
create_table_if_not_exists(
'collegial_approval',
sa.Column('line_id', sa.Integer(),
primary_key=True),
sa.Column('approved_amount', sa.Numeric()),
sa.Column('protocol_reference', sa.String()),
sa.Column('note', sa.String()),
schema='v3',
)
create_table_if_not_exists(
'contract_detail',
sa.Column('line_id', sa.Integer(),
primary_key=True),
sa.Column('counterparty', sa.String()),
sa.Column('reference', sa.String()),
sa.Column('addenda', sa.String()),
sa.Column('subject', sa.String()),
sa.Column('currency', sa.String()),
sa.Column('ceiling_amount', sa.Numeric()),
sa.Column('expenses_q1', sa.Numeric()),
sa.Column('expenses_q2', sa.Numeric()),
sa.Column('expenses_q3', sa.Numeric()),
sa.Column('expenses_q4', sa.Numeric()),
sa.Column('rf_schedule', sa.String()),
sa.Column('vat_rate', sa.String()),
sa.Column('exchange_rate', sa.Numeric()),
sa.Column('amount_foreign', sa.Numeric()),
sa.Column('deadline', sa.String()),
sa.Column('payment_scheme', sa.String()),
sa.Column('act', sa.String()),
sa.Column('comment', sa.String()),
sa.Column('contract_date', sa.Date()),
schema='v3',
)
create_table_if_not_exists(
'contract_summary',
sa.Column('line_id', sa.Integer(),
primary_key=True),
sa.Column('total_amount', sa.Numeric()),
sa.Column('counterparty', sa.String()),
sa.Column('reference', sa.String()),
sa.Column('deadline', sa.String()),
sa.Column('comment', sa.String()),
sa.Column('future_payments_y1', sa.Numeric()),
sa.Column('future_payments_y2', sa.Numeric()),
sa.Column('other_ssp_amount', sa.Numeric()),
sa.Column('centralized_flag', sa.String()),
schema='v3',
)
create_table_if_not_exists(
'expense_item',
sa.Column('id', sa.Integer(),
primary_key=True),
sa.Column('section_code', sa.String()),
sa.Column('item_id', sa.String()),
sa.Column('num_group_id', sa.String()),
sa.Column('name', sa.String()),
sa.Column('sheet', sa.String()),
sa.Column('direction', sa.String()),
sa.Column('parent_id', sa.Integer()),
sa.Column('depth', sa.Integer()),
schema='v3',
)
create_check_constraint_if_not_exists(
'expense_item_sheet_check', 'expense_item',
sa.text("sheet IN ('AHR', 'CAP', 'OPER')"),
schema='v3',
)
create_check_constraint_if_not_exists(
'expense_item_direction_check', 'expense_item',
sa.text("direction IN ('Support', 'Development')"),
schema='v3',
)
create_index_if_not_exists(
'ix_v3_expense_item_parent', 'expense_item', ['parent_id'],
schema='v3',
)
create_index_if_not_exists(
'ix_v3_expense_item_sheet', 'expense_item', ['sheet'],
schema='v3',
)
create_table_if_not_exists(
'form_limit',
sa.Column('budget_form_id', sa.Integer(),
primary_key=True),
sa.Column('template_id', sa.Integer(),
primary_key=True),
sa.Column('qty_q1', sa.Integer()),
sa.Column('qty_q2', sa.Integer()),
sa.Column('qty_q3', sa.Integer()),
sa.Column('qty_q4', sa.Integer()),
sa.Column('comment', sa.String()),
schema='v3',
)
create_index_if_not_exists(
'ix_v3_form_limit_form', 'form_limit', ['budget_form_id'],
schema='v3',
)
create_table_if_not_exists(
'form_phase',
sa.Column('budget_form_id', sa.Integer(),
primary_key=True),
sa.Column('sheet', sa.String(),
primary_key=True),
sa.Column('phase_code', sa.String(),
primary_key=True),
sa.Column('role', sa.String(),
nullable=False),
sa.Column('column_keys', postgresql.ARRAY(sa.Text()),
nullable=False),
sa.Column('opens_at', sa.DateTime(timezone=True),
nullable=False),
sa.Column('closes_at', sa.DateTime(timezone=True),
nullable=False),
schema='v3',
)
create_check_constraint_if_not_exists(
'chk_v4_form_phase_window', 'form_phase',
sa.text('closes_at > opens_at'),
schema='v3',
)
create_check_constraint_if_not_exists(
'chk_v4_form_phase_columns', 'form_phase',
sa.text('cardinality(column_keys) > 0'),
schema='v3',
)
create_check_constraint_if_not_exists(
'chk_v4_form_phase_no_admin', 'form_phase',
sa.text("role != 'ADMIN'"),
schema='v3',
)
create_table_if_not_exists(
'form_type',
sa.Column('code', sa.String(),
primary_key=True),
sa.Column('name', sa.String()),
sa.Column('scope', sa.String()),
sa.Column('storage_entity', sa.String()),
schema='v3',
)
create_check_constraint_if_not_exists(
'ck_form_type_scope', 'form_type',
sa.text("scope IN ('GO','PD','RF')"),
schema='v3',
)
create_check_constraint_if_not_exists(
'ck_form_type_storage_entity', 'form_type',
sa.text("storage_entity IN ('BUDGET_FORM','RF_PROJECT_REPORT')"),
schema='v3',
)
create_table_if_not_exists(
'limit_template',
sa.Column('id', sa.Integer(),
primary_key=True),
sa.Column('parent_id', sa.Integer()),
sa.Column('sort_order', sa.Integer(),
nullable=False),
sa.Column('row_type', sa.String(),
nullable=False),
sa.Column('section_no', sa.String()),
sa.Column('expense_item_code', sa.String()),
sa.Column('name', sa.String(),
nullable=False),
sa.Column('unit', sa.String()),
sa.Column('limit_with_vat', sa.Numeric()),
sa.Column('limit_without_vat', sa.Numeric()),
schema='v3',
)
create_check_constraint_if_not_exists(
'ck_v3_limit_template_row_type', 'limit_template',
sa.text("row_type IN ('SECTION','GROUP','LEAF')"),
schema='v3',
)
create_index_if_not_exists(
'ix_v3_limit_template_parent', 'limit_template', ['parent_id'],
schema='v3',
)
create_table_if_not_exists(
'org_unit',
sa.Column('id', sa.Integer(),
primary_key=True),
sa.Column('title', sa.String(),
nullable=False),
sa.Column('is_active', sa.Boolean(),
nullable=False),
sa.Column('is_ssp', sa.Boolean(),
nullable=False),
schema='v3',
)
create_index_if_not_exists(
'ix_v4_org_unit_active', 'org_unit', ['is_active'],
schema='v3',
postgresql_where='is_active', )
create_table_if_not_exists(
'phase_template',
sa.Column('form_type', sa.String(),
primary_key=True),
sa.Column('sheet', sa.String(),
primary_key=True),
sa.Column('phase_code', sa.String(),
primary_key=True),
sa.Column('role', sa.String(),
nullable=False),
sa.Column('column_keys', postgresql.ARRAY(sa.Text()),
nullable=False),
sa.Column('opens_at', sa.DateTime(timezone=True),
nullable=False),
sa.Column('closes_at', sa.DateTime(timezone=True),
nullable=False),
schema='v3',
)
create_check_constraint_if_not_exists(
'chk_v4_phase_template_columns', 'phase_template',
sa.text('cardinality(column_keys) > 0'),
schema='v3',
)
create_check_constraint_if_not_exists(
'chk_v4_phase_template_no_admin', 'phase_template',
sa.text("role != 'ADMIN'"),
schema='v3',
)
create_check_constraint_if_not_exists(
'chk_v4_phase_template_window', 'phase_template',
sa.text('closes_at > opens_at'),
schema='v3',
)
create_table_if_not_exists(
'plan',
sa.Column('line_id', sa.Integer(),
primary_key=True),
sa.Column('plan_q1', sa.Numeric()),
sa.Column('plan_q2', sa.Numeric()),
sa.Column('plan_q3', sa.Numeric()),
sa.Column('plan_q4', sa.Numeric()),
sa.Column('comment', sa.String()),
schema='v3',
)
create_table_if_not_exists(
'project',
sa.Column('id', sa.Integer(),
primary_key=True),
sa.Column('name', sa.String()),
sa.Column('level', sa.String()),
sa.Column('parent_id', sa.Integer()),
sa.Column('project_type', sa.String()),
sa.Column('vsp_format', sa.String()),
sa.Column('placement_type', sa.String()),
sa.Column('object_address', sa.String()),
sa.Column('staff_count', sa.Integer()),
sa.Column('total_area', sa.Numeric()),
sa.Column('org_unit_id', sa.Integer()),
schema='v3',
)
create_check_constraint_if_not_exists(
'project_project_type_check', 'project',
sa.text("project_type IS NULL OR project_type IN ('current', 'development')"),
schema='v3',
)
create_check_constraint_if_not_exists(
'project_level_check', 'project',
sa.text("level IN ('program', 'project')"),
schema='v3',
)
create_check_constraint_if_not_exists(
'project_vsp_format_check', 'project',
sa.text("vsp_format IS NULL OR vsp_format IN ('office', 'standalone', 'atm', 'other')"),
schema='v3',
)
create_check_constraint_if_not_exists(
'project_placement_type_check', 'project',
sa.text("placement_type IS NULL OR placement_type IN ('own', 'rent', 'other')"),
schema='v3',
)
create_check_constraint_if_not_exists(
'chk_v3_project_name', 'project',
sa.text("name IS NOT NULL AND name <> ''"),
schema='v3',
)
create_index_if_not_exists(
'ix_v3_project_ssp', 'project', ['org_unit_id'],
schema='v3',
)
create_table_if_not_exists(
'rent_detail',
sa.Column('id', sa.Integer(),
primary_key=True),
sa.Column('line_id', sa.Integer(),
nullable=False),
sa.Column('vsp_id', sa.Integer(),
nullable=False),
sa.Column('contract_number', sa.String()),
sa.Column('contract_end_date', sa.Date()),
sa.Column('plan_q1', sa.Numeric()),
sa.Column('plan_q2', sa.Numeric()),
sa.Column('plan_q3', sa.Numeric()),
sa.Column('plan_q4', sa.Numeric()),
sa.Column('actual_jan', sa.Numeric()),
sa.Column('actual_feb', sa.Numeric()),
sa.Column('actual_mar', sa.Numeric()),
sa.Column('actual_apr', sa.Numeric()),
sa.Column('actual_may', sa.Numeric()),
sa.Column('actual_jun', sa.Numeric()),
sa.Column('actual_jul', sa.Numeric()),
sa.Column('actual_aug', sa.Numeric()),
sa.Column('actual_sep', sa.Numeric()),
sa.Column('actual_oct', sa.Numeric()),
sa.Column('actual_nov', sa.Numeric()),
sa.Column('actual_dec', sa.Numeric()),
sa.Column('comment', sa.String()),
schema='v3',
)
create_index_if_not_exists(
'ix_v3_rent_detail_line', 'rent_detail', ['line_id'],
schema='v3',
)
create_index_if_not_exists(
'ix_v3_rent_detail_vsp', 'rent_detail', ['vsp_id'],
schema='v3',
)
create_table_if_not_exists(
'reserve',
sa.Column('line_id', sa.Integer(),
primary_key=True),
sa.Column('amount_q1', sa.Numeric()),
sa.Column('amount_q2', sa.Numeric()),
sa.Column('amount_q3', sa.Numeric()),
sa.Column('amount_q4', sa.Numeric()),
sa.Column('justification', sa.String()),
schema='v3',
)
create_table_if_not_exists(
'rf_project_report',
sa.Column('id', sa.Integer(),
primary_key=True),
sa.Column('project_id', sa.Integer(),
nullable=False),
sa.Column('year', sa.Integer(),
nullable=False),
sa.Column('report_type', sa.String(),
nullable=False),
sa.Column('created_by', sa.Integer()),
sa.Column('created_at', sa.DateTime(),
server_default=sa.func.now()),
sa.Column('updated_by', sa.Integer()),
sa.Column('updated_at', sa.DateTime(),
server_default=sa.func.now()),
schema='v3',
)
create_index_if_not_exists(
'ix_v3_rf_project_report_proj_year', 'rf_project_report', ['project_id', 'year'],
schema='v3',
)
create_unique_constraint_if_not_exists(
'uq_v3_rf_project_report', 'rf_project_report',
['project_id', 'year', 'report_type'],
schema='v3',
)
create_table_if_not_exists(
'rf_project_report_line',
sa.Column('id', sa.Integer(),
primary_key=True),
sa.Column('rf_project_report_id', sa.Integer(),
nullable=False),
sa.Column('expense_item_id', sa.Integer(),
nullable=False),
schema='v3',
)
create_index_if_not_exists(
'ix_v3_rf_project_report_line_rep', 'rf_project_report_line', ['rf_project_report_id'],
schema='v3',
)
create_unique_constraint_if_not_exists(
'uq_v3_rf_project_report_line', 'rf_project_report_line',
['rf_project_report_id', 'expense_item_id'],
schema='v3',
)
create_table_if_not_exists(
'rf_project_report_quarter',
sa.Column('rf_project_report_line_id', sa.Integer(),
primary_key=True),
sa.Column('quarter', sa.SmallInteger(),
primary_key=True),
sa.Column('adj_by_items', sa.Numeric()),
sa.Column('adj_increase', sa.Numeric()),
sa.Column('actual_m1', sa.Numeric()),
sa.Column('actual_m2', sa.Numeric()),
sa.Column('actual_m3', sa.Numeric()),
sa.Column('actual_spod', sa.Numeric()),
schema='v3',
)
create_table_if_not_exists(
'role',
sa.Column('id', sa.Integer(),
primary_key=True, autoincrement=False),
sa.Column('code', sa.String(),
nullable=False),
schema='v3',
)
create_unique_constraint_if_not_exists(
'uq_role_code', 'role',
['code'],
schema='v3',
)
create_table_if_not_exists(
'security_detail',
sa.Column('id', sa.Integer(),
primary_key=True),
sa.Column('line_id', sa.Integer(),
nullable=False),
sa.Column('vsp_id', sa.Integer(),
nullable=False),
sa.Column('contract_number', sa.String()),
sa.Column('contract_end_date', sa.Date()),
sa.Column('plan_q1', sa.Numeric()),
sa.Column('plan_q2', sa.Numeric()),
sa.Column('plan_q3', sa.Numeric()),
sa.Column('plan_q4', sa.Numeric()),
sa.Column('actual_jan', sa.Numeric()),
sa.Column('actual_feb', sa.Numeric()),
sa.Column('actual_mar', sa.Numeric()),
sa.Column('actual_apr', sa.Numeric()),
sa.Column('actual_may', sa.Numeric()),
sa.Column('actual_jun', sa.Numeric()),
sa.Column('actual_jul', sa.Numeric()),
sa.Column('actual_aug', sa.Numeric()),
sa.Column('actual_sep', sa.Numeric()),
sa.Column('actual_oct', sa.Numeric()),
sa.Column('actual_nov', sa.Numeric()),
sa.Column('actual_dec', sa.Numeric()),
sa.Column('comment', sa.String()),
schema='v3',
)
create_index_if_not_exists(
'ix_v3_security_detail_vsp', 'security_detail', ['vsp_id'],
schema='v3',
)
create_index_if_not_exists(
'ix_v3_security_detail_line', 'security_detail', ['line_id'],
schema='v3',
)
create_table_if_not_exists(
'sequestration',
sa.Column('id', sa.Integer(),
primary_key=True),
sa.Column('line_id', sa.Integer(),
nullable=False),
sa.Column('actor', sa.String(),
nullable=False),
sa.Column('adj_q1', sa.Numeric()),
sa.Column('adj_q2', sa.Numeric()),
sa.Column('adj_q3', sa.Numeric()),
sa.Column('adj_q4', sa.Numeric()),
sa.Column('justification', sa.String()),
schema='v3',
)
create_check_constraint_if_not_exists(
'ck_v3_sequestration_actor', 'sequestration',
sa.text("actor IN ('DFIP','SSP_GO')"),
schema='v3',
)
create_index_if_not_exists(
'ix_v3_sequestration_line_actor', 'sequestration', ['line_id', 'actor'],
schema='v3',
)
create_unique_constraint_if_not_exists(
'uq_v3_sequestration_line_actor', 'sequestration',
['line_id', 'actor'],
schema='v3',
)
create_table_if_not_exists(
'user_org',
sa.Column('id', sa.Integer(),
primary_key=True),
sa.Column('user_id', sa.Integer(),
nullable=False),
sa.Column('org_unit_id', sa.Integer(),
nullable=False),
schema='v3',
)
create_index_if_not_exists(
'ix_v4_user_org_user', 'user_org', ['user_id'],
schema='v3',
)
create_index_if_not_exists(
'ix_v4_user_org_org', 'user_org', ['org_unit_id'],
schema='v3',
)
create_unique_constraint_if_not_exists(
None, 'user_org',
['user_id', 'org_unit_id'],
schema='v3',
)
create_table_if_not_exists(
'utility_detail',
sa.Column('id', sa.Integer(),
primary_key=True),
sa.Column('line_id', sa.Integer(),
nullable=False),
sa.Column('vsp_id', sa.Integer(),
nullable=False),
sa.Column('contract_number', sa.String()),
sa.Column('contract_end_date', sa.Date()),
sa.Column('plan_q1', sa.Numeric()),
sa.Column('plan_q2', sa.Numeric()),
sa.Column('plan_q3', sa.Numeric()),
sa.Column('plan_q4', sa.Numeric()),
sa.Column('actual_jan', sa.Numeric()),
sa.Column('actual_feb', sa.Numeric()),
sa.Column('actual_mar', sa.Numeric()),
sa.Column('actual_apr', sa.Numeric()),
sa.Column('actual_may', sa.Numeric()),
sa.Column('actual_jun', sa.Numeric()),
sa.Column('actual_jul', sa.Numeric()),
sa.Column('actual_aug', sa.Numeric()),
sa.Column('actual_sep', sa.Numeric()),
sa.Column('actual_oct', sa.Numeric()),
sa.Column('actual_nov', sa.Numeric()),
sa.Column('actual_dec', sa.Numeric()),
sa.Column('comment', sa.String()),
schema='v3',
)
create_index_if_not_exists(
'ix_v3_utility_detail_line', 'utility_detail', ['line_id'],
schema='v3',
)
create_index_if_not_exists(
'ix_v3_utility_detail_vsp', 'utility_detail', ['vsp_id'],
schema='v3',
)
create_table_if_not_exists(
'vsp',
sa.Column('id', sa.Integer(),
primary_key=True),
sa.Column('branch_id', sa.Integer(),
nullable=False),
sa.Column('reg_number', sa.String()),
sa.Column('address', sa.String()),
sa.Column('format', sa.String()),
sa.Column('opened_at', sa.Date()),
sa.Column('placement_type', sa.String()),
sa.Column('staff_count', sa.Integer()),
sa.Column('total_area', sa.Numeric()),
sa.Column('closed_at', sa.Date()),
sa.Column('is_active', sa.Boolean(),
nullable=False),
sa.Column('is_deleted', sa.Boolean(),
nullable=False),
sa.Column('system_code', sa.String(100)),
sa.Column('created_at', sa.DateTime(timezone=True),
nullable=False,
server_default=sa.func.now()),
sa.Column('updated_at', sa.DateTime(timezone=True)),
sa.Column('created_by', sa.Integer()),
sa.Column('updated_by', sa.Integer()),
sa.Column('vsp_type', sa.String(100)),
sa.Column('notes', sa.Text()),
sa.Column('location_form', sa.String()),
sa.Column('rent_contract_num', sa.String()),
sa.Column('rent_end_date', sa.Date()),
schema='v3',
)
create_check_constraint_if_not_exists(
'chk_closed_after_opened', 'vsp',
sa.text('closed_at IS NULL OR opened_at IS NULL OR closed_at >= opened_at'),
schema='v3',
)
create_unique_constraint_if_not_exists(
'vsp_reg_number_unique', 'vsp',
['reg_number'],
schema='v3',
)
create_table_if_not_exists(
'fixed_asset_report',
sa.Column('id', sa.Integer(), primary_key=True, autoincrement=True),
sa.Column('budget_form_id', sa.Integer(), nullable=False),
sa.Column('expense_item_id', sa.Integer()),
sa.Column('equipment_name', sa.String()),
sa.Column('month', sa.SmallInteger(), nullable=False),
sa.Column('opening_qty_604', sa.Integer()),
sa.Column('opening_amt_604', sa.Numeric()),
sa.Column('acquired_qty_604', sa.Integer()),
sa.Column('acquired_amt_604', sa.Numeric()),
sa.Column('disposed_qty_604', sa.Integer()),
sa.Column('disposed_amt_604', sa.Numeric()),
sa.Column('opening_qty_60415', sa.Integer()),
sa.Column('opening_amt_60415', sa.Numeric()),
sa.Column('acquired_qty_60415', sa.Integer()),
sa.Column('acquired_amt_60415', sa.Numeric()),
sa.Column('transferred_qty_60415', sa.Integer()),
sa.Column('transferred_amt_60415', sa.Numeric()),
sa.Column('go_balance_only_amt', sa.Numeric()),
schema='v3',
)
create_check_constraint_if_not_exists(
'fixed_asset_report_month_check', 'fixed_asset_report',
sa.text('month >= 1 AND month <= 12'),
schema='v3',
)
create_index_if_not_exists(
'ix_v3_fixed_asset_report_form', 'fixed_asset_report', ['budget_form_id'],
schema='v3',
)
create_index_if_not_exists(
'ix_v3_fixed_asset_report_item', 'fixed_asset_report', ['expense_item_id'],
schema='v3',
)
create_table_if_not_exists(
'expense_item_form_type',
sa.Column('expense_item_id', sa.Integer(), primary_key=True),
sa.Column('form_type_code', sa.String(), primary_key=True),
schema='v3',
)
create_index_if_not_exists(
'ix_v3_eift_item', 'expense_item_form_type', ['expense_item_id'],
schema='v3',
)
op.execute(
"""
CREATE MATERIALIZED VIEW IF NOT EXISTS v3.mv_expense_item_tree
TABLESPACE pg_default
AS WITH RECURSIVE tree AS (
SELECT ei.id,
ei.sheet,
ei.section_code,
ei.item_id,
ei.num_group_id,
ei.name,
ei.parent_id,
ei.depth,
ARRAY[ei.id] AS path,
NULL::character varying AS parent_item_id
FROM v3.expense_item ei
WHERE ei.parent_id IS NULL
UNION ALL
SELECT ei.id,
ei.sheet,
ei.section_code,
ei.item_id,
ei.num_group_id,
ei.name,
ei.parent_id,
ei.depth,
t_1.path || ei.id,
t_1.item_id AS parent_item_id
FROM v3.expense_item ei
JOIN tree t_1 ON ei.parent_id = t_1.id
)
SELECT id,
sheet,
section_code,
item_id,
num_group_id,
name,
parent_id,
parent_item_id,
depth,
path,
ARRAY( SELECT c.id
FROM tree c
WHERE t.id = ANY (c.path)) AS desc_ids
FROM tree t
WITH DATA;
"""
)
op.execute("CREATE INDEX IF NOT EXISTS ix_v3_mv_expense_item_tree_sheet ON v3.mv_expense_item_tree USING btree (sheet);")
op.execute("CREATE UNIQUE INDEX IF NOT EXISTS ux_v2_mv_expense_item_tree_id ON v3.mv_expense_item_tree USING btree (id);")
def downgrade() -> None:
pass