""" Pension calculation models based on legacy PENSION.SC analysis """ from sqlalchemy import Column, Integer, String, Date, Text, Float, ForeignKey from sqlalchemy.orm import relationship from app.models.base import BaseModel class Pension(BaseModel): """ Pension calculation data Corresponds to PENSIONS table in legacy system """ __tablename__ = "pensions" id = Column(Integer, primary_key=True, autoincrement=True) file_no = Column(String(45), ForeignKey("files.file_no"), nullable=False) version = Column(String(10), default="01") # Version number plan_id = Column(String(45)) # Plan identifier plan_name = Column(String(200)) # Name of pension plan # Participant information title = Column(String(10)) # Mr., Mrs., Ms., etc. first = Column(String(50)) # First name last = Column(String(100)) # Last name birth = Column(Date) # Date of birth race = Column(String(1)) # Race code sex = Column(String(1)) # M/F # Pension calculation data info = Column(Text) # Additional pension information valu = Column(Float, default=0.0) # Pension valuation accrued = Column(Float, default=0.0) # Accrued benefit vested_per = Column(Float, default=0.0) # Vested percentage start_age = Column(Integer) # Starting age for benefits # Cost of living and withdrawal details cola = Column(Float, default=0.0) # Cost of living adjustment max_cola = Column(Float, default=0.0) # Maximum COLA withdrawal = Column(String(45)) # Withdrawal method pre_dr = Column(Float, default=0.0) # Pre-retirement discount rate post_dr = Column(Float, default=0.0) # Post-retirement discount rate tax_rate = Column(Float, default=0.0) # Tax rate # Relationships file = relationship("File", back_populates="pensions") def __repr__(self): return f"" class PensionSchedule(BaseModel): """ Pension payment schedules Corresponds to SCHEDULE table in legacy system """ __tablename__ = "pension_schedules" id = Column(Integer, primary_key=True, autoincrement=True) file_no = Column(String(45), ForeignKey("files.file_no"), nullable=False) version = Column(String(10), default="01") # Schedule details (legacy vesting fields) start_date = Column(Date) # Start date for payments end_date = Column(Date) # End date for payments payment_amount = Column(Float, default=0.0) # Payment amount frequency = Column(String(20)) # Monthly, quarterly, etc. vests_on = Column(Date) # Legacy SCHEDULE.csv Vests_On vests_at = Column(Float, default=0.0) # Legacy SCHEDULE.csv Vests_At (percent) # Relationships file = relationship("File", back_populates="pension_schedules") class MarriageHistory(BaseModel): """ Marriage/divorce history for pension calculations Corresponds to MARRIAGE table in legacy system """ __tablename__ = "marriage_history" id = Column(Integer, primary_key=True, autoincrement=True) file_no = Column(String(45), ForeignKey("files.file_no"), nullable=False) version = Column(String(10), default="01") # Marriage details marriage_date = Column(Date) # Date of marriage divorce_date = Column(Date) # Date of divorce/separation spouse_name = Column(String(100)) # Spouse name notes = Column(Text) # Additional notes # Legacy MARRIAGE.csv fields married_from = Column(Date) married_to = Column(Date) married_years = Column(Float, default=0.0) service_from = Column(Date) service_to = Column(Date) service_years = Column(Float, default=0.0) marital_percent = Column(Float, default=0.0) # Relationships file = relationship("File", back_populates="marriage_history") class DeathBenefit(BaseModel): """ Death benefit information Corresponds to DEATH table in legacy system """ __tablename__ = "death_benefits" id = Column(Integer, primary_key=True, autoincrement=True) file_no = Column(String(45), ForeignKey("files.file_no"), nullable=False) version = Column(String(10), default="01") # Death benefit details beneficiary_name = Column(String(100)) # Beneficiary name benefit_amount = Column(Float, default=0.0) # Benefit amount benefit_type = Column(String(45)) # Type of death benefit notes = Column(Text) # Additional notes # Legacy DEATH.csv fields lump1 = Column(Float, default=0.0) lump2 = Column(Float, default=0.0) growth1 = Column(Float, default=0.0) growth2 = Column(Float, default=0.0) disc1 = Column(Float, default=0.0) disc2 = Column(Float, default=0.0) # Relationships file = relationship("File", back_populates="death_benefits") class SeparationAgreement(BaseModel): """ Separation agreement details Corresponds to SEPARATE table in legacy system """ __tablename__ = "separation_agreements" id = Column(Integer, primary_key=True, autoincrement=True) file_no = Column(String(45), ForeignKey("files.file_no"), nullable=False) version = Column(String(10), default="01") # Agreement details agreement_date = Column(Date) # Date of agreement terms = Column(Text) # Terms of separation notes = Column(Text) # Additional notes # Relationships file = relationship("File", back_populates="separation_agreements") class LifeTable(BaseModel): """ Life expectancy tables for actuarial calculations Corresponds to LIFETABL table in legacy system """ __tablename__ = "life_tables" id = Column(Integer, primary_key=True, autoincrement=True) age = Column(Integer, nullable=False) # Age # Rich typed columns reflecting legacy LIFETABL.csv headers # LE_* = Life Expectancy, NA_* = Number Alive/Survivors le_aa = Column(Float) na_aa = Column(Float) le_am = Column(Float) na_am = Column(Float) le_af = Column(Float) na_af = Column(Float) le_wa = Column(Float) na_wa = Column(Float) le_wm = Column(Float) na_wm = Column(Float) le_wf = Column(Float) na_wf = Column(Float) le_ba = Column(Float) na_ba = Column(Float) le_bm = Column(Float) na_bm = Column(Float) le_bf = Column(Float) na_bf = Column(Float) le_ha = Column(Float) na_ha = Column(Float) le_hm = Column(Float) na_hm = Column(Float) le_hf = Column(Float) na_hf = Column(Float) # Optional metadata retained for future variations table_year = Column(Integer) # Year/version of table if known table_type = Column(String(45)) # Source/type of table (optional) class NumberTable(BaseModel): """ Numerical tables for calculations Corresponds to NUMBERAL table in legacy system """ __tablename__ = "number_tables" id = Column(Integer, primary_key=True, autoincrement=True) month = Column(Integer, nullable=False) # Rich typed NA_* columns reflecting legacy NUMBERAL.csv headers na_aa = Column(Float) na_am = Column(Float) na_af = Column(Float) na_wa = Column(Float) na_wm = Column(Float) na_wf = Column(Float) na_ba = Column(Float) na_bm = Column(Float) na_bf = Column(Float) na_ha = Column(Float) na_hm = Column(Float) na_hf = Column(Float) # Optional metadata retained for future variations table_type = Column(String(45)) description = Column(Text) class PensionResult(BaseModel): """ Computed pension results summary Corresponds to RESULTS table in legacy system """ __tablename__ = "pension_results" id = Column(Integer, primary_key=True, autoincrement=True) # Optional linkage if present in future exports file_no = Column(String(45)) version = Column(String(10)) # Columns observed in legacy RESULTS.csv header accrued = Column(Float) start_age = Column(Integer) cola = Column(Float) withdrawal = Column(String(45)) pre_dr = Column(Float) post_dr = Column(Float) tax_rate = Column(Float) age = Column(Integer) years_from = Column(Float) life_exp = Column(Float) ev_monthly = Column(Float) payments = Column(Float) pay_out = Column(Float) fund_value = Column(Float) pv = Column(Float) mortality = Column(Float) pv_am = Column(Float) pv_amt = Column(Float) pv_pre_db = Column(Float) pv_annuity = Column(Float) wv_at = Column(Float) pv_plan = Column(Float) years_married = Column(Float) years_service = Column(Float) marr_per = Column(Float) marr_amt = Column(Float)