Step 8: discovery + Rule 12.351 subpoena (objection-window gate + pro-se/attorney routing)
familylaw.discovery.request (per proceeding): - discovery_type incl. nonparty_production (Rule 12.351) - HARD objection-window gate: a non-party subpoena cannot issue before notice is served + the 10-day objection window elapses, or while an objection is pending (_ensure_objection_window_elapsed). Party discovery is not gated. - issuance_route computed from representation: attorney issues directly, pro se via the clerk (Forms & Playbook Part C) - on issue: Notice of Issuance served the SAME DAY; response due +30 days - objection_deadline (+10, weekend roll) and response_due (+30, roll) computed - VERIFY note: Rule 12.410 subpoena amendment eff. Oct 1 2025 Proceeding gets a Discovery tab; discovery views + menu + ACL. Tests (familylaw_step8, fixed dates): cannot issue before notice / before window / with pending objection; can issue after window; 10-day deadline math with weekend roll; same-day notice of issuance; attorney vs clerk routing; party production not gated; serve-notice transition; proceeding linkage. 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.7.0.0",
|
"version": "18.0.8.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": """
|
||||||
@@ -34,6 +34,7 @@ Each step adds one vertical, independently testable slice. See BUILD_PLAN.md.
|
|||||||
"views/familylaw_deadline_views.xml",
|
"views/familylaw_deadline_views.xml",
|
||||||
"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_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",
|
||||||
|
|||||||
@@ -12,4 +12,5 @@ from . import familylaw_ai
|
|||||||
from . import familylaw_citation
|
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_ai_wizard
|
from . import familylaw_ai_wizard
|
||||||
|
|||||||
@@ -0,0 +1,204 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""STEP 8 — Discovery + subpoena (Rule 12.351 objection-window gate + routing).
|
||||||
|
|
||||||
|
A discovery request hangs off a PROCEEDING. The headline safety feature is the
|
||||||
|
NON-PARTY PRODUCTION (Rule 12.351) objection-window gate:
|
||||||
|
|
||||||
|
Before a Rule 12.351 subpoena for production from a non-party may be ISSUED, the
|
||||||
|
requesting party must serve notice on the other parties and wait out the objection
|
||||||
|
window (10 days). The subpoena CANNOT be issued until that window has elapsed AND
|
||||||
|
no objection is pending. This is a HARD gate, enforced in code.
|
||||||
|
|
||||||
|
Issuance ROUTING depends on representation (Forms & Playbook, Part C):
|
||||||
|
* attorney of record -> issues directly (officer of the court)
|
||||||
|
* pro se -> the CLERK issues the subpoena
|
||||||
|
On issuance, a Notice of Issuance must be served the SAME DAY.
|
||||||
|
|
||||||
|
VERIFY current rule — Rule 12.410 (subpoenas) was amended effective Oct 1 2025;
|
||||||
|
confirm the objection window and notice mechanics before relying in production.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from odoo import api, fields, models, _
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
|
||||||
|
OBJECTION_DAYS = 10 # Rule 12.351 notice/objection window — VERIFY
|
||||||
|
RESPONSE_DAYS = 30 # typical production response window — VERIFY
|
||||||
|
|
||||||
|
|
||||||
|
def _roll(due):
|
||||||
|
while due.weekday() >= 5:
|
||||||
|
due += timedelta(days=1)
|
||||||
|
return due
|
||||||
|
|
||||||
|
|
||||||
|
class FamilyLawDiscoveryRequest(models.Model):
|
||||||
|
_name = "familylaw.discovery.request"
|
||||||
|
_description = "Discovery Request / Subpoena"
|
||||||
|
_inherit = ["mail.thread"]
|
||||||
|
_order = "create_date desc"
|
||||||
|
|
||||||
|
name = fields.Char(required=True, 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,
|
||||||
|
)
|
||||||
|
representation = fields.Selection(
|
||||||
|
related="case_id.representation", store=True, string="Representation",
|
||||||
|
)
|
||||||
|
discovery_type = fields.Selection(
|
||||||
|
selection=[
|
||||||
|
("interrogatories", "Interrogatories"),
|
||||||
|
("production", "Request for Production (party)"),
|
||||||
|
("admissions", "Requests for Admission"),
|
||||||
|
("nonparty_production", "Non-Party Production — Rule 12.351"),
|
||||||
|
("deposition", "Deposition"),
|
||||||
|
],
|
||||||
|
string="Type",
|
||||||
|
required=True,
|
||||||
|
default="production",
|
||||||
|
tracking=True,
|
||||||
|
)
|
||||||
|
is_nonparty = fields.Boolean(compute="_compute_is_nonparty", store=True)
|
||||||
|
nonparty_name = fields.Char(string="Non-Party (subpoena target)")
|
||||||
|
|
||||||
|
issuance_route = fields.Selection(
|
||||||
|
selection=[
|
||||||
|
("attorney_direct", "Attorney issues directly"),
|
||||||
|
("clerk", "Clerk issues (pro se)"),
|
||||||
|
],
|
||||||
|
compute="_compute_issuance_route",
|
||||||
|
store=True,
|
||||||
|
string="Issuance Route",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Rule 12.351 objection window
|
||||||
|
notice_served_date = fields.Date(
|
||||||
|
string="Notice to Parties Served",
|
||||||
|
tracking=True,
|
||||||
|
help="Starts the Rule 12.351 objection window.",
|
||||||
|
)
|
||||||
|
objection_deadline = fields.Date(
|
||||||
|
compute="_compute_objection_deadline", store=True,
|
||||||
|
)
|
||||||
|
objection_received = fields.Boolean(string="Objection Received", tracking=True)
|
||||||
|
objection_note = fields.Text()
|
||||||
|
|
||||||
|
state = fields.Selection(
|
||||||
|
selection=[
|
||||||
|
("draft", "Draft"),
|
||||||
|
("notice_served", "Notice Served"),
|
||||||
|
("issued", "Issued"),
|
||||||
|
("responded", "Responded"),
|
||||||
|
("objected", "Objected"),
|
||||||
|
],
|
||||||
|
default="draft",
|
||||||
|
required=True,
|
||||||
|
tracking=True,
|
||||||
|
)
|
||||||
|
issuance_date = fields.Date(string="Issued On", readonly=True, copy=False)
|
||||||
|
notice_of_issuance_date = fields.Date(
|
||||||
|
string="Notice of Issuance Served", readonly=True, copy=False,
|
||||||
|
help="Must be served the same day the subpoena issues.",
|
||||||
|
)
|
||||||
|
response_due_date = fields.Date(compute="_compute_response_due", store=True)
|
||||||
|
|
||||||
|
@api.depends("discovery_type")
|
||||||
|
def _compute_is_nonparty(self):
|
||||||
|
for r in self:
|
||||||
|
r.is_nonparty = r.discovery_type == "nonparty_production"
|
||||||
|
|
||||||
|
@api.depends("representation")
|
||||||
|
def _compute_issuance_route(self):
|
||||||
|
for r in self:
|
||||||
|
r.issuance_route = (
|
||||||
|
"attorney_direct" if r.representation == "attorney" else "clerk"
|
||||||
|
)
|
||||||
|
|
||||||
|
@api.depends("notice_served_date")
|
||||||
|
def _compute_objection_deadline(self):
|
||||||
|
for r in self:
|
||||||
|
if r.notice_served_date:
|
||||||
|
r.objection_deadline = _roll(
|
||||||
|
r.notice_served_date + timedelta(days=OBJECTION_DAYS)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
r.objection_deadline = False
|
||||||
|
|
||||||
|
@api.depends("issuance_date")
|
||||||
|
def _compute_response_due(self):
|
||||||
|
for r in self:
|
||||||
|
if r.issuance_date:
|
||||||
|
r.response_due_date = _roll(
|
||||||
|
r.issuance_date + timedelta(days=RESPONSE_DAYS)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
r.response_due_date = False
|
||||||
|
|
||||||
|
# --- workflow -----------------------------------------------------------
|
||||||
|
def action_serve_notice(self):
|
||||||
|
for r in self:
|
||||||
|
if not r.notice_served_date:
|
||||||
|
r.notice_served_date = fields.Date.context_today(r)
|
||||||
|
r.state = "notice_served"
|
||||||
|
r.message_post(body=_("Notice to other parties served (Rule 12.351). "
|
||||||
|
"Objection window runs to %s.") % r.objection_deadline)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _ensure_objection_window_elapsed(self):
|
||||||
|
"""HARD gate for Rule 12.351 non-party subpoenas."""
|
||||||
|
today = fields.Date.context_today(self)
|
||||||
|
for r in self:
|
||||||
|
if not r.is_nonparty:
|
||||||
|
continue
|
||||||
|
if not r.notice_served_date:
|
||||||
|
raise UserError(
|
||||||
|
_("Cannot issue a Rule 12.351 non-party subpoena before serving "
|
||||||
|
"notice on the other parties and running the objection window.")
|
||||||
|
)
|
||||||
|
if r.objection_received:
|
||||||
|
raise UserError(
|
||||||
|
_("An objection is pending on '%s'. The subpoena cannot be issued "
|
||||||
|
"until the objection is resolved by the court.") % r.name
|
||||||
|
)
|
||||||
|
if not r.objection_deadline or today < r.objection_deadline:
|
||||||
|
raise UserError(
|
||||||
|
_("The Rule 12.351 objection window has not elapsed (runs to %s). "
|
||||||
|
"The non-party subpoena cannot be issued yet.")
|
||||||
|
% r.objection_deadline
|
||||||
|
)
|
||||||
|
|
||||||
|
def action_record_objection(self):
|
||||||
|
for r in self:
|
||||||
|
r.objection_received = True
|
||||||
|
r.state = "objected"
|
||||||
|
r.message_post(body=_("Objection recorded — issuance blocked pending "
|
||||||
|
"court resolution."))
|
||||||
|
return True
|
||||||
|
|
||||||
|
def action_issue(self):
|
||||||
|
"""Issue the subpoena/request. Enforces the 12.351 objection gate for
|
||||||
|
non-party production and serves the Notice of Issuance the SAME DAY."""
|
||||||
|
self._ensure_objection_window_elapsed()
|
||||||
|
today = fields.Date.context_today(self)
|
||||||
|
for r in self:
|
||||||
|
r.write({
|
||||||
|
"state": "issued",
|
||||||
|
"issuance_date": today,
|
||||||
|
"notice_of_issuance_date": today, # same-day requirement
|
||||||
|
})
|
||||||
|
route = dict(r._fields["issuance_route"].selection).get(r.issuance_route)
|
||||||
|
r.message_post(body=_("Issued (%(route)s). Notice of Issuance served "
|
||||||
|
"same day. Response due %(due)s.",
|
||||||
|
route=route, due=r.response_due_date))
|
||||||
|
return True
|
||||||
|
|
||||||
|
def action_mark_responded(self):
|
||||||
|
for r in self:
|
||||||
|
r.state = "responded"
|
||||||
|
r.message_post(body=_("Response received."))
|
||||||
|
return True
|
||||||
@@ -66,6 +66,9 @@ class FamilyLawProceeding(models.Model):
|
|||||||
affidavit_ids = fields.One2many(
|
affidavit_ids = fields.One2many(
|
||||||
"familylaw.financial.affidavit", "proceeding_id", string="Financial Affidavits",
|
"familylaw.financial.affidavit", "proceeding_id", string="Financial Affidavits",
|
||||||
)
|
)
|
||||||
|
discovery_ids = fields.One2many(
|
||||||
|
"familylaw.discovery.request", "proceeding_id", string="Discovery",
|
||||||
|
)
|
||||||
|
|
||||||
def action_seed_disclosure_items(self):
|
def action_seed_disclosure_items(self):
|
||||||
"""Seed the standard Rule 12.285 mandatory disclosure checklist.
|
"""Seed the standard Rule 12.285 mandatory disclosure checklist.
|
||||||
|
|||||||
@@ -27,3 +27,5 @@ access_familylaw_ai_task_attorney,familylaw.ai.task attorney,model_familylaw_ai_
|
|||||||
access_familylaw_citation_user,familylaw.citation staff,model_familylaw_citation,group_familylaw_user,1,1,1,0
|
access_familylaw_citation_user,familylaw.citation staff,model_familylaw_citation,group_familylaw_user,1,1,1,0
|
||||||
access_familylaw_citation_attorney,familylaw.citation attorney,model_familylaw_citation,group_familylaw_attorney,1,1,1,1
|
access_familylaw_citation_attorney,familylaw.citation attorney,model_familylaw_citation,group_familylaw_attorney,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_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_attorney,familylaw.discovery.request attorney,model_familylaw_discovery_request,group_familylaw_attorney,1,1,1,1
|
||||||
|
|||||||
|
@@ -5,3 +5,4 @@ from . import test_step4
|
|||||||
from . import test_step5
|
from . import test_step5
|
||||||
from . import test_step6
|
from . import test_step6
|
||||||
from . import test_step7
|
from . import test_step7
|
||||||
|
from . import test_step8
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""STEP 8 tests — discovery + Rule 12.351 subpoena (objection-window gate + routing).
|
||||||
|
|
||||||
|
odoo -d <db> -u activeblue_familylaw --test-enable \
|
||||||
|
--test-tags familylaw_step8 --stop-after-init
|
||||||
|
|
||||||
|
Objection-window math uses FIXED notice dates safely in the past/future. Proves:
|
||||||
|
* a non-party subpoena cannot issue before the objection window elapses;
|
||||||
|
* it cannot issue while an objection is pending;
|
||||||
|
* it can issue once the window has elapsed with no objection;
|
||||||
|
* issuance serves the Notice of Issuance the SAME DAY;
|
||||||
|
* issuance routing follows representation (attorney direct vs clerk);
|
||||||
|
* party discovery (non-12.351) is not blocked by the window.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from datetime import date
|
||||||
|
|
||||||
|
from odoo.tests.common import TransactionCase, tagged
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
|
||||||
|
|
||||||
|
@tagged("post_install", "-at_install", "familylaw", "familylaw_step8")
|
||||||
|
class TestStep8Discovery(TransactionCase):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super().setUpClass()
|
||||||
|
cls.partner = cls.env["res.partner"].create({"name": "Disc8 Client"})
|
||||||
|
cls.case = cls.env["familylaw.case"].create({
|
||||||
|
"name": "Discovery Matter", "client_id": cls.partner.id,
|
||||||
|
"case_type": "support_modification", "representation": "attorney",
|
||||||
|
})
|
||||||
|
cls.proc = cls.case.proceeding_ids[0]
|
||||||
|
cls.case_prose = cls.env["familylaw.case"].create({
|
||||||
|
"name": "Pro Se Matter", "client_id": cls.partner.id,
|
||||||
|
"case_type": "support_modification", "representation": "pro_se",
|
||||||
|
})
|
||||||
|
cls.proc_prose = cls.case_prose.proceeding_ids[0]
|
||||||
|
cls.Req = cls.env["familylaw.discovery.request"]
|
||||||
|
|
||||||
|
def _nonparty(self, proc=None, **kw):
|
||||||
|
vals = {
|
||||||
|
"name": "Subpoena to Employer",
|
||||||
|
"proceeding_id": (proc or self.proc).id,
|
||||||
|
"discovery_type": "nonparty_production",
|
||||||
|
"nonparty_name": "Acme Corp",
|
||||||
|
}
|
||||||
|
vals.update(kw)
|
||||||
|
return self.Req.create(vals)
|
||||||
|
|
||||||
|
# --- objection window gate ----------------------------------------------
|
||||||
|
def test_01_cannot_issue_before_notice(self):
|
||||||
|
req = self._nonparty()
|
||||||
|
with self.assertRaises(UserError):
|
||||||
|
req.action_issue()
|
||||||
|
|
||||||
|
def test_02_cannot_issue_before_window_elapses(self):
|
||||||
|
# notice served in the future -> window not elapsed
|
||||||
|
req = self._nonparty(notice_served_date=date(2999, 1, 1),
|
||||||
|
state="notice_served")
|
||||||
|
with self.assertRaises(UserError):
|
||||||
|
req.action_issue()
|
||||||
|
self.assertNotEqual(req.state, "issued")
|
||||||
|
|
||||||
|
def test_03_can_issue_after_window(self):
|
||||||
|
req = self._nonparty(notice_served_date=date(2000, 1, 1),
|
||||||
|
state="notice_served")
|
||||||
|
req.action_issue()
|
||||||
|
self.assertEqual(req.state, "issued")
|
||||||
|
|
||||||
|
def test_04_pending_objection_blocks_issue(self):
|
||||||
|
req = self._nonparty(notice_served_date=date(2000, 1, 1),
|
||||||
|
state="notice_served")
|
||||||
|
req.action_record_objection()
|
||||||
|
self.assertEqual(req.state, "objected")
|
||||||
|
with self.assertRaises(UserError):
|
||||||
|
req.action_issue()
|
||||||
|
|
||||||
|
# --- objection deadline math --------------------------------------------
|
||||||
|
def test_05_objection_deadline_10_days(self):
|
||||||
|
# 2025-01-01 (Wed) + 10 = 2025-01-11 (Sat) -> 2025-01-13 (Mon)
|
||||||
|
req = self._nonparty(notice_served_date=date(2025, 1, 1))
|
||||||
|
self.assertEqual(req.objection_deadline, date(2025, 1, 13))
|
||||||
|
|
||||||
|
# --- same-day notice of issuance ----------------------------------------
|
||||||
|
def test_06_notice_of_issuance_same_day(self):
|
||||||
|
req = self._nonparty(notice_served_date=date(2000, 1, 1),
|
||||||
|
state="notice_served")
|
||||||
|
req.action_issue()
|
||||||
|
self.assertTrue(req.issuance_date)
|
||||||
|
self.assertEqual(req.notice_of_issuance_date, req.issuance_date)
|
||||||
|
|
||||||
|
def test_07_response_due_30_days(self):
|
||||||
|
req = self._nonparty(notice_served_date=date(2000, 1, 1),
|
||||||
|
state="notice_served")
|
||||||
|
req.action_issue()
|
||||||
|
self.assertTrue(req.response_due_date)
|
||||||
|
|
||||||
|
# --- routing ------------------------------------------------------------
|
||||||
|
def test_08_attorney_route(self):
|
||||||
|
req = self._nonparty()
|
||||||
|
self.assertEqual(req.issuance_route, "attorney_direct")
|
||||||
|
|
||||||
|
def test_09_prose_route_clerk(self):
|
||||||
|
req = self._nonparty(proc=self.proc_prose)
|
||||||
|
self.assertEqual(req.issuance_route, "clerk")
|
||||||
|
|
||||||
|
# --- party discovery is not gated by 12.351 -----------------------------
|
||||||
|
def test_10_party_production_issues_freely(self):
|
||||||
|
req = self.Req.create({
|
||||||
|
"name": "RFP to opposing party",
|
||||||
|
"proceeding_id": self.proc.id,
|
||||||
|
"discovery_type": "production",
|
||||||
|
})
|
||||||
|
req.action_issue() # no window required
|
||||||
|
self.assertEqual(req.state, "issued")
|
||||||
|
|
||||||
|
# --- serve notice sets date + state -------------------------------------
|
||||||
|
def test_11_serve_notice(self):
|
||||||
|
req = self._nonparty()
|
||||||
|
req.action_serve_notice()
|
||||||
|
self.assertEqual(req.state, "notice_served")
|
||||||
|
self.assertTrue(req.notice_served_date)
|
||||||
|
self.assertTrue(req.objection_deadline)
|
||||||
|
|
||||||
|
# --- isolation ----------------------------------------------------------
|
||||||
|
def test_12_discovery_listed_on_proceeding(self):
|
||||||
|
req = self._nonparty()
|
||||||
|
self.assertIn(req, self.proc.discovery_ids)
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<record id="view_familylaw_discovery_list" model="ir.ui.view">
|
||||||
|
<field name="name">familylaw.discovery.request.list</field>
|
||||||
|
<field name="model">familylaw.discovery.request</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list string="Discovery">
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="case_id"/>
|
||||||
|
<field name="discovery_type"/>
|
||||||
|
<field name="issuance_route"/>
|
||||||
|
<field name="objection_deadline"/>
|
||||||
|
<field name="response_due_date"/>
|
||||||
|
<field name="state" widget="badge"
|
||||||
|
decoration-success="state == 'responded'"
|
||||||
|
decoration-danger="state == 'objected'"
|
||||||
|
decoration-info="state in ('draft','notice_served')"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_familylaw_discovery_form" model="ir.ui.view">
|
||||||
|
<field name="name">familylaw.discovery.request.form</field>
|
||||||
|
<field name="model">familylaw.discovery.request</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Discovery Request">
|
||||||
|
<header>
|
||||||
|
<button name="action_serve_notice" type="object"
|
||||||
|
string="Serve Notice (12.351)" class="btn-primary"
|
||||||
|
invisible="not is_nonparty or state not in ('draft',)"/>
|
||||||
|
<button name="action_record_objection" type="object"
|
||||||
|
string="Record Objection"
|
||||||
|
invisible="state not in ('notice_served',)"/>
|
||||||
|
<button name="action_issue" type="object"
|
||||||
|
string="Issue" class="btn-primary"
|
||||||
|
invisible="state in ('issued','responded','objected')"/>
|
||||||
|
<button name="action_mark_responded" type="object"
|
||||||
|
string="Mark Responded"
|
||||||
|
invisible="state != 'issued'"/>
|
||||||
|
<field name="state" widget="statusbar"
|
||||||
|
statusbar_visible="draft,notice_served,issued,responded"/>
|
||||||
|
</header>
|
||||||
|
<sheet>
|
||||||
|
<div class="alert alert-warning" role="alert"
|
||||||
|
invisible="not is_nonparty or state != 'notice_served'">
|
||||||
|
Rule 12.351 objection window runs to
|
||||||
|
<field name="objection_deadline" readonly="1" nolabel="1"/>.
|
||||||
|
The non-party subpoena cannot be issued before then, or while
|
||||||
|
an objection is pending.
|
||||||
|
</div>
|
||||||
|
<div class="oe_title">
|
||||||
|
<label for="name"/>
|
||||||
|
<h1><field name="name" placeholder="e.g. Subpoena to Employer for payroll records"/></h1>
|
||||||
|
</div>
|
||||||
|
<group>
|
||||||
|
<group string="Request">
|
||||||
|
<field name="discovery_type"/>
|
||||||
|
<field name="is_nonparty" invisible="1"/>
|
||||||
|
<field name="nonparty_name" invisible="not is_nonparty"/>
|
||||||
|
<field name="proceeding_id"/>
|
||||||
|
<field name="case_id" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
<group string="Routing & Timing">
|
||||||
|
<field name="representation" readonly="1"/>
|
||||||
|
<field name="issuance_route" readonly="1"/>
|
||||||
|
<field name="notice_served_date"/>
|
||||||
|
<field name="objection_deadline" readonly="1"/>
|
||||||
|
<field name="issuance_date" readonly="1"/>
|
||||||
|
<field name="notice_of_issuance_date" readonly="1"/>
|
||||||
|
<field name="response_due_date" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<group string="Objection">
|
||||||
|
<field name="objection_received"/>
|
||||||
|
<field name="objection_note"/>
|
||||||
|
</group>
|
||||||
|
</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_discovery" model="ir.actions.act_window">
|
||||||
|
<field name="name">Discovery</field>
|
||||||
|
<field name="res_model">familylaw.discovery.request</field>
|
||||||
|
<field name="view_mode">list,form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
@@ -41,6 +41,13 @@
|
|||||||
action="action_familylaw_affidavit"
|
action="action_familylaw_affidavit"
|
||||||
sequence="40"/>
|
sequence="40"/>
|
||||||
|
|
||||||
|
<!-- Discovery -->
|
||||||
|
<menuitem id="menu_familylaw_discovery"
|
||||||
|
name="Discovery"
|
||||||
|
parent="menu_familylaw_root"
|
||||||
|
action="action_familylaw_discovery"
|
||||||
|
sequence="45"/>
|
||||||
|
|
||||||
<!-- Citations -->
|
<!-- Citations -->
|
||||||
<menuitem id="menu_familylaw_citations"
|
<menuitem id="menu_familylaw_citations"
|
||||||
name="Citations"
|
name="Citations"
|
||||||
|
|||||||
@@ -112,6 +112,18 @@
|
|||||||
</list>
|
</list>
|
||||||
</field>
|
</field>
|
||||||
</page>
|
</page>
|
||||||
|
<page string="Discovery" name="discovery">
|
||||||
|
<field name="discovery_ids"
|
||||||
|
context="{'default_proceeding_id': id}">
|
||||||
|
<list>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="discovery_type"/>
|
||||||
|
<field name="issuance_route"/>
|
||||||
|
<field name="objection_deadline"/>
|
||||||
|
<field name="state" widget="badge"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</page>
|
||||||
</notebook>
|
</notebook>
|
||||||
</sheet>
|
</sheet>
|
||||||
<div class="oe_chatter">
|
<div class="oe_chatter">
|
||||||
|
|||||||
Reference in New Issue
Block a user