Sprint 10 — Cómo se evalúan BOMs multi-nivel y materiales intermedios
Un material intermedio es un subensamble que el productor declara explícitamente como tal: si cumple su propia regla de origen, todo su valor cuenta como originario. Si no cumple, el algoritmo se "cae" a evaluar sus componentes individuales.
El algoritmo se ejecuta recursivamente, una vez por cada nodo del BOM — desde las hojas hasta el producto raíz. Para cada nodo decide cuánto valor aporta como originario al nodo padre. El resultado final es el VCR del producto completo.
Hay tres caminos posibles según cómo se haya declarado el componente en el BOM: (1) hoja terminal — se evalúa su origen y listo; (2) subensamble común — se desarma y cada hijo cuenta individualmente; (3) material intermedio — se evalúa contra su propia regla T-MEC, y según si cumple o no, se trata como bloque originario o se desarma.
flowchart TD
Start(["📦 Nodo del BOM
componente o subensamble"])
Start --> Q1{"¿Es hoja?
sourcing_type = PURCHASED
o sin hijos en el BOM"}
Q1 -->|Sí| Leaf["LEAF — Caso 1
Componente terminal.
Origen por país / certificado / manual.
Aporta su valor al padre con ese origen."]
Q1 -->|No| Q2{"¿El productor declaró
material intermedio?
is_intermediate_material = true"}
Q2 -->|No| SubA["SUBENSAMBLE COMÚN — Caso 2
Material propio sin regla.
Cada hijo aporta al padre
con su origen individual."]
Q2 -->|Sí| Inter["MATERIAL INTERMEDIO — Caso 3
Tiene regla de origen propia
(Anexo 4-B).
Buscarla y evaluarla."]
Inter --> Q3{"¿Cumple su
regla T-MEC?
VCR, brinco arancelario,
o ambos según rule_type"}
Q3 -->|Sí| Whole["WHOLE_ORIGINATING
Todo el subensamble cuenta
como originario al padre,
sin importar composición interna."]
Q3 -->|No| Drill["DRILL_DOWN
El subensamble no cuenta como bloque.
Sus hijos aportan al padre
individualmente con sus orígenes."]
classDef leafNode fill:#f3f4f6,stroke:#6b7280,color:#111827,stroke-width:1.5px
classDef commonNode fill:#fef3c7,stroke:#c2410c,color:#111827,stroke-width:1.5px
classDef interNode fill:#dbeafe,stroke:#2563eb,color:#111827,stroke-width:1.5px
classDef passNode fill:#dcfce7,stroke:#15803d,color:#111827,stroke-width:1.5px
classDef failNode fill:#fee2e2,stroke:#b91c1c,color:#111827,stroke-width:1.5px
classDef startNode fill:#ffffff,stroke:#111827,color:#111827,stroke-width:1.5px
class Start startNode
class Leaf leafNode
class SubA commonNode
class Inter interNode
class Whole passNode
class Drill failNode
LEAF = el nodo no se desarma, se evalúa como pieza simple.WHOLE_ORIGINATING = el subensamble entero (su valor total) suma como originario al padre.DRILL_DOWN = el subensamble se "desarma" y son sus hijos los que aportan al padre.| rule_type | Significado | Cumple si... |
|---|---|---|
CC / CTH / CTSH | Sólo cambio arancelario | Todos los hijos no originarios cambian de capítulo / partida / subpartida |
VCR | Sólo Valor de Contenido Regional | Sub-VCR del subensamble ≥ umbral de la regla |
BOTH EITHER | El productor elige | Brinco O VCR (basta con uno) |
MIXED | Ambos exigidos | Brinco Y VCR (ambos) |
Producto: Motor completo 8407.32 — destino PASSENGER — VCR umbral 75%
Regla T-MEC: BOTH (Tabla B, EITHER — el productor elige)
Los componentes se evalúan individualmente; no se aplica regla al subensamble.
Si el motor de arranque no cumple ni VCR ni brinco, el algoritmo "se cae" a desglosar sus componentes.
sourcing_type = PURCHASED.
No se explota. Se trata como leaf con su origen propio (proveedor / certificado / país).
sourcing_type = INTERNAL + is_intermediate_material = false.
Sin regla propia. Cada hijo aporta su origen individual al padre.
sourcing_type = INTERNAL + is_intermediate_material = true.
Se evalúa contra su propia regla. Si cumple, todo el valor cuenta como originario.
El cliente declara estos flags en su carga de datos (template CSV o formulario UI):
Sí / No.
Cuando se marca, el algoritmo busca la regla de origen del subensamble y la evalúa.Interno / Comprado.
Indica si el subensamble se fabrica en planta (puede explotarse) o se compra armado.