Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ency07/B2B-import/llms.txt

Use this file to discover all available pages before exploring further.

The Approvals module provides a configurable multi-level authorization engine that governs commercial decisions across B2B Import ERP. Rather than hard-coding who approves what, the system lets each tenant define reusable approval flows (sequential, parallel, or mixed), attach amount-based rules to business objects, and route incoming approval requests to the right people automatically. Every decision — regardless of outcome — is recorded immutably in both approval_request_steps and the central audit_log.

What Can Be Approved

The approval engine currently supports the following object types, as defined by the entity_type CHECK constraint in approval_rules and approval_requests:

Quotations

The primary use case. Quotes entering EN_REVISION automatically trigger approval routing based on the configured amount rules.

Invoices

Invoice approval workflows for billing authorization before issuance to clients.

Contracts

Contract sign-off workflows for formal service agreements.
Approval workflows are fully configurable per tenant in Settings → Approval Flows. You can create as many flows as needed, each with different step sequences, assigned roles or users, and amount thresholds.

Approval States

Each approval_requests record and each approval_request_steps record tracks its own state independently:
PENDIENTE

   ├──► APROBADA            (all required steps approved)
   ├──► RECHAZADA           (any required step rejected)
   └──► AJUSTES_SOLICITADOS (approver requests changes)

          └──► PENDIENTE    (request reset after adjustments applied)
Additionally, a request can be cancelled (CANCELADA) by an administrator before it reaches a final decision.
StateDescription
PENDIENTEAwaiting action from the assigned approver
EN_PROCESOAt least one step approved; remaining steps still pending
APROBADAAll required steps approved; linked object updated accordingly
RECHAZADAA required step was rejected; linked object set to RECHAZADA
AJUSTES_SOLICITADOSApprover requested changes; linked quote returned to EN_REVISION
CANCELADARequest cancelled by administrator

Approval Flow

The following sequence describes how a Quote triggers and moves through the approval engine:
  1. Commercial executive moves the quote from BORRADOREN_REVISION.
  2. The route_quote_approvals trigger fires (BEFORE UPDATE OF status on quotes) and:
    • Searches approval_rules for an active rule matching entity_type = 'QUOTE' and the quote’s total_amount.
    • If a rule with a flow_id is found: creates an approval_requests record (PENDIENTE) and instantiates one approval_request_steps row per step in the flow.
    • If no rule is found: escalates automatically to the GERENTE_GENERAL role with a single-step request.
    • If flow_id = NULL on the rule: auto-approves the quote immediately.
  3. Approver calls resolve_approval_step(requestId, stepOrder, decision, comments) with a mandatory comment.
  4. The function validates the approver’s identity and role, checks sequential ordering (in SECUENCIAL flow type), updates the step, and evaluates whether all required steps have been resolved.
  5. If all required steps are APROBADA: the approval_requests status becomes APROBADA and the quote status is set to APROBADA.
  6. If any step is RECHAZADA: the request and the quote both become RECHAZADA.
  7. If a step is AJUSTES_SOLICITADOS: the request status becomes AJUSTES_SOLICITADOS and the quote is returned to EN_REVISION for the commercial team to revise.
While an approval request is in PENDIENTE or EN_PROCESO state, the quote and all of its line items are locked against modification. Attempting to edit them raises a database-level exception.

Multi-Level Approvals

Workflows can chain any number of approvers. Each step in an approval_flow is assigned either to a role (role_id) or a specific user (user_id) — never both. The step_order determines the sequence.
Flow TypeBehaviour
SECUENCIALSteps must be resolved in order; step N cannot be approved until step N-1 is APROBADA
PARALELAAll steps can be resolved simultaneously; the request resolves when all required steps complete
MIXTAA combination of sequential and parallel steps, defined per flow configuration
For a quote to reach APROBADA status, all steps marked required = true must be individually approved. Optional steps (required = false) do not block final resolution.

approval_requests Table — Key Columns

The following columns on the approval_requests table carry the most operationally significant information:
ColumnTypeDescription
request_codevarchar(50)Auto-generated code APR-000001; unique per tenant
entity_typevarchar(100)Object being approved: QUOTE, INVOICE, CONTRACT
entity_iduuidFK to the object’s primary key
flow_iduuidFK to approval_flows; NULL for escalation requests
requested_byuuidUser who triggered the approval (e.g. the commercial executive)
requested_attimestampWhen the approval was requested
statusenumCurrent state of the request (see table above)
resolved_byuuidUser who made the final decision
resolved_attimestampTimestamp of the final decision
commentstextFinal decision comment (populated by resolve_approval_step)
Each individual step decision is recorded in approval_request_steps, including the step-level comments, resolved_by, and resolved_at.

RBAC — Role-Based Access

ActionRoles
Configure flows & rulesADMINISTRADOR, GERENTE_GENERAL, SUPER_ADMIN
Approve / reject quotes (quotes.approve)GERENTE_GENERAL, DIRECTOR_COMERCIAL
View approval requestsAll authenticated tenant users
Cancel an approval requestADMINISTRADOR, GERENTE_GENERAL, SUPER_ADMIN
The enforce_approval_config_permissions trigger blocks INSERT, UPDATE, and DELETE on approval_flows, approval_steps, and approval_rules for any user without the ADMINISTRADOR or GERENTE_GENERAL role. Platform Super Admins bypass this check.

Audit Trail

Every approval decision is permanently recorded across three layers:
  1. approval_request_steps — the per-step decision record with resolved_by, resolved_at, and the full comments text.
  2. business_events — semantic events emitted by resolve_approval_step() and dispatch_approval_events():
Event CodeEmitted When
APPROVAL_REQUEST_CREATEDNew approval request instantiated
APPROVAL_REQUEST_APPROVEDA step is approved
APPROVAL_REQUEST_REJECTEDA step is rejected
APPROVAL_REQUEST_ADJUSTMENTS_REQUESTEDApprover requests changes
APPROVAL_REQUEST_CANCELLEDRequest cancelled by administrator
APPROVAL_FLOW_CREATEDA new approval flow is configured
APPROVAL_RULE_CREATEDA new amount rule is added
  1. audit_log — the process_audit_log() trigger fires on every INSERT, UPDATE, or DELETE across all approval tables, capturing the full before/after JSONB diff.
Physical deletion of any approval entity is blocked by block_physical_approval_delete. All records are permanent and can only be logically deactivated via soft-delete.

Dashboard

Navigate to pending approvals for your tenant:
/dashboard/approvals?tenant=<code>

Build docs developers (and LLMs) love