from odoo import api, fields, models class FlFeeWaiver(models.Model): """ FL Statute 57.082 — Determination of Civil Indigent Status. Income threshold: < 200% of federal poverty level. 2025 Federal Poverty Level (HHS): Base (1 person): $15,060/year Per additional person: $5,380/year Update FPL_BASE and FPL_PER_PERSON constants annually. Source: https://aspe.hhs.gov/topics/poverty-economic-mobility/poverty-guidelines """ _name = 'fl.fee.waiver' _description = 'Fee Waiver / Civil Indigent Status (FL 57.082)' _inherit = ['mail.thread'] _order = 'create_date desc' # 2025 FPL constants — UPDATE ANNUALLY FPL_BASE_2025 = 15060 # 1-person household FPL_PER_PERSON_2025 = 5380 # Each additional person case_id = fields.Many2one( 'fl.case', string='Case', ondelete='cascade', index=True ) party_id = fields.Many2one( 'res.partner', string='Applicant', required=True ) # ── Income & Household ───────────────────────────────────────────────── household_size = fields.Integer( string='Household Size', required=True, default=1, help='Include all persons in the household (applicant + dependents + spouse/partner)' ) monthly_gross_income = fields.Float( string='Monthly Gross Income ($)', required=True, help='Total gross monthly income from all sources' ) annual_gross_income = fields.Float( string='Annual Gross Income ($)', compute='_compute_annual', store=True ) # ── FPL Threshold Calculation ────────────────────────────────────────── fpl_annual = fields.Float( string='Federal Poverty Level — Annual ($)', compute='_compute_threshold', store=True, help='100% FPL for this household size' ) fpl_200pct_threshold = fields.Float( string='200% FPL Threshold ($)', compute='_compute_threshold', store=True, help='200% FPL — income must be below this to qualify' ) eligible = fields.Boolean( string='Fee Waiver Eligible', compute='_compute_eligibility', store=True ) eligibility_note = fields.Char( string='Eligibility Result', compute='_compute_eligibility' ) # ── Miami-Dade Mediator Fee Waiver (FL 44.108) ───────────────────────── mediator_fee_waiver_eligible = fields.Boolean( string='Mediator Fee Waiver Eligible (FL 44.108)', compute='_compute_mediator_waiver', store=True, help='Miami-Dade County provides free mediators for qualifying income. ' 'Same income threshold as civil indigent status (200% FPL).' ) # ── Status ──────────────────────────────────────────────────────────── state = fields.Selection([ ('draft', 'Draft'), ('submitted', 'Submitted to Clerk'), ('approved', 'Approved'), ('denied', 'Denied'), ], string='Status', default='draft', tracking=True) application_date = fields.Date( string='Application Date', default=fields.Date.today ) approval_date = fields.Date(string='Approval Date') denial_reason = fields.Text(string='Denial Reason') expiration_date = fields.Date( string='Expiration Date', help='Fee waiver approvals typically expire — check with clerk' ) clerk_stamp_attachment_ids = fields.Many2many( 'ir.attachment', 'fl_fee_waiver_attachment_rel', 'waiver_id', 'attachment_id', string='Clerk-Stamped Copy' ) notes = fields.Text(string='Notes') # ── Computed ────────────────────────────────────────────────────────── @api.depends('monthly_gross_income') def _compute_annual(self): for rec in self: rec.annual_gross_income = (rec.monthly_gross_income or 0.0) * 12 @api.depends('household_size') def _compute_threshold(self): for rec in self: size = max(rec.household_size or 1, 1) fpl = self.FPL_BASE_2025 + (size - 1) * self.FPL_PER_PERSON_2025 rec.fpl_annual = fpl rec.fpl_200pct_threshold = fpl * 2 @api.depends('annual_gross_income', 'fpl_200pct_threshold') def _compute_eligibility(self): for rec in self: annual = rec.annual_gross_income or 0.0 threshold = rec.fpl_200pct_threshold or 0.0 if annual and threshold: rec.eligible = annual <= threshold if rec.eligible: rec.eligibility_note = ( f'✅ ELIGIBLE — Annual income ${annual:,.0f} ' f'is below 200% FPL (${threshold:,.0f})' ) else: excess = annual - threshold rec.eligibility_note = ( f'❌ NOT ELIGIBLE — Annual income ${annual:,.0f} ' f'exceeds 200% FPL (${threshold:,.0f}) ' f'by ${excess:,.0f}' ) else: rec.eligible = False rec.eligibility_note = 'Enter income and household size to check eligibility' @api.depends('eligible') def _compute_mediator_waiver(self): # Miami-Dade FL 44.108 — same threshold as civil indigent status for rec in self: rec.mediator_fee_waiver_eligible = rec.eligible def action_submit(self): self.state = 'submitted' def action_approve(self): self.state = 'approved' self.approval_date = fields.Date.today() def action_deny(self): self.state = 'denied'