Skip to content

feat(spp_drims): collect proof of delivery in a popup off the dispatch - #393

Draft
emjay0921 wants to merge 1 commit into
19.0from
feat/1088-drims-delivery-confirmation
Draft

feat(spp_drims): collect proof of delivery in a popup off the dispatch#393
emjay0921 wants to merge 1 commit into
19.0from
feat/1088-drims-delivery-confirmation

Conversation

@emjay0921

Copy link
Copy Markdown
Contributor

Why is this change needed?

Three problems on the dispatch form, all in the ticket:

  • Confirm Departure and Confirm Delivery sat in their own column beside Distribution Details, far enough from Departure & Arrival to read as unrelated.
  • Confirm Delivery was available before departure, so an arrival could be logged for goods that had not left.
  • Confirming delivery required typing the receiver's details into the form first. action_confirm_pod then refused with "Please enter the receiver's name" if you had not — the button told you what you should have done rather than letting you do it.

How was the change implemented?

Layout — each button now sits on the row of the field it fills, via <div class="o_row"> inside the Departure & Arrival group.

Ordering — Confirm Delivery is hidden until date_departed is set, with a muted "Confirm departure first" hint in its place.

The ticket asked for the button greyed out, which an Odoo form cannot express: ViewButton's disabled is a component prop and form_compiler.js never wires it to the arch, so invisible is the only declarative option. Flagged rather than silently substituted. The ordering is also enforced on the model — in action_open_delivery_confirmation and in action_confirm_pod — so no path can log an arrival for goods that never left, whatever the UI does.

The popup — new spp.drims.delivery.confirmation.wizard: receiver name/title/ID and delivery status up front, then tabs for Delivered Items, Evidence (signature, GPS, photos) and Notes & Discrepancies. On confirm it writes the existing POD block on the picking, which then becomes readonly="is_pod_confirmed" so the delivery record is not casually edited afterwards.

Delivered quantities — the popup also records what actually arrived per line. This is the part worth a reviewer's attention: nothing in the module wrote spp.drims.request.line.quantity_delivered before this, so total_delivered and fulfillment_pct sat at 0 however much had been delivered, and spp.drims.alert kept reporting the full requested quantity as still needed. Both #390 and #391 flagged this as belonging here. Quantities default to everything dispatched, are capped at it, and accumulate so a request filled by several dispatches totals correctly instead of overwriting.

A bug the tests missed and the fixtures caught

Lines are populated in both default_get and create. default_get alone only covers callers that pass the picking through the context — which is what the UI does, so the suite was green — but passing picking_id in the create() values, the obvious way from a script or over RPC, produced a wizard with no lines that silently recorded nothing. create() only routes missing fields through default_get, so the early return fired. Found by running the demo script rather than by the tests; there is now a test pinning that exact path.

New unit tests

spp_drims/tests/test_delivery_confirmation_wizard.py — 15 tests:

  • The button opens the wizard once departed, and refuses before departure, twice over, or on a non-dispatch picking.
  • Lines pre-fill from the done moves, defaulting to everything arriving — via the context path and via the values path.
  • Confirm writes the full POD block, stamps arrival, and computes the GeoPoint for GIS reporting.
  • Delivered quantities land on the request: fulfillment_pct goes 0 → 100; a short delivery records only what arrived; quantities accumulate across two dispatches.
  • Cannot deliver more than was dispatched, or a negative quantity; arrival cannot precede departure; out-of-range GPS raises rather than being silently dropped by _compute_pod_gps_point; departure cannot be re-recorded after delivery.

Unit tests executed by the author

Full module suite:

0 failed, 0 error(s) of 262 tests

All 15 new tests confirmed executing by name in the log. ./spp lint (ruff, ruff-format, prettier) passes. Module upgrades cleanly; both wizard models registered with 8 ACL rows across manager / officer / warehouse staff / coordinator, mirroring the create-return wizard's grants.

Verified in the running app on a fresh database via demo-scripts/ds-openspp2-op1088-spp_drims-20260804-01.py (7/7, exits non-zero on regression), and the rendering was checked by hand: buttons sit inline with their fields, the popup's quantity column is editable, the POD block populates and locks, and the request's Fulfillment % reads 100.

How to test manually

The script above leaves three dispatches, one per state.

  1. Not departed — Confirm Departure beside Departed At; Arrived At shows no button, only the hint.
  2. Departed, pending — Confirm Delivery beside Arrived At. Click it. Submitting with Received By empty must refuse; a delivered quantity above what was dispatched must refuse. Fill it in and confirm — the POD block populates and locks.
  3. Delivered — POD read-only, both buttons gone, and the request's Fulfillment % reads 100.

Related links

  • OP#1088 — Improve departure and delivery buttons

Notes for the reviewer

Behaviour change: action_confirm_pod now refuses when departure has not been recorded. test_pod_confirmation asserted the old behaviour and is updated for the new ordering. Anything calling that method directly needs departure first. The method is kept for programmatic callers; the form routes through action_open_delivery_confirmation.

Deliberately out of scope: the request state machine is still unwired. A fully delivered request stays at dispatched even now that Fulfillment reads 100%, because nothing sets the delivered or fulfilled states — and the request-states vocabulary contains both with no documented distinction between them. That is a design decision rather than an oversight, so it wants its own ticket instead of being folded in here.

readme/HISTORY.md and the manifest version are untouched — per our convention those land on 19.0 after merge, to avoid conflicts between concurrent PRs on the same module.

Overlap with the other open DRIMS PRs: this touches the DRIMS tab of stock_picking_views.xml and action_confirm_pod/action_confirm_departure in stock_picking.py. #391 (OP#1057) touches the Operations field and button_validate; #392 (OP#1086) touches the header statusbars; #390 (OP#1087) touches field definitions and button_validate. Different hunks throughout, so they should merge in any order, but this is the largest of the four and may want a rebase check if it lands last.

🤖 Generated with Claude Code

The Confirm Departure and Confirm Delivery buttons sat in their own column
beside Distribution Details, far enough from Departure & Arrival to read as
unrelated. Each now sits on the row of the field it fills.

Confirm Delivery stays hidden until departure is recorded, with a hint in
its place. The ticket asked for it greyed out, which an Odoo form cannot
express: ViewButton's `disabled` is a component prop and is never wired to
the arch, so `invisible` is the only declarative option. The ordering is
enforced on the model as well, in action_open_delivery_confirmation and
action_confirm_pod, so no path can log an arrival for goods that never
left.

Confirming delivery now opens spp.drims.delivery.confirmation.wizard
instead of expecting the officer to have typed the receiver's details into
the form and then pressing a button that refused if they had not. The
wizard collects receiver, delivery status, signature, photos, GPS and
notes, writes them back to the POD block, and locks that block once
confirmed so the delivery record is not casually edited afterwards.

It also records what actually arrived per line. Nothing in the module
wrote spp.drims.request.line.quantity_delivered before this, so
total_delivered and fulfillment_pct sat at 0 however much had been
delivered, and spp.drims.alert kept reporting the full requested quantity
as still needed. Quantities default to everything dispatched, are capped
at it, and accumulate so a request filled by several dispatches totals
correctly rather than overwriting.

Lines are populated in both default_get and create. default_get alone only
covers callers that pass the picking through the context; passing
picking_id in the values — the obvious way from a script or over RPC —
produced a wizard with no lines that silently recorded nothing. A test
pins that path.

test_pod_confirmation asserted the old behaviour of confirming delivery
with no departure recorded, and is updated for the new ordering.

OP#1088
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@codecov

codecov Bot commented Aug 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.96970% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.32%. Comparing base (7fff93b) to head (05d0b12).
⚠️ Report is 1 commits behind head on 19.0.

Files with missing lines Patch % Lines
spp_drims/wizard/delivery_confirmation_wizard.py 96.47% 3 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             19.0     #393      +/-   ##
==========================================
+ Coverage   72.27%   72.32%   +0.05%     
==========================================
  Files        1010     1009       -1     
  Lines       60741    60838      +97     
==========================================
+ Hits        43900    44003     +103     
+ Misses      16841    16835       -6     
Flag Coverage Δ
spp_base_common 91.07% <ø> (ø)
spp_drims 81.71% <96.96%> (+0.88%) ⬆️
spp_drims_sl_demo 69.01% <ø> (+0.52%) ⬆️
spp_programs 65.27% <ø> (ø)
spp_registry 87.22% <ø> (ø)
spp_security 69.56% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
spp_drims/models/stock_picking.py 82.40% <100.00%> (+5.61%) ⬆️
spp_drims/wizard/__init__.py 100.00% <100.00%> (ø)
spp_drims/wizard/delivery_confirmation_wizard.py 96.47% <96.47%> (ø)

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@emjay0921
emjay0921 marked this pull request as draft August 4, 2026 02:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant