Files
2026-09-18 13:55:25 +07:00
..
2026-09-18 13:55:25 +07:00
2026-09-18 13:55:25 +07:00
2026-09-18 13:55:25 +07:00
2026-09-18 13:55:25 +07:00
2026-09-18 13:55:25 +07:00
2026-09-18 13:55:25 +07:00
2026-09-18 13:55:25 +07:00
2026-09-18 13:55:25 +07:00
2026-09-18 13:55:25 +07:00
2026-09-18 13:55:25 +07:00
2026-09-18 13:55:25 +07:00

NextZen Approvals — document binding
====================================

This module extends **nextzen_approval** so approval definitions can target any
business model (for example ``product.product`` or ``sale.order`` when Sale is
installed).

Deployed definitions
----------------------

Use **Document binding** on an approval definition, set **Target model** and an
**Eligibility domain** (Python list, same format as Odoo domains), then click
**Deploy to model**. The module will:

- Create three fields on the target model (names **must** start with ``x_`` per Odoo rules for custom fields):

  - ``x_nxz_needs_approval`` — non-stored boolean, true when the record matches
    the combined eligibility domains of deployed definitions for that model.
    Its ``depends`` list is derived from those domains (plus ``display_name`` /
    ``name`` and ``active``) so the value updates after save; ``create``/``write``
    also invalidate it so the **Request approval** header updates without a manual
    page refresh.
  - ``x_nxz_approval_outcome`` — stored char: ``approved``, ``refused``, or empty.
  - ``x_nxz_approval_request_open`` — stored boolean, set when a request exists from
    the UI wizard (for “View approval” / duplicate protection).

- Inject form header buttons: **Request approval**, **View approval**, **Rework**
  (after refusal).

Python actions
--------------

On **final approval** or **refusal**, optional server-side Python can run
(**Python on final approval** / **Python on refusal**). The evaluation context
contains:

- ``env``, ``uid``, ``user``
- ``doc`` — the source business record (with a safe-eval context flag set)
- ``approval`` — the ``nxz.approval.request`` record
- ``refusal_reason`` — text (refusal path only)
- ``UserError``, ``ValidationError``
- ``log(message, level='info')`` — writes to the server log

Assign ``action`` in that namespace to return a window action dict to the client.

Write rules
-----------

While ``x_nxz_needs_approval`` is true and the outcome is not **approved**:

- Changing the configured **State / stage field** is blocked.
- If the outcome is **refused**, any write is blocked until **Rework** clears it.

Other edits are allowed when the outcome is still empty (submitted/pending), in
line with the original multi-level configuration behavior.

Tests
-----

Run with::

  ./odoo-bin -d DB -i nextzen_approval_configuration --test-enable \\
    --stop-after-init --addons-path=...

See ``tests/`` for automated checks.

Upgrading from older builds
---------------------------

If **Configure** previously created fields named ``nxz_*`` (without the ``x_`` prefix),
remove those custom fields from the affected models (or uninstall/reinstall the
module on a test DB) and run **Configure** again so Odoo can create ``x_nxz_*`` fields.

Further reading
---------------

Functional rules for the base workflow are documented under
``nextzen_approval/readme/FUNCTIONAL_SPEC.md``.