refactor(jobs): address code review feedback on fp.job.step (Task 1.6)
- I1: Replace 'Task 1.6' markers in stub method comments and
NotImplementedError messages with forward-looking phrasing.
Task 1.6 is what just shipped (the field expansion); the action
stubs are deferred to an unspecified future task. Stale markers
would have confused future readers/operators.
- I2: Add test_cost_total_recomputes_when_rate_changes — insurance
test that verifies @api.depends('cost_per_hour') triggers through
the related-from-work_centre chain. Catches future Odoo upgrades
that break related-depends.
Manifest 19.0.8.5.0 → 19.0.8.5.1.
Part of: native job model migration (spec 2026-04-25)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
'name': 'Fusion Plating',
|
'name': 'Fusion Plating',
|
||||||
'version': '19.0.8.5.0',
|
'version': '19.0.8.5.1',
|
||||||
'category': 'Manufacturing/Plating',
|
'category': 'Manufacturing/Plating',
|
||||||
'summary': 'Core plating / metal finishing ERP: facilities, processes, tanks, baths, jobs, operators.',
|
'summary': 'Core plating / metal finishing ERP: facilities, processes, tanks, baths, jobs, operators.',
|
||||||
'description': """
|
'description': """
|
||||||
|
|||||||
@@ -158,31 +158,31 @@ class FpJobStep(models.Model):
|
|||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# Implemented: button_start (ready/paused → in_progress),
|
# Implemented: button_start (ready/paused → in_progress),
|
||||||
# button_finish (in_progress → done).
|
# button_finish (in_progress → done).
|
||||||
# Stubs (raise NotImplementedError for Task 1.6):
|
# Stubs (raise NotImplementedError; wiring deferred):
|
||||||
# button_pause (in_progress → paused)
|
# button_pause (in_progress → paused)
|
||||||
# button_resume (covered by button_start when state='paused')
|
# button_resume (covered by button_start when state='paused')
|
||||||
# button_skip (pending/ready → skipped)
|
# button_skip (pending/ready → skipped)
|
||||||
# button_cancel (any non-done → cancelled)
|
# button_cancel (any non-done → cancelled)
|
||||||
# Predecessor-driven transition pending → ready will land in
|
# Predecessor-driven transition pending → ready will be wired
|
||||||
# Task 1.6 along with first-step / dependency wiring.
|
# alongside first-step / dependency logic in a future task.
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
def button_pause(self):
|
def button_pause(self):
|
||||||
raise NotImplementedError(_(
|
raise NotImplementedError(_(
|
||||||
"button_pause lands in Task 1.6 (operator pause / break / "
|
"button_pause is not yet implemented (operator pause / break / "
|
||||||
"end-of-shift). Use button_finish to complete a step or set "
|
"end-of-shift). Use button_finish to complete a step or set "
|
||||||
"state directly via privileged code."
|
"state directly via privileged code."
|
||||||
))
|
))
|
||||||
|
|
||||||
def button_skip(self):
|
def button_skip(self):
|
||||||
raise NotImplementedError(_(
|
raise NotImplementedError(_(
|
||||||
"button_skip lands in Task 1.6 (skip an opt-in step that "
|
"button_skip is not yet implemented (skip an opt-in step that "
|
||||||
"wasn't activated for this job)."
|
"wasn't activated for this job)."
|
||||||
))
|
))
|
||||||
|
|
||||||
def button_cancel(self):
|
def button_cancel(self):
|
||||||
raise NotImplementedError(_(
|
raise NotImplementedError(_(
|
||||||
"button_cancel lands in Task 1.6 (cancelling a single step; "
|
"button_cancel is not yet implemented (cancelling a single step; "
|
||||||
"cancelling the whole job runs through fp.job.action_cancel)."
|
"cancelling the whole job runs through fp.job.action_cancel)."
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|||||||
@@ -103,3 +103,20 @@ class TestFpJobStepStateMachine(TransactionCase):
|
|||||||
step.duration_actual = 30.0
|
step.duration_actual = 30.0
|
||||||
# Recompute happens on read after a write to a depends field
|
# Recompute happens on read after a write to a depends field
|
||||||
self.assertEqual(step.cost_total, 30.0)
|
self.assertEqual(step.cost_total, 30.0)
|
||||||
|
|
||||||
|
def test_cost_total_recomputes_when_rate_changes(self):
|
||||||
|
# Insurance test: verify @api.depends('cost_per_hour') triggers
|
||||||
|
# through the related-from-work_centre chain. If a future Odoo
|
||||||
|
# upgrade breaks related-depends, this test catches it.
|
||||||
|
wc = self.env['fp.work.centre'].create({
|
||||||
|
'name': 'WC4', 'code': 'WC4', 'kind': 'wet_line',
|
||||||
|
'cost_per_hour': 60.0,
|
||||||
|
})
|
||||||
|
step = self._make_step(work_centre_id=wc.id)
|
||||||
|
step.duration_actual = 30.0
|
||||||
|
self.assertEqual(step.cost_total, 30.0)
|
||||||
|
# Change the rate; cost_total should recompute.
|
||||||
|
wc.cost_per_hour = 120.0
|
||||||
|
# Force recompute via invalidate (Odoo recomputes on next read).
|
||||||
|
step.invalidate_recordset(['cost_total'])
|
||||||
|
self.assertEqual(step.cost_total, 60.0)
|
||||||
|
|||||||
Reference in New Issue
Block a user