feat(spp_drims): Dispatch page and waybill review — locked lines, one-page waybill - #433
Open
emjay0921 wants to merge 8 commits into
Open
feat(spp_drims): Dispatch page and waybill review — locked lines, one-page waybill#433emjay0921 wants to merge 8 commits into
emjay0921 wants to merge 8 commits into
Conversation
Rendered the waybill and read the result rather than the template. It came out two pages, with every column stacked and the signature row pushed onto page 2; the TO box empty; "Total Items" reading 1 for a 200-unit consignment; the picking's internal note printed; the quantity column showing demand rather than what was picked; and no barcode. Lay it out with tables instead of Bootstrap's grid. Reports are rendered by wkhtmltopdf 0.12.6, a WebKit build with no flexbox, so row/col-* and card collapse and each column becomes a row. A test fails if any of those classes reappear, because the damage is invisible in the browser preview and only shows in the PDF. Fill the TO box from location_dest_id. partner_id is blank on a dispatch — relief goods go to a location, not a customer — which is why the box was empty. Print an address only when a street is recorded, since the contact widget on a bare partner renders its name wrapped in dashes. Show Shipped alongside Demand. A waybill accompanies the goods, so it has to state what is actually on the vehicle; demand stays for reconciliation at the receiving end. Drop the "Total Items" footer, which counted move lines, and the note, which is internal. Always print the Vehicle and Driver rows so there is somewhere to write, and print whichever of Request or Donation matches the transaction type. Add the transaction type, distribution area, estimated beneficiaries and distribution type. The barcode needed two fixes and neither was in the template. reportlab 4.1 defaults renderPMBackend to rlPyCairo, which the image does not install, so /report/barcode/ answered HTTP 500 for every URL form — every barcode and QR code in every Odoo report, not just this one. Odoo's own requirements only pin a backend for win32, assuming the Debian package covers Linux. Adding rlPyCairo fixes the route. The image still did not appear, because an <img> with a relative URL needs wkhtmltopdf to fetch it from inside the rendering process, where web.base.url points at an external host and port that cannot be reached; embedding it as a data URI removes that dependency, verified by rendering with web.base.url deliberately pointed at a dead port. A failure to build the barcode is logged and skipped rather than raised, so it cannot stop a waybill printing. Also expose stock.move's drims_request_line_id and drims_donation_line_id, which appeared in no view, so it is possible to see which request or donation line a move fulfils. Read-only, since reassigning one by hand would misattribute dispatched and delivered quantities. Kept in its own file: the picking form's Operations list is defined inline in stock.view_picking_form and cannot be extended from a separate view. Note the ticket lists a third linkage field, drims_allocation_id, which does not exist on the model. OP#1151
The DRIMS tab sat last, behind Additional Info and Note, although it is where a dispatch is actually worked. It now sits second, right after Operations, and is labelled "Dispatch & Delivery" rather than "DRIMS". Replace "Delivery Address" with the destination location on a dispatch. partner_id is left blank because relief goods go to a location rather than a customer, so the field only invited someone to fill in something meaningless — and its emptiness is why the waybill's TO box printed blank (OP#1151). Core hides location_dest_id for outgoing pickings and keeps an invisible="1" copy behind stock.group_stock_multi_locations, which is why a dispatch showed no destination at all; rather than un-hide core's copy, which would stay invisible wherever that group is off, add a read-only one scoped to dispatches. It is populated by spp.drims.request.action_create_dispatch from the request's destination warehouse. Both changes are scoped to request dispatches, so donation receipts, transfers, returns and plain stock pickings are untouched — asserted per picking kind by evaluating the view's own invisible expressions. The ticket's fourth item, removing the ability to delete a line, is already implemented for request dispatches in OP#1057; repeating it here would mean two xpaths setting the same attribute on the same field. OP#1150
…waybill-and-dispatch-page # Conflicts: # spp_drims/views/stock_picking_views.xml
A request dispatch is generated by action_create_dispatch, which sets the operation type, the source location, the source document, the products and every field under DRIMS Information. None of them is the dispatcher's to change, but core only locks the header fields once the picking is done or cancelled, so they stayed editable for a dispatch's whole working life. Lock them for request dispatches only. Ordinary transfers, donation receipts and returns keep core's behaviour. Quantity is deliberately left editable: entering less than Demand is how a partial dispatch and its backorder are produced (OP#1087). Both header xpaths need qualifying. Core declares picking_type_id twice — once in the header and once column_invisible in the moves list — and location_id three times: a copy hidden behind !stock.group_stock_multi_locations, the visible Source Location behind that same group, and one in the list. position="attributes" takes the first match, which for location_id is the invisible copy, so an unqualified xpath would have locked a field nobody can see and looked like nothing happened. A test asserts the lock lands on the visible field for that reason. Also converts a round-1 xpath from @Class to hasclass(), which the UI hook requires, and moves the test fixtures onto OP#1079's per-warehouse allocation model.
…waybill-and-dispatch-page
…ad-only QA asked whether Source Location had become clickable. It had, and round 2 is what did it: making a many2one read-only turns it into an internal link to the record. Core sets no_open on picking_type_id already, which is why Operation Type is inert - it does not on location_id. no_open cannot be made conditional, because options is parsed as a static dict and cannot reference drims_type. So core's copy is hidden on a dispatch and an inert one shown in its place, the same shape as OP#1158's hazard category. The replacement repeats the multi-locations group, or a single-location installation would start seeing a Source Location field it is not meant to have. The view tests now ask which copy a given kind of picking actually renders, rather than assuming one node per field.
view_stock_move_operations_drims fails the XML ID hook - "operations" is not a view type - so it would block this branch's PR. Renamed to view_move_form_operations_drims, matching its siblings in the same file (view_move_form_drims, view_move_tree_drims). Introduced by the waybill commit on this branch; never on 19.0, and referenced nowhere else, so the rename is contained.
…waybill-and-dispatch-page
emjay0921
marked this pull request as ready for review
August 18, 2026 06:15
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 19.0 #433 +/- ##
==========================================
+ Coverage 72.24% 72.27% +0.02%
==========================================
Files 419 419
Lines 29813 29829 +16
==========================================
+ Hits 21539 21558 +19
+ Misses 8274 8271 -3
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why is this change needed?
Two children of the Stock Allocation & Dispatch review (OP#1077), both returned from QA as passing:
How was the change implemented?
rlPyCairowas added todocker/requirements.txt: every barcode and QR in every Odoo report goes throughrenderPM, reportlab 4.1 defaults that backend torlPyCairo, and without it/report/barcode/returns 500. Odoo's own requirements only pin a backend for win32, assuming Debian'spython3-renderpm— this image does not install it.spp.drims.request.action_create_dispatchactually populates;partner_idstays blank, and that emptiness is why the waybill's TO box printed blank.no_opencannot be conditional, so core's copy is hidden on a dispatch and an inert copy shown in its place — the same shape as OP#1158's hazard category.picking_type_idtwice andlocation_idthree times, andposition="attributes"takes the first match — which forlocation_idis the copy nobody can see, so an unqualified xpath would have looked like nothing happened.New unit tests
spp_drims/tests/test_waybill_report.py— 13 tests, asserting against the rendered PDF/HTML rather than the template.spp_drims/tests/test_dispatch_page.py— 11 tests, evaluating the view's owninvisibleexpressions per kind of picking so a change scoped to dispatches is proven not to touch transfers, receipts or returns.Unit tests executed by the author
Full
spp_drimssuite on this branch, against a fresh database: 287 tests, 0 failed, 0 errors.Worth knowing for anyone testing locally: two of the barcode tests need the
rlPyCairothis PR adds, so a container image built before this branch fails them withModuleNotFoundError: No module named 'rlPyCairo', andpip install rlPyCairoinside the runtime image cannot fix it — pycairo needs the dev headers that only the builder stage has. Rebuild the image (docker compose build openspp-dev) and they pass. CI builds the test image fromdocker/Dockerfileat this checkout, so it picks the dependency up on its own.How to test manually
./spp start, then open a DRIMS request and allocate it.Related links