Step 9: child-support modification workflow (end to end)
familylaw.support.modification — wires Steps 1-8 for a support modification: - open_for_case() opens a NEW modification proceeding under the same case (locked decision) and sets a 20-day answer deadline on it - 15%/$50 substantial-change PRESUMPTION: threshold = max($50, 15% of current); meets_threshold computed. Explicitly a deterministic test, NOT a prediction of whether the court grants it (no outcome/probability — EXCLUDED capability honored) - DOR / Title IV-D flag; retroactivity to filing date + note - prior-judgment handling: action_extract_prior_judgment produces a plain summary + FLAGGED interpretation QUESTIONS (carries a not-a-conclusion disclaimer); the model has no conclusion/ruling field by design. AI call mocked. Wizard + views + menu; "Open Support Modification" button on the case form (shown for support_modification matters). ACL added. Tests (familylaw_step9): new proceeding created + distinct from original; threshold 15% prong, $50 prong (met/not), change %, no-change; 20-day answer deadline + date math; DOR flag; retroactivity date; extraction summarizes + flags (not concluded, no conclusion field); extraction logs a done ai.task. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
{
|
{
|
||||||
"name": "Active Blue Family Law",
|
"name": "Active Blue Family Law",
|
||||||
"version": "18.0.8.0.0",
|
"version": "18.0.9.0.0",
|
||||||
"category": "Services/Legal",
|
"category": "Services/Legal",
|
||||||
"summary": "Florida family law case management (Miami-Dade / 11th Judicial Circuit)",
|
"summary": "Florida family law case management (Miami-Dade / 11th Judicial Circuit)",
|
||||||
"description": """
|
"description": """
|
||||||
@@ -35,6 +35,7 @@ Each step adds one vertical, independently testable slice. See BUILD_PLAN.md.
|
|||||||
"views/familylaw_disclosure_views.xml",
|
"views/familylaw_disclosure_views.xml",
|
||||||
"views/familylaw_ai_views.xml",
|
"views/familylaw_ai_views.xml",
|
||||||
"views/familylaw_discovery_views.xml",
|
"views/familylaw_discovery_views.xml",
|
||||||
|
"views/familylaw_modification_views.xml",
|
||||||
"views/familylaw_proceeding_views.xml",
|
"views/familylaw_proceeding_views.xml",
|
||||||
"views/familylaw_intake_views.xml",
|
"views/familylaw_intake_views.xml",
|
||||||
"views/familylaw_case_views.xml",
|
"views/familylaw_case_views.xml",
|
||||||
|
|||||||
@@ -13,4 +13,6 @@ from . import familylaw_citation
|
|||||||
from . import familylaw_verifier
|
from . import familylaw_verifier
|
||||||
from . import familylaw_research
|
from . import familylaw_research
|
||||||
from . import familylaw_discovery
|
from . import familylaw_discovery
|
||||||
|
from . import familylaw_modification
|
||||||
from . import familylaw_ai_wizard
|
from . import familylaw_ai_wizard
|
||||||
|
from . import familylaw_modification_wizard
|
||||||
|
|||||||
@@ -0,0 +1,161 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""STEP 9 — Child-support modification workflow (end to end).
|
||||||
|
|
||||||
|
Wires Steps 1-8 for a support modification. Per the locked decision, a modification
|
||||||
|
does NOT mutate the original action — it opens a NEW `familylaw.proceeding` under the
|
||||||
|
same case, and deadlines/documents attach to that proceeding.
|
||||||
|
|
||||||
|
Captures the deterministic, NON-judgment facts:
|
||||||
|
* the 15%/$50 substantial-change threshold (presumption of substantial change) —
|
||||||
|
computed, never an opinion on whether the court will grant it;
|
||||||
|
* the 20-day answer clock on the supplemental petition;
|
||||||
|
* the DOR / Title IV-D flag (routes differently);
|
||||||
|
* retroactivity to the filing date.
|
||||||
|
|
||||||
|
Prior-judgment handling is EXTRACTION + PLAIN SUMMARY + FLAGGED interpretation
|
||||||
|
QUESTIONS — never a conclusion or ruling (locked decision). The AI call is mocked
|
||||||
|
in tests. Nothing here decides the modification; the attorney does.
|
||||||
|
|
||||||
|
VERIFY current rule — the 15%/$50 presumption (§61.30(1)(b)) and the 20-day answer
|
||||||
|
window are volatile; confirm before relying in production.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from odoo import api, fields, models, _
|
||||||
|
|
||||||
|
THRESHOLD_PCT = 0.15 # 15% — VERIFY
|
||||||
|
THRESHOLD_MIN = 50.0 # or $50, whichever is greater — VERIFY
|
||||||
|
ANSWER_DAYS = 20 # answer to supplemental petition — VERIFY
|
||||||
|
|
||||||
|
|
||||||
|
class FamilyLawSupportModification(models.Model):
|
||||||
|
_name = "familylaw.support.modification"
|
||||||
|
_description = "Child-Support Modification"
|
||||||
|
_inherit = ["mail.thread"]
|
||||||
|
_order = "create_date desc"
|
||||||
|
|
||||||
|
name = fields.Char(default="Support Modification", tracking=True)
|
||||||
|
proceeding_id = fields.Many2one(
|
||||||
|
"familylaw.proceeding", required=True, ondelete="cascade", index=True,
|
||||||
|
tracking=True,
|
||||||
|
)
|
||||||
|
case_id = fields.Many2one(
|
||||||
|
"familylaw.case", related="proceeding_id.case_id", store=True, index=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
current_support_amount = fields.Float(string="Current Monthly Support", tracking=True)
|
||||||
|
proposed_support_amount = fields.Float(string="Proposed Monthly Support", tracking=True)
|
||||||
|
change_amount = fields.Float(compute="_compute_threshold", store=True)
|
||||||
|
change_pct = fields.Float(compute="_compute_threshold", store=True,
|
||||||
|
string="Change %")
|
||||||
|
threshold_amount = fields.Float(compute="_compute_threshold", store=True,
|
||||||
|
string="Required Min Change")
|
||||||
|
meets_threshold = fields.Boolean(
|
||||||
|
compute="_compute_threshold", store=True,
|
||||||
|
string="Meets 15%/$50 Presumption",
|
||||||
|
help="Deterministic threshold check ONLY. Whether the court grants the "
|
||||||
|
"modification is the attorney's/judge's call — not stated here.",
|
||||||
|
)
|
||||||
|
|
||||||
|
is_dor_case = fields.Boolean(
|
||||||
|
string="DOR / Title IV-D Case",
|
||||||
|
tracking=True,
|
||||||
|
help="Department of Revenue Title IV-D case — routes differently.",
|
||||||
|
)
|
||||||
|
filing_date = fields.Date(string="Petition Filing Date",
|
||||||
|
default=fields.Date.context_today, tracking=True)
|
||||||
|
retroactivity_date = fields.Date(
|
||||||
|
string="Retroactive To",
|
||||||
|
help="Modification is generally retroactive to the date the supplemental "
|
||||||
|
"petition was filed. Verify the current rule for the matter.",
|
||||||
|
)
|
||||||
|
retroactivity_note = fields.Text(
|
||||||
|
default=lambda self: _(
|
||||||
|
"A granted modification is generally retroactive to the petition filing "
|
||||||
|
"date. The attorney determines the applicable retroactivity."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Prior judgment — extraction + summary + FLAGGED questions (no conclusions)
|
||||||
|
prior_order_text = fields.Text(string="Prior Order Text")
|
||||||
|
extracted_summary = fields.Text(string="Plain-Language Summary", readonly=True)
|
||||||
|
interpretation_flags = fields.Text(
|
||||||
|
string="Interpretation Questions (for attorney)", readonly=True,
|
||||||
|
help="Questions surfaced for the attorney — never answered or concluded here.",
|
||||||
|
)
|
||||||
|
extraction_task_id = fields.Many2one("familylaw.ai.task", readonly=True)
|
||||||
|
|
||||||
|
@api.depends("current_support_amount", "proposed_support_amount")
|
||||||
|
def _compute_threshold(self):
|
||||||
|
for rec in self:
|
||||||
|
change = abs((rec.proposed_support_amount or 0.0)
|
||||||
|
- (rec.current_support_amount or 0.0))
|
||||||
|
rec.change_amount = change
|
||||||
|
base = rec.current_support_amount or 0.0
|
||||||
|
rec.change_pct = (change / base * 100.0) if base else 0.0
|
||||||
|
rec.threshold_amount = max(THRESHOLD_MIN, THRESHOLD_PCT * base)
|
||||||
|
rec.meets_threshold = change >= rec.threshold_amount and change > 0
|
||||||
|
|
||||||
|
# --- creation wiring ----------------------------------------------------
|
||||||
|
@api.model
|
||||||
|
def open_for_case(self, case, current_amount, proposed_amount, *,
|
||||||
|
is_dor=False, filing_date=None, prior_order_text=None):
|
||||||
|
"""Open a NEW modification proceeding under the case and wire its 20-day
|
||||||
|
answer deadline. Returns the modification record."""
|
||||||
|
case = case if hasattr(case, "id") else self.env["familylaw.case"].browse(case)
|
||||||
|
filing_date = filing_date or fields.Date.context_today(self)
|
||||||
|
|
||||||
|
proc = self.env["familylaw.proceeding"].create({
|
||||||
|
"case_id": case.id,
|
||||||
|
"name": _("Support Modification (%s)") % filing_date,
|
||||||
|
"proceeding_type": "modification",
|
||||||
|
})
|
||||||
|
rec = self.create({
|
||||||
|
"proceeding_id": proc.id,
|
||||||
|
"current_support_amount": current_amount,
|
||||||
|
"proposed_support_amount": proposed_amount,
|
||||||
|
"is_dor_case": is_dor,
|
||||||
|
"filing_date": filing_date,
|
||||||
|
"retroactivity_date": filing_date,
|
||||||
|
"prior_order_text": prior_order_text or False,
|
||||||
|
})
|
||||||
|
# 20-day answer clock on the supplemental petition.
|
||||||
|
self.env["familylaw.deadline"].create({
|
||||||
|
"proceeding_id": proc.id,
|
||||||
|
"name": _("Answer to Supplemental Petition due"),
|
||||||
|
"deadline_type": "answer",
|
||||||
|
"trigger_date": filing_date,
|
||||||
|
"days": ANSWER_DAYS,
|
||||||
|
})
|
||||||
|
case.message_post(body=_(
|
||||||
|
"New support-modification proceeding opened (filing %s). 20-day answer "
|
||||||
|
"clock set. This is a new proceeding under the same matter.") % filing_date)
|
||||||
|
return rec
|
||||||
|
|
||||||
|
# --- prior-judgment extraction (flagged, not concluded) -----------------
|
||||||
|
def action_extract_prior_judgment(self):
|
||||||
|
"""AI extraction + plain summary + FLAGGED interpretation questions.
|
||||||
|
Never states a legal conclusion. Mocked in tests."""
|
||||||
|
Client = self.env["familylaw.ai.client"]
|
||||||
|
for rec in self:
|
||||||
|
instruction = _(
|
||||||
|
"Extract the key support terms from this order and write a plain-"
|
||||||
|
"language summary. Then LIST interpretation QUESTIONS the attorney "
|
||||||
|
"should resolve. Do NOT answer them or state any legal conclusion.\n\n"
|
||||||
|
"%s"
|
||||||
|
) % (rec.prior_order_text or "")
|
||||||
|
result, task = Client.generate(
|
||||||
|
"extract_judgment", [{"role": "user", "content": instruction}],
|
||||||
|
case=rec.case_id, proceeding=rec.proceeding_id,
|
||||||
|
name=_("Prior-judgment extraction"),
|
||||||
|
)
|
||||||
|
text = result.get("text") or ""
|
||||||
|
rec.extracted_summary = text
|
||||||
|
rec.interpretation_flags = _(
|
||||||
|
"FLAGGED FOR ATTORNEY — these are questions, NOT conclusions or "
|
||||||
|
"rulings. The software does not interpret the order:\n%s"
|
||||||
|
) % text
|
||||||
|
rec.extraction_task_id = task.id
|
||||||
|
rec.message_post(body=_(
|
||||||
|
"Prior judgment extracted and summarized. Interpretation questions "
|
||||||
|
"flagged for the attorney — no conclusion drawn by the software."))
|
||||||
|
return True
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""STEP 9 — Wizard to open a support modification from a case."""
|
||||||
|
|
||||||
|
from odoo import fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class FamilyLawModificationWizard(models.TransientModel):
|
||||||
|
_name = "familylaw.modification.wizard"
|
||||||
|
_description = "Open Support Modification"
|
||||||
|
|
||||||
|
case_id = fields.Many2one("familylaw.case", required=True)
|
||||||
|
current_support_amount = fields.Float(string="Current Monthly Support")
|
||||||
|
proposed_support_amount = fields.Float(string="Proposed Monthly Support")
|
||||||
|
is_dor_case = fields.Boolean(string="DOR / Title IV-D Case")
|
||||||
|
filing_date = fields.Date(default=fields.Date.context_today)
|
||||||
|
prior_order_text = fields.Text(string="Prior Order Text (optional)")
|
||||||
|
|
||||||
|
def action_open(self):
|
||||||
|
self.ensure_one()
|
||||||
|
rec = self.env["familylaw.support.modification"].open_for_case(
|
||||||
|
self.case_id,
|
||||||
|
self.current_support_amount,
|
||||||
|
self.proposed_support_amount,
|
||||||
|
is_dor=self.is_dor_case,
|
||||||
|
filing_date=self.filing_date,
|
||||||
|
prior_order_text=self.prior_order_text or None,
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
"type": "ir.actions.act_window",
|
||||||
|
"res_model": "familylaw.support.modification",
|
||||||
|
"res_id": rec.id,
|
||||||
|
"view_mode": "form",
|
||||||
|
"target": "current",
|
||||||
|
}
|
||||||
@@ -29,3 +29,6 @@ access_familylaw_citation_attorney,familylaw.citation attorney,model_familylaw_c
|
|||||||
access_familylaw_ai_draft_wizard_user,familylaw.ai.draft.wizard user,model_familylaw_ai_draft_wizard,group_familylaw_user,1,1,1,1
|
access_familylaw_ai_draft_wizard_user,familylaw.ai.draft.wizard user,model_familylaw_ai_draft_wizard,group_familylaw_user,1,1,1,1
|
||||||
access_familylaw_discovery_user,familylaw.discovery.request staff,model_familylaw_discovery_request,group_familylaw_user,1,1,1,0
|
access_familylaw_discovery_user,familylaw.discovery.request staff,model_familylaw_discovery_request,group_familylaw_user,1,1,1,0
|
||||||
access_familylaw_discovery_attorney,familylaw.discovery.request attorney,model_familylaw_discovery_request,group_familylaw_attorney,1,1,1,1
|
access_familylaw_discovery_attorney,familylaw.discovery.request attorney,model_familylaw_discovery_request,group_familylaw_attorney,1,1,1,1
|
||||||
|
access_familylaw_modification_user,familylaw.support.modification staff,model_familylaw_support_modification,group_familylaw_user,1,1,1,0
|
||||||
|
access_familylaw_modification_attorney,familylaw.support.modification attorney,model_familylaw_support_modification,group_familylaw_attorney,1,1,1,1
|
||||||
|
access_familylaw_modification_wizard_user,familylaw.modification.wizard user,model_familylaw_modification_wizard,group_familylaw_user,1,1,1,1
|
||||||
|
|||||||
|
@@ -6,3 +6,4 @@ from . import test_step5
|
|||||||
from . import test_step6
|
from . import test_step6
|
||||||
from . import test_step7
|
from . import test_step7
|
||||||
from . import test_step8
|
from . import test_step8
|
||||||
|
from . import test_step9
|
||||||
|
|||||||
@@ -0,0 +1,133 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""STEP 9 tests — child-support modification workflow.
|
||||||
|
|
||||||
|
odoo -d <db> -u activeblue_familylaw --test-enable \
|
||||||
|
--test-tags familylaw_step9 --stop-after-init
|
||||||
|
|
||||||
|
Proves:
|
||||||
|
* a modification opens a NEW proceeding under the same case;
|
||||||
|
* the 15%/$50 substantial-change threshold (max of 15% or $50);
|
||||||
|
* a 20-day answer deadline is created on the new proceeding;
|
||||||
|
* the DOR flag and retroactivity date are captured;
|
||||||
|
* prior-judgment handling produces a summary + FLAGGED interpretation questions,
|
||||||
|
never a conclusion (AI mocked).
|
||||||
|
"""
|
||||||
|
|
||||||
|
from datetime import date
|
||||||
|
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from odoo.tests.common import TransactionCase, tagged
|
||||||
|
|
||||||
|
CLIENT = "odoo.addons.activeblue_familylaw.models.familylaw_ai.FamilyLawAIClient"
|
||||||
|
|
||||||
|
|
||||||
|
def _ai(text="EXTRACTION OUTPUT"):
|
||||||
|
return {"text": text, "usage": {"input_tokens": 5, "output_tokens": 5},
|
||||||
|
"citations": []}
|
||||||
|
|
||||||
|
|
||||||
|
@tagged("post_install", "-at_install", "familylaw", "familylaw_step9")
|
||||||
|
class TestStep9Modification(TransactionCase):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super().setUpClass()
|
||||||
|
cls.partner = cls.env["res.partner"].create({"name": "Mod Client"})
|
||||||
|
cls.case = cls.env["familylaw.case"].create({
|
||||||
|
"name": "Mod Matter", "client_id": cls.partner.id,
|
||||||
|
"case_type": "support_modification",
|
||||||
|
})
|
||||||
|
cls.Mod = cls.env["familylaw.support.modification"]
|
||||||
|
icp = cls.env["ir.config_parameter"].sudo()
|
||||||
|
icp.set_param("familylaw.anthropic_api_key", "k")
|
||||||
|
icp.set_param("familylaw.model", "claude-sonnet-4-6")
|
||||||
|
|
||||||
|
# --- new proceeding -----------------------------------------------------
|
||||||
|
def test_01_opens_new_proceeding(self):
|
||||||
|
before = len(self.case.proceeding_ids)
|
||||||
|
rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0)
|
||||||
|
self.assertEqual(len(self.case.proceeding_ids), before + 1)
|
||||||
|
self.assertEqual(rec.proceeding_id.proceeding_type, "modification")
|
||||||
|
self.assertEqual(rec.case_id, self.case)
|
||||||
|
|
||||||
|
def test_02_separate_from_original_proceeding(self):
|
||||||
|
original = self.case.proceeding_ids[0]
|
||||||
|
rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0)
|
||||||
|
self.assertNotEqual(rec.proceeding_id, original)
|
||||||
|
|
||||||
|
# --- threshold ----------------------------------------------------------
|
||||||
|
def test_03_meets_threshold_15pct(self):
|
||||||
|
rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0) # +200 vs thr 150
|
||||||
|
self.assertTrue(rec.meets_threshold)
|
||||||
|
|
||||||
|
def test_04_below_threshold(self):
|
||||||
|
rec = self.Mod.open_for_case(self.case, 1000.0, 1100.0) # +100 vs thr 150
|
||||||
|
self.assertFalse(rec.meets_threshold)
|
||||||
|
|
||||||
|
def test_05_fifty_dollar_prong(self):
|
||||||
|
# low base: 15% of 200 = 30, but $50 floor applies; +60 meets
|
||||||
|
rec = self.Mod.open_for_case(self.case, 200.0, 260.0)
|
||||||
|
self.assertEqual(rec.threshold_amount, 50.0)
|
||||||
|
self.assertTrue(rec.meets_threshold)
|
||||||
|
|
||||||
|
def test_06_fifty_dollar_prong_not_met(self):
|
||||||
|
rec = self.Mod.open_for_case(self.case, 200.0, 240.0) # +40 < $50
|
||||||
|
self.assertFalse(rec.meets_threshold)
|
||||||
|
|
||||||
|
def test_07_change_pct(self):
|
||||||
|
rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0)
|
||||||
|
self.assertAlmostEqual(rec.change_pct, 20.0, places=2)
|
||||||
|
|
||||||
|
def test_08_no_change_not_met(self):
|
||||||
|
rec = self.Mod.open_for_case(self.case, 1000.0, 1000.0)
|
||||||
|
self.assertFalse(rec.meets_threshold)
|
||||||
|
|
||||||
|
# --- 20-day answer deadline ---------------------------------------------
|
||||||
|
def test_09_answer_deadline_created(self):
|
||||||
|
rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0,
|
||||||
|
filing_date=date(2025, 1, 1))
|
||||||
|
answer = rec.proceeding_id.deadline_ids.filtered(
|
||||||
|
lambda d: d.deadline_type == "answer")
|
||||||
|
self.assertTrue(answer)
|
||||||
|
self.assertEqual(answer.days, 20)
|
||||||
|
# 2025-01-01 + 20 = 2025-01-21 (Tue)
|
||||||
|
self.assertEqual(answer.due_date, date(2025, 1, 21))
|
||||||
|
|
||||||
|
# --- DOR + retroactivity ------------------------------------------------
|
||||||
|
def test_10_dor_flag(self):
|
||||||
|
rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0, is_dor=True)
|
||||||
|
self.assertTrue(rec.is_dor_case)
|
||||||
|
|
||||||
|
def test_11_retroactivity_date_is_filing_date(self):
|
||||||
|
rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0,
|
||||||
|
filing_date=date(2025, 3, 5))
|
||||||
|
self.assertEqual(rec.retroactivity_date, date(2025, 3, 5))
|
||||||
|
|
||||||
|
# --- prior-judgment extraction (flagged, not concluded) -----------------
|
||||||
|
def test_12_extraction_summarizes_and_flags(self):
|
||||||
|
rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0,
|
||||||
|
prior_order_text="Order: $1000/mo to Mother.")
|
||||||
|
with patch(CLIENT + "._call_provider", return_value=_ai("SUMMARY TEXT")):
|
||||||
|
rec.action_extract_prior_judgment()
|
||||||
|
self.assertIn("SUMMARY TEXT", rec.extracted_summary)
|
||||||
|
self.assertTrue(rec.interpretation_flags)
|
||||||
|
|
||||||
|
def test_13_interpretation_is_flagged_not_concluded(self):
|
||||||
|
rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0,
|
||||||
|
prior_order_text="Order text.")
|
||||||
|
with patch(CLIENT + "._call_provider", return_value=_ai()):
|
||||||
|
rec.action_extract_prior_judgment()
|
||||||
|
# the interpretation field carries the not-a-conclusion disclaimer
|
||||||
|
self.assertIn("NOT conclusions", rec.interpretation_flags)
|
||||||
|
# the model structurally has no field that states a legal conclusion/ruling
|
||||||
|
self.assertNotIn("legal_conclusion", rec._fields)
|
||||||
|
self.assertNotIn("ruling", rec._fields)
|
||||||
|
|
||||||
|
def test_14_extraction_logs_ai_task(self):
|
||||||
|
rec = self.Mod.open_for_case(self.case, 1000.0, 1200.0,
|
||||||
|
prior_order_text="Order text.")
|
||||||
|
with patch(CLIENT + "._call_provider", return_value=_ai()):
|
||||||
|
rec.action_extract_prior_judgment()
|
||||||
|
self.assertTrue(rec.extraction_task_id)
|
||||||
|
self.assertEqual(rec.extraction_task_id.state, "done")
|
||||||
@@ -50,6 +50,11 @@
|
|||||||
string="Start Mediation" invisible="state != 'discovery'"/>
|
string="Start Mediation" invisible="state != 'discovery'"/>
|
||||||
<button name="action_set_hearing" type="object"
|
<button name="action_set_hearing" type="object"
|
||||||
string="Set for Hearing" invisible="state != 'mediation'"/>
|
string="Set for Hearing" invisible="state != 'mediation'"/>
|
||||||
|
<!-- Open a support modification (new proceeding) -->
|
||||||
|
<button name="%(action_familylaw_modification_wizard)d" type="action"
|
||||||
|
string="Open Support Modification"
|
||||||
|
context="{'default_case_id': id}"
|
||||||
|
invisible="case_type != 'support_modification'"/>
|
||||||
<!-- Attorney-only: close / reopen -->
|
<!-- Attorney-only: close / reopen -->
|
||||||
<button name="action_close" type="object" string="Close Case"
|
<button name="action_close" type="object" string="Close Case"
|
||||||
invisible="state == 'closed'"
|
invisible="state == 'closed'"
|
||||||
|
|||||||
@@ -41,6 +41,13 @@
|
|||||||
action="action_familylaw_affidavit"
|
action="action_familylaw_affidavit"
|
||||||
sequence="40"/>
|
sequence="40"/>
|
||||||
|
|
||||||
|
<!-- Support Modifications -->
|
||||||
|
<menuitem id="menu_familylaw_modifications"
|
||||||
|
name="Support Modifications"
|
||||||
|
parent="menu_familylaw_root"
|
||||||
|
action="action_familylaw_modification"
|
||||||
|
sequence="44"/>
|
||||||
|
|
||||||
<!-- Discovery -->
|
<!-- Discovery -->
|
||||||
<menuitem id="menu_familylaw_discovery"
|
<menuitem id="menu_familylaw_discovery"
|
||||||
name="Discovery"
|
name="Discovery"
|
||||||
|
|||||||
@@ -0,0 +1,122 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<record id="view_familylaw_modification_list" model="ir.ui.view">
|
||||||
|
<field name="name">familylaw.support.modification.list</field>
|
||||||
|
<field name="model">familylaw.support.modification</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list string="Support Modifications">
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="case_id"/>
|
||||||
|
<field name="current_support_amount"/>
|
||||||
|
<field name="proposed_support_amount"/>
|
||||||
|
<field name="change_pct"/>
|
||||||
|
<field name="meets_threshold" widget="boolean_toggle"/>
|
||||||
|
<field name="is_dor_case"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_familylaw_modification_form" model="ir.ui.view">
|
||||||
|
<field name="name">familylaw.support.modification.form</field>
|
||||||
|
<field name="model">familylaw.support.modification</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Support Modification">
|
||||||
|
<header>
|
||||||
|
<button name="action_extract_prior_judgment" type="object"
|
||||||
|
string="Extract Prior Judgment"
|
||||||
|
invisible="not prior_order_text"/>
|
||||||
|
</header>
|
||||||
|
<sheet>
|
||||||
|
<div class="alert alert-info" role="alert">
|
||||||
|
The 15%/$50 check is a deterministic PRESUMPTION test only.
|
||||||
|
Whether the court grants the modification is the attorney's
|
||||||
|
and the court's judgment — the software does not predict it.
|
||||||
|
</div>
|
||||||
|
<div class="oe_title">
|
||||||
|
<label for="name"/>
|
||||||
|
<h1><field name="name"/></h1>
|
||||||
|
</div>
|
||||||
|
<group>
|
||||||
|
<group string="Support Amounts">
|
||||||
|
<field name="current_support_amount"/>
|
||||||
|
<field name="proposed_support_amount"/>
|
||||||
|
<field name="change_amount" readonly="1"/>
|
||||||
|
<field name="change_pct" readonly="1"/>
|
||||||
|
<field name="threshold_amount" readonly="1"/>
|
||||||
|
<field name="meets_threshold" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
<group string="Matter / Timing">
|
||||||
|
<field name="proceeding_id"/>
|
||||||
|
<field name="case_id" readonly="1"/>
|
||||||
|
<field name="is_dor_case"/>
|
||||||
|
<field name="filing_date"/>
|
||||||
|
<field name="retroactivity_date"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<group string="Retroactivity">
|
||||||
|
<field name="retroactivity_note" nolabel="1" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
<notebook>
|
||||||
|
<page string="Prior Judgment" name="prior">
|
||||||
|
<field name="prior_order_text"
|
||||||
|
placeholder="Paste the prior order text to extract + summarize."/>
|
||||||
|
<separator string="Plain-Language Summary (AI draft)"/>
|
||||||
|
<field name="extracted_summary" readonly="1"/>
|
||||||
|
<separator string="Interpretation Questions — FOR ATTORNEY (not conclusions)"/>
|
||||||
|
<field name="interpretation_flags" readonly="1"/>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
<div class="oe_chatter">
|
||||||
|
<field name="message_follower_ids"/>
|
||||||
|
<field name="activity_ids"/>
|
||||||
|
<field name="message_ids"/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="action_familylaw_modification" model="ir.actions.act_window">
|
||||||
|
<field name="name">Support Modifications</field>
|
||||||
|
<field name="res_model">familylaw.support.modification</field>
|
||||||
|
<field name="view_mode">list,form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- Wizard -->
|
||||||
|
<record id="view_familylaw_modification_wizard_form" model="ir.ui.view">
|
||||||
|
<field name="name">familylaw.modification.wizard.form</field>
|
||||||
|
<field name="model">familylaw.modification.wizard</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Open Support Modification">
|
||||||
|
<sheet>
|
||||||
|
<div class="alert alert-info" role="alert">
|
||||||
|
Opens a NEW proceeding under this matter and sets the 20-day
|
||||||
|
answer clock. Captures facts only.
|
||||||
|
</div>
|
||||||
|
<group>
|
||||||
|
<field name="case_id"/>
|
||||||
|
<field name="current_support_amount"/>
|
||||||
|
<field name="proposed_support_amount"/>
|
||||||
|
<field name="is_dor_case"/>
|
||||||
|
<field name="filing_date"/>
|
||||||
|
<field name="prior_order_text"/>
|
||||||
|
</group>
|
||||||
|
</sheet>
|
||||||
|
<footer>
|
||||||
|
<button name="action_open" type="object"
|
||||||
|
string="Open Modification" class="btn-primary"/>
|
||||||
|
<button string="Cancel" special="cancel"/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="action_familylaw_modification_wizard" model="ir.actions.act_window">
|
||||||
|
<field name="name">Open Support Modification</field>
|
||||||
|
<field name="res_model">familylaw.modification.wizard</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="target">new</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
Reference in New Issue
Block a user