mar-pod-b2b / module-b2b-advanced-approval
Conditional, parallel, delegated, and escalated approval rules for Marpod B2B Advanced.
Package info
gitlab.com/mar-pod-b2b/module-b2b-advanced-approval
Type:magento2-module
pkg:composer/mar-pod-b2b/module-b2b-advanced-approval
Requires
- php: ^8.5
- magento/framework: ^103.0
- magento/module-catalog: ^104.0
- magento/module-customer: ^103.0
- magento/module-graph-ql: ^100.4
- magento/module-webapi: ^100.4
- mar-pod-b2b/module-b2b-company: ^1.0
- mar-pod-b2b/module-b2b-core: ^1.0
- mar-pod-b2b/module-b2b-purchase-approval: ^1.0
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-08-24 17:11:49 UTC
README
Conditional approval rule groups, delegation, and escalation, layered on top of
Marpod_B2bPurchaseApproval's frozen workflow contracts.
Status
Full rule engine, delegation, escalation, and Admin UI shipped.
Implemented foundation
- declarative schema:
marpod_b2b_advanced_approval_rule_group(per company, with an AND/OR operator),marpod_b2b_advanced_approval_rule_condition(one or more conditions per group),marpod_b2b_advanced_approval_delegate(date-windowed reassignment from one approver to another),marpod_b2b_advanced_approval_deadline(due-soon tracking); - conditions are evaluated through the
ConditionMatcherInterfacepool:amount,category, andskuare real, live matchers against the purchase request.payment_methodandcost_centermatcher entries exist but are placeholders — the frozenMarpod_B2bPurchaseApproval\Api\Data\PurchaseRequestInterfacehas no such fields, so these two conditions never match anything today. They are kept as documented, honest placeholders for a future request-data extension rather than removed or faked; group-level AND/OR combines however many conditions a group has; - delegation:
ApprovalDelegateRepositoryInterfacelets one approver hand off pending approvals to another for a date range;ApprovalStepRepositoryInterface::save()performs the actual reassignment for steps that fall inside an active delegate's window;getListDueSoon()returns steps with a deadline in the next N days — this is only a query, used to build the due-soon reminder view; there is no automatic notification dispatch; - a rule simulator lets an admin test a group's conditions against a sample request without
creating one, using the same
ConditionMatcherInterfacepool the live workflow uses; - approval remains strictly sequential —
Marpod_B2bPurchaseApproval'sApprovalStepInterfacehas no concept of parallel/any-of steps, and this module does not add one; multiple conditions in a group combine logically (AND/OR), they do not create parallel approval steps.
Admin UI
Marpod_B2bAdvancedApproval::manage provides two screens, both a standard grid + dedicated
add/edit form: Approval Rule Groups (marpod_b2b_advanced_approval/group/index, with inline
condition add/delete) and Approval Delegates
(marpod_b2b_advanced_approval/delegate/index, a sortable/filterable grid of all delegates
across every company, with marpod_b2b_advanced_approval/delegate/edit for creating or editing
one). Approval Rule Group edit uses persistent General and Conditions tabs with a native
Magento action bar. The Conditions grid resolves category/product details and provides filtering,
record counts, page-size selection, and pagination; the add form is separated below the grid.
Requirements
- PHP 8.5
- Magento 2.4.9-compatible framework packages
mar-pod-b2b/module-b2b-core,mar-pod-b2b/module-b2b-purchase-approval
Installation
Run from the Magento project root:
composer require mar-pod-b2b/module-b2b-advanced-approval:^1.1
bin/magento module:enable Marpod_B2bAdvancedApproval
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:clean
Development
The planned scope, dependency rules, cache boundaries, security requirements, and test strategy
are documented in packages/B2B_LIGHT_PLAN.md in the development Magento project (section 9.5).
Unit tests:
vendor/bin/phpunit -c dev/tests/unit/phpunit.xml.dist packages/module-b2b-advanced-approval/Test/Unit
Admin smoke test:
cd packages/module-b2b-advanced-approval/Test/Playwright
npm install
npm test
REST/GraphQL API tests (real HTTP against a running instance — routing, authentication, ACL
enforcement, and cross-company isolation; see mar-pod-b2b/module-b2b-core's README for the
shared Test/Api base classes these build on):
vendor/bin/phpunit -c dev/tests/api-functional/phpunit_rest.xml \
packages/module-b2b-advanced-approval/Test/Api/Rest/AdvancedApprovalRestTest.php
vendor/bin/phpunit -c dev/tests/api-functional/phpunit_graphql.xml \
packages/module-b2b-advanced-approval/Test/Api/GraphQl/SimulatePurchaseApprovalGraphQlTest.php
Integration surfaces
Admin REST routes below /rest/V1/marpod-b2b/advanced-approval require the existing
Marpod_B2bAdvancedApproval::manage ACL resource and cover groups, conditions, and delegates —
the same CRUD surface the Admin UI already exposes. Deadlines, escalation, and the simulator have
no Admin UI either, so they stay unexposed via REST too.
Authenticated customers can query marpodB2bSimulatePurchaseApproval(totalAmount, skus,
categoryIds) through GraphQL — a read-only preview of how many approval steps a hypothetical
purchase would require for their own company (company ID is always derived from the customer
token, never accepted as an argument). Nothing else in this module is customer-facing:
ApprovalRuleGroupRepositoryInterface/ApprovalRuleConditionRepositoryInterface/
ApprovalDelegateRepositoryInterface all perform structural validation only, never
caller-identity or company-scoping — safe behind the ACL-gated Admin REST above, but never safe
to expose directly to a customer.
Limitations
payment_methodandcost_centerconditions are UI-visible placeholders that never match — see above;- no parallel ("any N of M") approval;
- due-soon reminders are a query only, with no email/notification dispatch.
- the rule simulator has a customer-facing GraphQL query (see Integration surfaces) but no Admin form yet.
Uninstallation
Do not remove the package while another installed module requires it. The
marpod_b2b_advanced_approval_* tables contain business data and are retained when the module
is disabled or its package is removed; the base Marpod_B2bPurchaseApproval workflow continues
to function with its own, unconditioned amount-threshold rules once this module is removed.