Guía: Lectura desde GET · ← Respuesta GET · Aplicación →
rule_conditions — referencia completa
:::info Campo en la respuesta GET
En GET /points y GET /points/{id}, este bloque viene en rule_conditions (string JSON). Tras parsear, la estructura es conditions.and[] / conditions.or[] como en esta sección.
:::
Índice
- Condiciones por
when - Condiciones en evento personalizado
- Qué hacen
- Dos formatos del mismo concepto
- Estructura lógica (AND, OR y subgrupos)
- Cómo identificar qué evalúa cada cláusula
- Campos estructurales (cláusulas dentro de
rule_conditions) - Operadores por tipo de dato
- Catálogo — condiciones de cliente
- Catálogo — condiciones de carrito (ticket)
- Catálogo — tienda (ubicación)
- Catálogo — condiciones en líneas
- Errores frecuentes al leer
rule_conditions - Apéndice: mapa del JSON maestro (todas las opciones)
Condiciones por when
when | Qué puede incluir rule_conditions |
|---|---|
Carrito (after_create_activity) | Misma gramática que descuentos: customer (tier, atributos, país de registro), ticket (total, original_total, total_cart_without_additional_costs), líneas (producto, categoría, atributos), tienda / categoría de tienda, payments (método de pago en condiciones de victoria), cantidades para bundle. |
Evento personalizado (after_create_custom_entity) | Filtros sobre atributos de la entidad custom enviada en el evento — ver Condiciones en evento personalizado. |
| Trigger (slug configurado) | Sin condiciones de victoria en ticket: el disparo API es la condición. |
Manual (manual) | Obligatorio vacío: {"conditions":{"and":[]}}. |
Condiciones en evento personalizado
En when: "after_create_custom_entity", rule_conditions define cuándo la campaña puede otorgar saldo según los campos del payload del evento (POST /custom_events o equivalente). No usa gramática de carrito (líneas, ticket, tienda).
Regla del
field: en cláusulaskey: "custom_event", elfieldsiempre esdata.+ nombre del atributo (p. ej.city→"field": "data.city",amount→"field": "data.amount"). El prefijodata.es obligatorio; no escribas soloamountocityenfield.
| Regla | Detalle |
|---|---|
| Campos | Cualquier atributo de la entidad custom, numérico o no. |
field | Siempre data.<nombre_atributo>. |
| Cláusula | key: "custom_event", field, operator (eq, gt, gte, …), value según tipo; opcional entity_attribute_key con el slug sin data.. |
| Sin condiciones | {"conditions":{"and":[]}} — la campaña aplica en todo evento de ese tipo (sigue haciendo falta cumplir audiencia, vigencia y límites). |
vs rule_application | Condiciones = elegibilidad (p. ej. amount > 100). Aplicación = qué campo numérico alimenta el efecto (p. ej. solo amount con exists). |
Ejemplo — ciudad del evento:
{
"conditions": {
"and": [
{
"and": [
{
"key": "custom_event",
"field": "data.city",
"value": "Montevideo",
"operator": "eq"
}
]
}
]
}
}
Ejemplo — importe mínimo (combinable con la aplicación sobre amount del apartado anterior):
{
"conditions": {
"and": [
{
"key": "custom_event",
"field": "data.amount",
"operator": "gt",
"value": 100,
"entity_attribute_key": "amount"
}
]
}
}
Ver también Reglas de acumulación y Aplicación en evento personalizado.
Qué hacen
Definen elegibilidad compleja para que la campaña pueda aplicar: combinan operadores lógicos (and, or) con datos del cliente, del carrito/ticket y de las líneas (productos, categorías, atributos, tienda, pago, totales).
Pregunta que responde al momento de evaluar: «¿Este cliente y este ticket cumplen para que la campaña de puntos entre en juego o la descarto?»
Dos formatos del mismo concepto
| Formato | Dónde suele aparecer | Estructura |
|---|---|---|
**conditions.and[] / conditions.or[]** | GET /points y GET /points/{id} → rule_conditions | Cláusulas tipadas con key, field, operator |
| Plano | Ejemplos POST /points en API de campañas | lines[], total_cart, country[], payment_method[] |
Prioriza el formato **conditions.and[]** al leer listados externos. Ambos expresan las mismas reglas con distinta serialización.
Estructura lógica (AND, OR y subgrupos)
conditions
└── and[] → TODAS las entradas del array deben cumplirse
├── { key, field, operator… } → cláusula suelta
└── { and: [ … ] } → subgrupo: TODAS las cláusulas internas deben cumplirse
También puede existir conditions.or[] (al menos una cláusula del grupo). En la práctica, las campañas complejas usan varios { "and": [ … ] } en el and raíz (por ejemplo, un bloque de condiciones de cliente + otro de líneas/tienda).
Cuando el nodo raíz de rule_conditions es conditions.or[] (no un subgrupo or anidado dentro de un and raíz), la lectura es:
conditions
└── or[] → AL MENOS UNA entrada del array debe cumplirse
├── { key, field, operator… } → cláusula suelta
└── { or: [ … ] } → subgrupo: AL MENOS UNA cláusula interna debe cumplirse
Interpretación del diagrama OR: basta con que una cláusula o subgrupo cumpla para que la campaña pueda aplicar. Solo si ninguna cumple, la campaña queda descartada. Un subgrupo { "or": [ … ] } se interpreta igual: al menos una cláusula interna debe pasar.
| Raíz | Regla | Si falla… |
|---|---|---|
conditions.and[] | Todas deben cumplir | Una sola falla → descartada |
conditions.or[] | Al menos una debe cumplir | Todas fallan → descartada |
Cómo identificar qué evalúa cada cláusula
| Campo JSON | Rol en interpretación del JSON |
|---|---|
**field** | Autoritativo. Indica qué dato se compara. Los value / values siempre se interpretan contra este campo. |
**key** | Solo informativo (etiqueta de la plataforma / Owner App). Puede ayudar a orientarse, pero no define qué se evalúa. Si key y field no coinciden en apariencia, manda **field**. |
**array_field** | Opcional. Indica dentro de qué lista del ticket se aplica el field. |
**operator** + **value** / **values** | Cómo y con qué umbral se compara el field. |
Sin array_field (dato a nivel ticket o customer)
El field apunta directamente al atributo evaluado.
Regla rápida de clasificación:
Prefijo / patrón del field | Familia |
|---|---|
Empieza por customer. | Condición de cliente |
country, total, original_total, total_cart_without_additional_costs, location_id, location_categories, attributes.* (sin customer.) | Condición de carrito / ticket / tienda |
field | Lectura |
|---|---|
customer.id | ID del customer (condición de cliente) |
country | País de la compra / transacción (condición de carrito, no de cliente) |
total | Total del carrito |
location_id | Tienda |
Con array_field (dato dentro de una lista del ticket)
La condición recorre cada elemento del array y evalúa el **field** dentro de ese contexto:
array_field | field | Significado |
|---|---|---|
lines | product_categories | Categorías de producto en las líneas del carrito |
lines | product_id | ID de producto en las líneas |
lines | attributes.color | Atributo de línea (dentro de lines[].attributes) |
payments | type | Campo **type** de cada entrada en el array de pagos (método de pago) |
Ejemplo mental: array_field: lines + field: product_categories + values: ["frutas|17852"] (feature_pk) → «¿Hay líneas con esa categoría de producto?».
Ejemplo: array_field: payments + field: type + values: ["Tarjeta OH!"] → «¿El ticket tiene un pago cuyo type coincide?».
Campos estructurales (cláusulas dentro de rule_conditions)
**bundle/grouped(flags) ≠rule_group(agrupación en el efecto).**
Los camposbundleygroupeden el JSON de condiciones/aplicación son serialización interna de Owner App: ignora su valor numérico al integrar el GET.
La mecánica de bundle / 2x1 / combo agrupado se lee con**rule_effects.rule_group: true** y las subcondiciones**quantity**en**rule_conditions**(tamaño del grupo) y**rule_application**(cuántas unidades del grupo reciben el efecto). Detalle: Mecánica bundle (rule_group).
| Campo | Descripción |
|---|---|
**field** | Campo evaluado (ruta del dato). Es la referencia principal para integraciones |
key | Etiqueta informativa de la plataforma; no sustituye a field |
operator | Comparación; depende del tipo de dato del field |
value | Valor único comparado contra field |
values | Lista comparada contra field (in, not_in, all_in, …) |
array_field | Si existe: lista del ticket donde se lee el field (lines, payments) |
bundle | Solo en **rule_conditions**: interno, ignorar valor al integrar |
grouped | Solo en **rule_conditions**: interno, ignorar valor al integrar |
conditions | Subcondiciones anidadas (típico en cláusulas con array_field: lines) |
payment_method_ids | IDs internos de método de pago (auxiliar; el criterio de negocio sigue siendo field: type + values) |
Operadores por tipo de dato
El operador válido depende del tipo del atributo o campo evaluado.
| Tipo | Operadores habituales | Ejemplo |
|---|---|---|
| Texto (string) | eq, neq, in, not_in, contains, starts_with, ends_with, not_contains | loyalty_tier = "silver"; referral_code contiene "77777" |
| Numérico | eq, neq, gt, gte, lt, lte, in,not_in | total > 40000; quantity >= 1 |
| Booleano | eq, neq | vip_status = true |
Fecha (string ISO YYYY-MM-DD) | eq, neq, gt, gte, lt, lte | customer.created_at >= "2023-10-27" |
| Lista en el customer | in, not_in, all_in | preferred_store_ids all_in [1,2,3,4] → todas esas tiendas deben estar en el atributo del customer |
Catálogo — condiciones de cliente
Usa **field** para identificar la condición. La columna key es solo referencia informativa.
Regla: las condiciones de cliente tienen
fieldque siempre empieza porcustomer.(ej.customer.id,customer.attributes.tags,customer.location.country).
Elfield: country(sin prefijo) es condición de carrito, no de cliente — véase catálogo de carrito.
field (evaluar este) | key (informativo) | Qué valida | Notas |
|---|---|---|---|
customer.id | customer_id | Mini-segmentación: lista explícita de clientes | operator: in con values de IDs separados por coma; máximo 500 IDs |
customer.created_at | customer_created_at | Fecha de registro del customer | Operadores de fecha |
customer.location.country | customer_registration_countries | País de la tienda de registro del customer | in / not_in |
customer.tier_achievements | tier | Tier(s) del programa | values = IDs de tier |
customer.attributes.nombre`` | client_attributes | Propiedad personalizada del customer | Operador según tipo del atributo |
customer.calculated_attributes.id`` | client_calculated_attributes | Atributo calculado (CDP / Loyalty Insights) | El id suele ser ca_número`` (ej. ca_125). Operador según tipo del atributo |
Ejemplos de customer.attributes (JSON maestro)
field | operator | Interpretación |
|---|---|---|
customer.attributes.tags | in | El customer tiene al menos uno de esos tags |
customer.attributes.interests | not_in | El customer no tiene esos intereses |
customer.attributes.vip_status | eq | Flag VIP (booleano) |
customer.attributes.loyalty_tier | eq | Tier textual (silver, …) |
customer.attributes.referral_code | contains | El código contiene el substring |
customer.attributes.customer_score | gt | Puntuación numérica mayor que el umbral |
customer.attributes.preferred_store_ids | all_in | Todas las tiendas listadas están en las preferidas del customer |
customer.attributes.preferred_communication | starts_with | Canal preferido empieza por el texto indicado |
customer.attributes.membership_start_date | lte | Fecha de inicio de membresía anterior o igual |
Ejemplos de customer.calculated_attributes (atributos calculados)
Los atributos calculados los define la Company en CDP (p. ej. recencia, frecuencia, ticket medio, contadores de compra). En el JSON aparecen como customer.calculated_attributes.ca_id, donde ca_id`` es el identificador interno del atributo (formato habitual: ca_125, ca_119).
Cláusula de ejemplo (JSON maestro):
{
"key": "client_calculated_attributes",
"field": "customer.calculated_attributes.ca_125",
"value": 12,
"operator": "neq"
}
{
"key": "client_calculated_attributes",
"field": "customer.calculated_attributes.ca_119",
"value": 122,
"operator": "gt"
}
field | operator | value / values | Interpretación |
|---|---|---|---|
customer.calculated_attributes.ca_125 | neq | 12 | El atributo calculado ca_125 del customer no es 12 (numérico) |
customer.calculated_attributes.ca_119 | gt | 122 | El atributo ca_119 es mayor que 122 |
customer.calculated_attributes.ca_50 | gte | 5 | Umbral mínimo (ej. “al menos 5 compras en 90 días” si así está definido ca_50) |
customer.calculated_attributes.ca_80 | in | ["gold","platinum"] | Valor categórico del atributo calculado está en la lista (si el CA es texto) |
customer.calculated_attributes.ca_200 | lte | "2024-06-01" | Comparación de fecha (si el CA es tipo fecha; ISO en value) |
customer.calculated_attributes.ca_30 | eq | true | Flag booleano del atributo calculado |
Cómo interpretar en integración:
- Identifica el
**field** completo:customer.calculated_attributes.ca_XXX. - Consulta en la Company qué significa
**ca_XXX**(nombre de negocio del atributo calculado en CDP / documentación de la Company). - Aplica el
**operator**y**value**/valuescomo en cualquier condición numérica, texto o fecha. - No confundir con
customer.attributes.*(propiedades configuradas del perfil) ni con atributos de línea/ticket.
Si el customer “debería” cumplir según CRM pero la campaña no aplica, verifica que el atributo calculado esté materializado para ese customer en el momento de la compra.
Catálogo — condiciones de carrito (ticket)
Condiciones sobre el ticket de compra. El field no empieza por customer. (salvo atributos del ticket bajo attributes.*).
field | array_field | key (informativo) | Qué valida |
|---|---|---|---|
country | — | country | País de la tienda de la compra / transacción. No confundir con customer.location.country (país de registro) |
total | — | total_cart | Total del carrito, compara campo 'total' del carrito |
total_cart_without_additional_costs | — | total_cart_without_additional_costs | Total derivado: original_total − suma de additional_costs (véase abajo) |
original_total | — | original_total | Total original del ticket (antes de descuentos de campaña en la evaluación) |
type | payments | payment | Método de pago: evalúa payments[].type contra values |
attributes.nombre`` | — | cart_attributes | Atributo del ticket (ej. attributes.customer_notes) |
Totales del carrito: total, original_total y total_cart_without_additional_costs
field | Qué compara la condición |
|---|---|
total | El total actual del ticket (total en el payload de compra). |
original_total | El total original del ticket (original_total), útil cuando no quieres que descuentos ya reflejados en total afecten el umbral de la condición. |
total_cart_without_additional_costs | Valor calculado por el motor a partir del ticket (no es un campo que envíe el integrador como umbral fijo). |
Cómo calcula el sistema total_cart_without_additional_costs:
Toma el original_total del ticket y le resta la suma de todos los valores dentro del objeto additional_costs:
total_cart_without_additional_costs = original_total − Σ (valores en additional_costs)
Ejemplo de ticket:
{
"original_total": 100.00,
"additional_costs": {
"cost1": 1.17,
"cost2": 2.99
}
}
Cálculo: 100.00 − (1.17 + 2.99) = 95.84
Si la campaña tiene:
{
"key": "total_cart_without_additional_costs",
"field": "total_cart_without_additional_costs",
"value": 90,
"operator": "gt"
}
→ 95.84 > 90 → cumple la condición (el umbral se evalúa sobre el total sin esos costes extra).
Interpretación:
- Revisa en el ticket
original_totaly el objetoadditional_costs(puede tener una o varias claves:cost1,cost2, envío, seguro, etc.). - No confundir con
total: ese es el total ya neto/distinto según lo que envíe la integración. - Si la condición no cuadra, suma manualmente los valores de
additional_costsy resta deoriginal_totalantes de comparar con elvaluede la campaña.
Catálogo — tienda (ubicación)
field | key (informativo) | Qué valida | Auxiliares |
|---|---|---|---|
location_id | location_id | Tienda(s) concreta(s) | values con IDs |
location_categories | location_categories | Categoría de tienda | values = lista de feature_pk (`taxonomy_slug |
Catálogo — condiciones en líneas
Siempre con **array_field: lines**. El **field** indica qué propiedad de cada línea se evalúa.
field | key (informativo) | Qué valida | Auxiliares |
|---|---|---|---|
product_categories | cart_item_product_category | Categorías de producto en la línea | values = lista de feature_pk (`taxonomy_slug |
product_id / product_code | cart_item_product / cart_product_id | Producto por ID en línea o catálogo | conditions[] |
attributes.nombre`` | cart_item_attributes | Atributo personalizado de línea | Ej. attributes.color, attributes.product_condition |
Subcondiciones en líneas (conditions[]) — en rule_conditions
En **rule_conditions**, las subcondiciones anidadas pueden usar **quantity** y **total** de línea.
En **rule_application**, las subcondiciones solo admiten quantity (no total). Ver rule_application.
field en subcondición | En rule_conditions | En rule_application |
|---|---|---|
quantity | Cantidad de ítems (gte, lte, …) | ✓ (única subcondición disponible) |
total | Importe de los ítems (suma) | No configurable |
Si la cláusula padre trae bundle o grouped, son campos internos — no usarlos al integrar (no confundir con rule_group del efecto).
Formato de values en location_categories y product_categories
Para **field: location_categories** (tienda) y **field: product_categories** (líneas con array_field: lines), cada entrada de values es un feature_pk:
taxonomy_slug|external_id
| Parte | Significado | Ejemplo |
|---|---|---|
taxonomy_slug | Slug de la taxonomía / categoría en el catálogo | angular_diez, tiendas_mate, frutas |
external_id | ID externo del feature en esa taxonomía | 64, 123111111, 17852 |
Ejemplos de values:
- Tienda:
["tiendas_mate|123111111"]confield: location_categories - Producto en línea:
["angular_diez|64", "frutas|17852"]conarray_field: lines,field: product_categories
Interpretación: compara la lista values del JSON con los feature_pk que trae el ticket o el catálogo de la Company. El campo auxiliar feature_ids (numéricos) es complementario; la condición de negocio se expresa en **values como feature_pk**, no solo por el slug legible.
Productos en líneas: cart_item_product vs cart_product_id
Siempre con array_field: lines. El **key** indica cómo se configuraron los productos en Owner App; el **field** indica si la Company trabaja con IDs o códigos de producto.
key (informativo) | Origen de los productos en la campaña |
|---|---|
cart_item_product | Selección desde el catálogo de la Company |
cart_product_id | Ingreso manual de IDs o códigos (sin catálogo) |
field | Contenido de values |
|---|---|
product_id | Lista de IDs numéricos de producto (ej. [1, 2, 3, 10045]) |
product_code | Lista de códigos/SKU de producto (ej. ["CC-33CL-LATA", "SKU-99"]) |
Ejemplo — catálogo (cart_item_product) + IDs:
{
"key": "cart_item_product",
"field": "product_id",
"array_field": "lines",
"operator": "in",
"values": [1, 2, 3],
"product_ids": ["1", "2", "3"]
}
Interpretación: la campaña exige líneas con productos del catálogo cuyos IDs están en values.
Ejemplo — catálogo + códigos:
{
"key": "cart_item_product",
"field": "product_code",
"array_field": "lines",
"operator": "in",
"values": ["CC-33CL-LATA", "AGUA-50CL"]
}
Ejemplo — manual sin catálogo (cart_product_id) + exclusión por ID:
{
"key": "cart_product_id",
"field": "product_id",
"array_field": "lines",
"operator": "not_in",
"values": [1, 5, 4]
}
Interpretación: productos escritos a mano en la regla; el ticket no debe llevar esos product_id en líneas (operador not_in en el ejemplo del JSON maestro).
Ejemplo — manual + códigos:
{
"key": "cart_product_id",
"field": "product_code",
"array_field": "lines",
"operator": "in",
"values": ["PROMO-2024", "OUTLET-X"]
}
Reglas rápidas:
- Mira
**field** (product_idvsproduct_code) para saber qué tipo de lista traevalues. - Mira
**key**para saber si la selección fue por catálogo (cart_item_product) o manual (cart_product_id).
Errores frecuentes al leer rule_conditions
| Confusión | Cómo resolverlo |
|---|---|
country vs customer.location.country | field: country = carrito (país de compra); field: customer.location.country = cliente (país de registro) |
Condición “de cliente” sin prefijo customer. | Si el field no empieza por customer., no es condición de cliente (ej. country es carrito) |
total vs original_total vs total_cart_without_additional_costs | total = campo del ticket; original_total = base sin descuentos de campaña; total_cart_without_additional_costs = original_total − sum(additional_costs) |
bundle / grouped (valor numérico) | Flags internos en JSON; ignorar valor. Con rule_group: true, sí leer **quantity** en subcondiciones |
| Bundle / 2x1 mal interpretado | Revisar trío: rule_conditions (qty grupo) + rule_application (qty con dto.) + rule_effects.rule_group + limits |
Confiar solo en key | El dato evaluado lo define **field** (+ array_field); key es informativo |
cart_item_product vs cart_product_id | Catálogo vs ingreso manual; mismo field/values (id o code), distinto origen de configuración |
Mezclar flags con rule_group | bundle/grouped en JSON ≠ activar agrupación; la agrupación la marca **rule_group: true** en el efecto |
| Operador incompatible con el tipo | Ej. contains en un campo numérico no tiene sentido; revisa definición del atributo |
| JSON sin parsear | Si rule_conditions llega como string, deserializar antes de leer conditions.and |
| Subgrupos anidados | Un fallo en un solo { "and": [ … ] } hace fallar toda la campaña aunque el resto del ticket parezca correcto |
Apéndice: mapa del JSON maestro (todas las opciones)
El siguiente JSON de referencia agrupa la mayoría las familias de condiciones soportadas en descuentos. Al leer una campaña real, identifica cada cláusula por su **field** (y array_field si existe); usa key solo como ayuda visual.
JSON maestro de referencia
{
"conditions": {
"and": [
{
"and": [
{ "key": "country", "field": "country", "values": ["ES", "IL", "AF"], "operator": "in" },
{ "key": "client_attributes", "field": "customer.attributes.tags", "values": ["657567"], "operator": "in" },
{ "key": "client_attributes", "field": "customer.attributes.interests", "values": ["electronics"], "operator": "not_in" },
{ "key": "client_attributes", "field": "customer.attributes.vip_status", "value": true, "operator": "eq" },
{ "key": "client_attributes", "field": "customer.attributes.loyalty_tier", "value": "silver", "operator": "eq" },
{ "key": "client_attributes", "field": "customer.attributes.referral_code", "value": "77777", "operator": "contains" },
{ "key": "client_attributes", "field": "customer.attributes.customer_score", "value": 676, "operator": "gt" },
{ "key": "client_attributes", "field": "customer.attributes.preferred_store_ids", "values": [1, 2, 3, 4], "operator": "all_in" },
{ "key": "client_attributes", "field": "customer.attributes.preferred_communication", "value": "push", "operator": "starts_with" },
{ "key": "client_attributes", "field": "customer.attributes.membership_start_date", "value": "2023-10-27", "operator": "lte" },
{ "key": "client_calculated_attributes", "field": "customer.calculated_attributes.ca_125", "value": 12, "operator": "neq" },
{ "key": "client_calculated_attributes", "field": "customer.calculated_attributes.ca_119", "value": 122, "operator": "gt" },
{ "key": "customer_created_at", "field": "customer.created_at", "value": "2023-10-27", "operator": "gte" },
{ "key": "customer_id", "field": "customer.id", "values": [1, 4, 5555, 67777, 88888, 99999], "operator": "in" },
{ "key": "tier", "field": "customer.tier_achievements", "values": [553, 190], "operator": "in" },
{ "key": "customer_registration_countries", "field": "customer.location.country", "values": ["ES", "UY"], "operator": "in" },
{ "key": "total_cart", "field": "total", "value": 40000, "operator": "gt" },
{ "key": "total_cart_without_additional_costs", "field": "total_cart_without_additional_costs", "value": 3500, "operator": "gt" },
{ "key": "original_total", "field": "original_total", "value": 6000, "operator": "gt" },
{ "key": "payment", "field": "type", "values": ["Tarjeta OH!", "Agora Pay Web"], "operator": "in", "array_field": "payments", "payment_method_ids": [95, 92] }
]
},
{
"and": [
{ "key": "location_categories", "field": "location_categories", "values": ["tiendas_mate|123111111"], "operator": "in", "location_ids": [208] },
{ "key": "location_id", "field": "location_id", "values": [4, 5, 3], "operator": "not_in" },
{ "key": "cart_attributes", "field": "attributes.customer_notes", "value": "testtt", "operator": "contains" },
{ "key": "cart_item_product_category", "field": "product_categories", "bundle": 2, "values": ["angular_diez|64", "0913|68"], "grouped": true, "operator": "in", "conditions": [{ "field": "quantity", "value": 1, "operator": "gte" }, { "field": "total", "value": 100, "operator": "gte" }], "array_field": "lines", "feature_ids": [17817, 17852] },
{ "key": "cart_item_product", "field": "product_id", "bundle": 1, "values": [1, 2, 3], "grouped": true, "operator": "in", "conditions": [{ "field": "quantity", "value": 1, "operator": "gte" }], "array_field": "lines", "product_ids": ["1", "2", "3"] },
{ "key": "cart_product_id", "field": "product_id", "bundle": 1, "values": [1, 5, 4], "grouped": true, "operator": "not_in", "conditions": [{ "field": "quantity", "value": 1, "operator": "gte" }], "array_field": "lines" },
{ "key": "cart_item_attributes", "field": "attributes.color", "value": "azuk", "operator": "neq", "array_field": "lines" },
{ "key": "cart_item_attributes", "field": "attributes.bundle_id", "values": ["1222"], "operator": "not_in", "array_field": "lines" }
]
}
]
}
}
Subgrupo 1 — cliente, carrito y pago (lectura rápida)
| # | field (referencia) | Lectura en una frase |
|---|---|---|
| 1 | country | Carrito: compra en ES, IL o AF (no es condición de cliente) |
| 2–10 | customer.attributes.* | Cliente: filtros por propiedades (tags, tier, VIP, score, …) |
| 11–12 | customer.calculated_attributes.ca_* | Cliente: atributos calculados ca_125, ca_119 |
| 13 | customer.created_at | Cliente: registrado desde el 2023-10-27 |
| 14 | customer.id | Cliente: solo esos IDs (mini-segmentación) |
| 15 | customer.tier_achievements | Cliente: tier 553 o 190 |
| 16 | customer.location.country | Cliente: alta en ES o UY (país de registro) |
| 17 | total | Carrito: total > 40000 |
| 18 | total_cart_without_additional_costs | Carrito: original_total − additional_costs > 3500 |
| 19 | original_total | Carrito: total original > 6000 |
| 20 | payments[].type | Carrito: pago Tarjeta OH! o Agora Pay Web (array_field: payments, field: type) |
Subgrupo 2 — tienda, carrito y líneas (lectura rápida)
| # | field / contexto | Lectura en una frase |
|---|---|---|
| 1 | location_categories | Tienda con feature_pk `tiendas_mate |
| 2 | location_id | Tienda no puede ser 4, 5 ni 3 |
| 3 | attributes.customer_notes | Notas del carrito contienen testtt |
| 4 | lines → product_categories | Categorías listadas, qty≥1 y total línea≥100 |
| 5–6 | lines → product_categories | Otras reglas de categoría con distintas subcondiciones de qty |
| 7 | lines → product_id, key cart_item_product | Catálogo: IDs 1–5 en values, qty≥1 |
| 8 | lines → product_id, key cart_product_id | Manual (sin catálogo): not_in IDs 1,5,4, qty≥1 |
| 9–11 | lines → attributes.* | Atributos de línea (color, bundle_id, condición producto) |
Siguiente: Aplicación (rule_application)