Files
famlaw/activeblue_familylaw/models/fl_caselaw.py
Carlos Garcia 1d52d85a78 Phase 1: core models, security, seed data, and backend views
Implements full Phase 1 of the activeblue_familylaw Odoo 18 module:
- 17 Python models (fl.case, fl.party, fl.child, fl.support.calculation,
  fl.fee.waiver, fl.income.withholding, fl.deadline, fl.hearing,
  fl.deposition, fl.discovery, fl.document, fl.caselaw, fl.analysis,
  fl.ai.engine, fl.argument, fl.statute, fl.issue.tag) + hr.expense extension
- 3 wizard stubs (intake, analysis, generate-packet)
- Security: 4 groups (admin/paralegal/portal-petitioner/portal-respondent)
  + record rules scoping portal users to their own cases
- Seed data: issue tags, FL statutes, FL DCF support schedule, ir.sequence
- 13 backend view XML files with FL 61.30 worksheet, fee waiver
  eligibility banner, DV safety resources, emancipation alerts
- Static CSS/JS stubs for Phase 6 portal

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 18:52:04 -04:00

96 lines
3.2 KiB
Python

import urllib.parse
from odoo import api, fields, models
class FlCaselaw(models.Model):
"""
Phase 5 — Full caselaw library with AI integration.
Phase 1: Full model definition (seed data loaded in Phase 5).
"""
_name = 'fl.caselaw'
_description = 'Florida Family Law Case'
_inherit = ['mail.thread']
_order = 'year desc, short_name'
_rec_name = 'short_name'
citation = fields.Char(
string='Full Citation',
required=True,
help='e.g. Smith v. Jones, 123 So.3d 456 (Fla. 3d DCA 2019)'
)
short_name = fields.Char(
string='Short Name',
required=True,
help='e.g. Smith v. Jones'
)
court = fields.Selection([
('fl_supreme', 'Florida Supreme Court'),
('1st_dca', '1st District Court of Appeal'),
('2nd_dca', '2nd District Court of Appeal'),
('3rd_dca', '3rd DCA (Miami-Dade / Monroe)'),
('4th_dca', '4th District Court of Appeal'),
('5th_dca', '5th District Court of Appeal'),
('11th_circuit', '11th Circuit Court (Trial — Miami-Dade)'),
('other', 'Other'),
], string='Court', required=True)
year = fields.Integer(string='Year', required=True)
statute_ref_ids = fields.Many2many(
'fl.statute',
'fl_caselaw_statute_rel',
'caselaw_id', 'statute_id',
string='FL Statutes'
)
issue_tag_ids = fields.Many2many(
'fl.issue.tag',
'fl_caselaw_tag_rel',
'caselaw_id', 'tag_id',
string='Issue Tags'
)
holding = fields.Text(string='Holding', required=True)
facts_summary = fields.Text(string='Facts Summary')
relevance = fields.Text(string='Why It Matters for Pro Se')
favorable_to = fields.Selection([
('petitioner', 'Petitioner / Moving Party'),
('respondent', 'Respondent'),
('neutral', 'Neutral / Procedural'),
('depends', 'Depends on Facts'),
], string='Generally Favorable To', required=True)
full_text_url = fields.Char(string='Full Opinion URL')
google_scholar_url = fields.Char(
string='Google Scholar URL',
compute='_compute_google_scholar_url'
)
case_ids = fields.Many2many(
'fl.case',
'fl_case_caselaw_rel',
'caselaw_id', 'case_id',
string='Cases Citing This'
)
active = fields.Boolean(default=True)
# Plain English summaries (AI-generated, human-reviewed)
plain_english = fields.Text(
string='Plain English Explanation (EN)',
help='What this case means for a pro se litigant — no legal jargon'
)
plain_english_es = fields.Text(
string='Plain English Explanation (ES)',
help='Explicación en español para litigantes pro se'
)
# Post-2023 flag for alimony cases
superseded_by_2023_reform = fields.Boolean(
string='Superseded by 2023 Alimony Reform (HB 1409)',
help='Pre-2023 permanent alimony cases are superseded by FL 61.08 amendment'
)
@api.depends('citation')
def _compute_google_scholar_url(self):
base = 'https://scholar.google.com/scholar?q='
for rec in self:
if rec.citation:
rec.google_scholar_url = base + urllib.parse.quote(rec.citation)
else:
rec.google_scholar_url = ''