Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6148b1b
fix(spp_drims): bundled round-1 fixes for DRIMS tracker (#651)
emjay0921 May 18, 2026
4c910b9
fix(spp_drims): make Priority field editable on Request form (#965)
emjay0921 May 19, 2026
1e37e64
feat(spp_drims): collect rejection reason via wizard on Request rejec…
emjay0921 May 19, 2026
e782c29
fix(spp_base_common,spp_drims): round-2 QA fixes for OP#967 + OP#968
emjay0921 May 20, 2026
f98eecd
fix(spp_drims): hide redundant standard Print + Return buttons on DRI…
emjay0921 May 20, 2026
32f3369
fix(spp_drims): escape xmlid-resolution sigil in comment to avoid par…
emjay0921 May 20, 2026
09f872b
feat(spp_drims): add post-approval lanes Ready for Allocation / Ready…
emjay0921 May 20, 2026
d7e9c7b
fix(spp_drims): lock quantity_received editing to the received state …
emjay0921 May 22, 2026
724a838
feat(spp_drims): add warehouse tier + surface GIS location field on w…
emjay0921 May 22, 2026
93753a4
fix(spp_drims): donation statusbar is read-only display, not clickabl…
emjay0921 May 22, 2026
3546fdf
fix(spp_drims): block empty allocation and keep request at Ready for …
emjay0921 May 22, 2026
ce555c2
feat(drims): redesign inspection wizard with inline editing and split…
emjay0921 May 25, 2026
21b50b7
feat(drims): support multiple partial dispatches per request (#1033)
emjay0921 May 25, 2026
030b9de
fix(drims): exclude non-accept dispositions from donation stocking (#…
emjay0921 May 26, 2026
5d6b9ce
feat(drims): polish inspection wizard list per QA feedback (#963 r2)
emjay0921 May 26, 2026
84ada72
feat(drims): inspection wizard add-split UX polish (#963 r3)
emjay0921 May 26, 2026
625ebbf
fix(drims): robust non-accept exclusion when receipt moves merge (#10…
emjay0921 May 26, 2026
a3e8d1e
feat(drims): dynamic Confirm gate with stacked reason messages (#963 r4)
emjay0921 May 26, 2026
d6bfdf5
fix(drims): subtract pending allocations from available qty (#1033 r2)
emjay0921 May 26, 2026
2802364
chore(drims): point users to the DRIMS tab on dispatch validation errors
emjay0921 May 26, 2026
2a0a872
fix(drims): refresh donation form after action_stock's notification
emjay0921 May 28, 2026
6dd6a07
feat(drims): hide Stock button when every donation line is non-accept…
emjay0921 May 29, 2026
8540644
fix(drims): give GPS map its own full-width section on warehouse form…
emjay0921 Jun 3, 2026
51d9d1e
Merge remote-tracking branch 'origin/19.0' into fix/651-drims-improve…
emjay0921 Jun 8, 2026
06bebc4
chore: regenerate addon READMEs to satisfy pre-commit
emjay0921 Jun 8, 2026
b890139
fix(drims): address review feedback on inspection wizard + picking vi…
emjay0921 Jun 8, 2026
cfd8dee
feat(drims): split a line into two rows on first split (#651)
emjay0921 Jun 8, 2026
e14e1f8
Merge remote-tracking branch 'origin/19.0' into fix/651-drims-improve…
emjay0921 Jun 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions spp_base_common/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"spp_base_common/static/src/xml/custom_list_create_template.xml",
"spp_base_common/static/src/js/filterable_radio_field.js",
"spp_base_common/static/src/xml/filterable_radio_field.xml",
"spp_base_common/static/src/js/integer_positive_required.js",
"spp_base_common/static/src/xml/pager_hide_single.xml",
"spp_base_common/static/src/scss/pager_hide_single.scss",
],
Expand Down
59 changes: 59 additions & 0 deletions spp_base_common/static/src/js/integer_positive_required.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/** @odoo-module **/
/*
* `integer_positive_required` field widget — a reusable Integer field that
* treats 0 as invalid when the field is required.
*
* Why: Odoo 19's `_checkValidity` (web/static/src/model/relational_model/
* record.js) explicitly skips numeric field types (`boolean`, `float`,
* `integer`, `monetary`) from the required-empty validation. That means
* a required Integer with value 0 is NEVER added to `_invalidFields`,
* the `o_field_invalid` class is NEVER applied, and the user gets no
* visual cue (asterisk on label / pink highlight on input) that the
* field is unfilled. The model-side validation still rejects 0 on save,
* but the form is silent until then.
*
* `fieldVisualFeedback` calls `field.isValid(record, fieldName, fieldInfo)`
* BEFORE falling back to `record.isFieldInvalid(...)`. So a widget can
* override `isValid` to plug its own check into the visual-feedback
* pipeline. We use that hook to mark the field invalid when value <= 0
* AND `required` evaluates true.
*
* Usage:
* <field name="beneficiary_count"
* widget="integer_positive_required"
* required="..."/>
*/

import {evaluateBooleanExpr} from "@web/core/py_js/py";
import {registry} from "@web/core/registry";
import {integerField} from "@web/views/fields/integer/integer_field";

export const integerPositiveRequiredField = {
...integerField,
isEmpty: (record, fieldName) => {
const value = record.data[fieldName];
return value === false || value === 0;
},
isValid: (record, fieldName, fieldInfo) => {
const value = record.data[fieldName];
// Field is valid if value is a positive integer.
if (typeof value === "number" && value > 0) {
return true;
}
// 0, false (unset), or non-numeric — only valid when field is not
// required. Evaluate the required modifier against the record's
// eval context (it may be a dynamic expression like
// `drims_type == 'request_dispatch'`). `fieldInfo.required` is
// undefined for fields with no required modifier; guard against it
// so `evaluateBooleanExpr` is never handed `undefined` (which throws
// and crashes the form view).
const required = fieldInfo.required
? evaluateBooleanExpr(fieldInfo.required, record.evalContextWithVirtualIds)
: false;
return !required;
},
};

registry
.category("fields")
.add("integer_positive_required", integerPositiveRequiredField);
12 changes: 11 additions & 1 deletion spp_drims/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"mail",
"stock",
"spp_alerts",
"spp_base_common",
"spp_security",
"spp_vocabulary",
"spp_area",
Expand Down Expand Up @@ -51,6 +52,7 @@
"views/menu_structure.xml",
# Wizards (before views, as views may reference wizard actions)
"wizard/bulk_approve_wizard.xml",
"wizard/request_reject_wizard_views.xml",
"wizard/report_4w_wizard_views.xml",
"wizard/stock_adjustment_wizard_views.xml",
"wizard/inter_warehouse_transfer_wizard_views.xml",
Expand Down Expand Up @@ -79,7 +81,15 @@
# Menus with actions (loaded last, after all views define their actions)
"views/menus.xml",
],
"assets": {},
"assets": {
"web.assets_backend": [
"spp_drims/static/src/js/hide_dispatch_form_create.js",
"spp_drims/static/src/js/inspection_list_renderer.js",
"spp_drims/static/src/js/qty_split_progress_field.js",
"spp_drims/static/src/xml/qty_split_progress_field.xml",
"spp_drims/static/src/css/inspection_wizard.css",
],
},
"application": True,
"installable": True,
"auto_install": False,
Expand Down
35 changes: 23 additions & 12 deletions spp_drims/data/vocabulary_codes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,20 @@
<field name="display">Submitted</field>
<field name="sequence">20</field>
</record>
<record id="code_drims_request_approved" model="spp.vocabulary.code">
<field name="vocabulary_id" ref="vocab_drims_request_state" />
<field name="code">approved</field>
<field name="display">Approved</field>
<field name="sequence">30</field>
</record>
<!--
OP#969: relabel `approved` so the post-approval queue is obvious.
Wrapped in noupdate=0 so the renamed `display` propagates on every
module upgrade (the outer odoo element has noupdate=1, which would
otherwise skip the rewrite on already-installed databases).
-->
<data noupdate="0">
<record id="code_drims_request_approved" model="spp.vocabulary.code">
<field name="vocabulary_id" ref="vocab_drims_request_state" />
<field name="code">approved</field>
<field name="display">Ready for Allocation</field>
<field name="sequence">30</field>
</record>
</data>
<record id="code_drims_request_rejected" model="spp.vocabulary.code">
<field name="vocabulary_id" ref="vocab_drims_request_state" />
<field name="code">rejected</field>
Expand All @@ -173,12 +181,15 @@
<field name="display">Fulfilled</field>
<field name="sequence">50</field>
</record>
<record id="code_drims_request_allocated" model="spp.vocabulary.code">
<field name="vocabulary_id" ref="vocab_drims_request_state" />
<field name="code">allocated</field>
<field name="display">Allocated</field>
<field name="sequence">35</field>
</record>
<!-- OP#969: relabel `allocated` — see note on `approved` above. -->
<data noupdate="0">
<record id="code_drims_request_allocated" model="spp.vocabulary.code">
<field name="vocabulary_id" ref="vocab_drims_request_state" />
<field name="code">allocated</field>
<field name="display">Ready for Dispatch</field>
<field name="sequence">35</field>
</record>
</data>
<record id="code_drims_request_dispatched" model="spp.vocabulary.code">
<field name="vocabulary_id" ref="vocab_drims_request_state" />
<field name="code">dispatched</field>
Expand Down
Loading
Loading