# Parámetros de plantillas Twilio — `getValueParams()`

Referencia para refactorización de `TwilioController::getValueParams()` (líneas 816–1413).

**Fuente:** `src/NvCarga/Bundle/Controller/TwilioController.php`

---

## 1. Reglas globales

### Valor predeterminado de tags de texto

- Cada tag inicia en `'N/A'`.
- Tras resolver el valor, si queda vacío/falsy (`''`, `null`, `false`, `0`, `"0"`) → se reemplaza por `'N/A'`.
- Excepción: `[COMENTARIOESTATUS]` asigna `'N/A'` explícitamente cuando no hay comentario.

### Mapeo a Twilio

| Concepto | Detalle |
|----------|---------|
| Tags de texto | Se mapean a claves numéricas extraídas del `tbody` de la plantilla (`{{1}}`, `{{2}}`, …) en el mismo orden que `template.getParameters()` |
| Imagen | Clave fija `'1'` (solo si `template.getImages()` es `true`) |
| PDF | Clave fija `'10'` (solo si `template.getPdfs()` es `true`) |

### Formato de fechas

- General: `maincompany.getFormatdate() + ' H:i:s'`
- `[FECHAAUX]`: solo `maincompany.getFormatdate()` (sin hora)

### Decimales

Pesos y volúmenes usan `round(valor, maincompany.getDecimals())`.

### Modo prueba (`templateID > 0`)

Fuerza imagen y PDF de fallback aunque existan archivos reales.

---

## 2. Catálogo general de tags

Tabla maestra con **todos** los tags soportados por `getValueParams()`.

| Tag | Origen / lógica | Entidades donde aplica | Default |
|-----|-----------------|------------------------|---------|
| `[FECHACREACION]` | `entity.getCreationdate()` formateada | Cualquiera con `getCreationdate()` | N/A |
| `[TIPOENVIO]` | Receipt/WHrec: `getShippingtype()` · Guide: `getShippingtype().getName()` | Receipt, WHrec, Guide | N/A |
| `[NUMEROCONSOLIDADO]` | `entity.getConsol().getNumber()` | Con `getConsol()` | N/A |
| `[CONSOLIDADOALTERNATIVO]` | `entity.getConsol().getName()` | Con `getConsol()` | N/A |
| `[NUMERORUTAPICKUP]` | `entity.getListpickup().getNumber()` | Solo Pickup (otros no tienen el método) | N/A |
| `[NUMERORUTADELIVERY]` | `entity.getDeliverylist().getNumber()` | Receipt, WHrec, Guide | N/A |
| `[PACKAGETRACKING]` | `entity.getTracking()` | Solo Receipt | N/A |
| `[PACKAGEWEIGHT]` | `round(entity.getWeight(), decimals)` | Solo Receipt | N/A |
| `[PACKAGEVOLUME]` | `round(entity.getVolume(), decimals)` | Solo Receipt | N/A |
| `[SHIPPERNAME]` | `shipper.name + ' ' + shipper.lastname` | Con `getShipper()` | N/A |
| `[CONSIGNEENAME]` | `receiver.name + ' ' + receiver.lastname` | Con `getReceiver()` | N/A |
| `[SHIPPERADDRESS]` | `shipper.adrdefault.address` | Con shipper y adrdefault | N/A |
| `[ELEMENTTYPE]` | Traducción según clase: Paquete / Guía / Warehouse / Factura / Pickup | Receipt, Guide, WHrec, Bill, Pickup | N/A |
| `[NOMBREEMPRESA]` | `maincompany.getName()` | Siempre (usuario logueado) | — |
| `[URLEMPRESA]` | `https://` + `maincompany.getHomepage()` | Siempre | — |
| `[NOMBREAGENCIA]` | `entity.getAgency().getName()` | Con `getAgency()` | N/A |
| `[NUMERO]` | Concatena `getNumber()` de `$list_entities` (máx. 50 chars) | Con `getNumber()` | N/A |
| `[NOMBREESTATUS]` | `completation` → traduce "Finalizado" · otro → `status.step.name` | Requiere `$status` o `action=completation` | N/A |
| `[FECHAESTATUS]` | `completation` → `entity.getDelidate()` · otro → `status.date` | Requiere `$status` o `action=completation` | N/A |
| `[CIUDADESTATUS]` | `status.place.name` | Requiere `$status` | N/A |
| `[COMENTARIOESTATUS]` | `status.comment` | Requiere `$status` | N/A |
| `[ENLACEFRIMA]` | WHrec → `whrec_signpublic` · Guide → `guide_signpublic` (id + pubtoken) | WHrec, Guide | N/A |
| `[CAMBIOTIPOENVIO]` | WHrec → `whrec_instruction` (id + pubtoken) | Solo WHrec | N/A |
| `[LINKPAGO]` | Stripe o Square activo → URL pública de pago (id + tokenpublic) | Solo Bill | N/A |
| `[ENLACETRACKING]` | `https://{homepage}/tracking/tracking` | Siempre | — |
| `[ENLACEPICKUP]` | `https://{homepage}/pickup/public/new_public` | Siempre | — |
| `[DELIVERYDATE]` | `entity.getDelidate()` formateada | Con `getDelidate()` | N/A |
| `[DELIVERYCOMMENT]` | `entity.getDelicomment()` | Con `getDelicomment()` | N/A |
| `[PDF_URL]` | URL absoluta `pdf_public` (table, id, pubtoken; genera token si falta) | No Pickup; requiere `getPubtoken()` | N/A |
| `[NOMBREDESTINATARIO]` | `receiver.name + lastname` | Con receiver | N/A |
| `[DIRECCIONDESTINATARIO]` | `receiver.address` | Con receiver | N/A |
| `[CASILLERODESTINATARIO]` | `receiver.customer.pobox.number` | Con receiver y pobox | N/A |
| `[MOVILDESTINATARIO]` | `receiver.mobile` | Con receiver | N/A |
| `[PAISDESTINATARIO]` | `receiver.city.state.country.name` | Con receiver | N/A |
| `[ESTADODESTINATARIO]` | `receiver.city.state.name` | Con receiver | N/A |
| `[DOCIDDESTINATARIO]` | `receiver.docid` | Con receiver | N/A |
| `[NOMBREREMITENTE]` | `shipper.name + lastname` | Con shipper | N/A |
| `[DIRECCIONREMITENTE]` | `shipper.adrdefault.address` | Con shipper | N/A |
| `[CASILLEROREMITENTE]` | `shipper.pobox.number` | Con shipper | N/A |
| `[MOVILREMITENTE]` | `shipper.adrdefault.mobile` | Con shipper | N/A |
| `[PAISREMITENTE]` | `shipper.adrdefault.city.state.country.name` | Con shipper | N/A |
| `[ESTADOREMITENTE]` | `shipper.adrdefault.city.state.name` | Con shipper | N/A |
| `[DOCIDREMITENTE]` | `shipper.adrdefault.docid` | Con shipper | N/A |
| `[DIRECCIONAGENCIA]` | `agency.address` | Con agency | N/A |
| `[CIUDADAGENCIA]` | `agency.city.name` | Con agency | N/A |
| `[TELEFONOAGENCIA]` | `agency.phone` | Con agency | N/A |
| `[EMAILAGENCIA]` | `agency.email` | Con agency | N/A |
| `[NOTAWR]` | `entity.getNote()` | Solo WHrec | N/A |
| `[REFERENCIAWR]` | `entity.getAux()` | Solo WHrec | N/A |
| `[MONTOFACTURA]` | `number_format(entity.getTotal(), 2, '.', '')` | Solo Bill | N/A |
| `[MONTOPENDIENTE]` | `number_format(total - paid, 2, '.', '')` | Solo Bill | N/A |
| `[MONTOPAGADO]` | `number_format(entity.getPaid(), 2, '.', '')` | Solo Bill | N/A |
| `[FECHAFACTURA]` | `entity.getCreationdate()` formateada | Solo Bill | N/A |
| `[STATUSFACTURA]` | `entity.getStatus()` | Solo Bill | N/A |
| `[DOCID]` | `entity.getAdrdefault().getDocid()` | Customer (y entidades con adrdefault) | N/A |
| `[AUXDATE]` | `entity.getAuxdate()` con hora | WHrec, Guide, Customer | N/A |
| `[CUSTYPE]` | `entity.getCustype()` | Solo Customer | N/A |
| `[LOCATION]` | `entity.getLocation().getCode()` | WHrec, Guide, Receipt, Customer | N/A |
| `[NOMBREAGENTE]` | `entity.getAgent().getComplete()` | Con `getAgent()` | N/A |
| `[NOMBRECLIENTE]` | `entity.getName()` | Solo Customer | N/A |
| `[APELLIDOCLIENTE]` | `entity.getLastname()` | Solo Customer | N/A |
| `[DIRECCIONCLIENTE]` | `entity.getAdrdefault().getAddress()` | Solo Customer | N/A |
| `[CIUDADCLIENTE]` | `adrdefault.city.name` | Solo Customer | N/A |
| `[ESTADOCLIENTE]` | `adrdefault.city.state.name` | Solo Customer | N/A |
| `[PAISCLIENTE]` | `adrdefault.city.state.country.name` | Solo Customer | N/A |
| `[EMAILCLIENTE]` | `entity.getEmail()` | Solo Customer | N/A |
| `[MOVILCLIENTE]` | `adrdefault.mobile` | Solo Customer | N/A |
| `[TELEFONOCLIENTE]` | `adrdefault.phone` | Solo Customer | N/A |
| `[CASILLEROCLIENTE]` | `entity.getPobox().getNumber()` | Solo Customer | N/A |
| `[FECHAAUX]` | `entity.getAuxdate()` solo fecha | WHrec, Guide, Customer | N/A |
| `[TOTALPACK]` | `entity.getNpack()` | WHrec, Guide, Receipt | N/A |
| `[TOTALWEIGHT]` | `round(entity.getWeight(), decimals)` | WHrec, Guide, Receipt | N/A |
| `[TOTALVOLUME]` | `round(entity.getVolume(), decimals)` | WHrec, Guide, Receipt | N/A |
| `[TOTALPVOL]` | `round(entity.getVolweight(), decimals)` | WHrec, Guide, Receipt | N/A |
| `[TARIFFWEIGHT]` | `round(entity.getPTariff(), decimals)` | WHrec, Guide, Receipt | N/A |
| `[SHIPPERCITY]` | `shipper.getCityname()` | Con shipper | N/A |
| `[CONSIGNEECITY]` | `receiver.getCityname()` | Con receiver | N/A |
| `[LINKPOBOXLOGIN]` | `https://{entity.maincompany.homepage}/login` | Con `getMaincompany()` | N/A |
| `[LINKPOBOXNEW]` | `https://{entity.maincompany.homepage}/pobox/new_public` | Con `getMaincompany()` | N/A |

---

## 3. Parámetros multimedia (imagen y PDF)

### Imagen — clave `'1'`

Condición: `template.getImages() === true`.

| Acción | Origen primario | Ruta |
|--------|-----------------|------|
| `new_guide`, `new_warehouse` | Primera de `entity.getImagepacks()` | `storage/{acronym}/images/{file}` |
| `new_package`, `new_pickup` | `entity.getImage()` | `storage/{acronym}/images/{image}` |
| `completation` | `entity.getEndimage()` | `storage/{acronym}/endimages/{endimage}` |
| Resto de acciones | Sin case en el switch | — |

**Fallback** (sin imagen primaria **o** `templateID > 0`):

1. `logosmain/{agency.whatsappImage}`
2. `logosmain/{maincompany.whatsappImage}`
3. `logosmain/no-image.png`

### PDF — clave `'10'`

Condición: `template.getPdfs() === true`.

Estado inicial: `{ pdf: false, respond: 'tmp/no-pdf.pdf' }`.

| Acción | Generación |
|--------|------------|
| `new_guide` | `formatservices.pdfcreate('Guide', entity)` |
| `new_warehouse` | `formatservices.pdfcreate('WHrec', entity)` |
| `new_invoice` | `formatservices.pdfcreate('Bill', entity)` |
| `new_package` | `formatservices.pdfcreate('Receipt', entity)` |
| `new_pickup` | `formatservices.pdfcreate('Pickup', entity)` |
| `new_qinvoice` | `formatservices.pdfcreate('Qinvoice', entity)` |
| Resto de acciones | No genera PDF |

**Fallback** (`pdf === false` **o** `templateID > 0`): copia `documents/no-pdf.pdf` → `tmp/no-pdf.pdf`.

---

## 4. WHrec (Warehouse)

| Campo | Valor |
|-------|-------|
| Entidad | `NvCarga\Bundle\Entity\WHrec` |
| Acciones | `new_warehouse`, `status_change`, `completation` |
| Invocación | WHrecController — creación, cambio de estatus (vía StatusController), finalización |

### 4.1 Tags comunes (las 3 acciones)

Misma lógica independiente de la acción. Si el dato no existe → `N/A`.

| Tag | Origen en WHrec |
|-----|-----------------|
| `[FECHACREACION]` | `getCreationdate()` |
| `[TIPOENVIO]` | `getShippingtype()` |
| `[NUMEROCONSOLIDADO]` | `getConsol().getNumber()` |
| `[CONSOLIDADOALTERNATIVO]` | `getConsol().getName()` |
| `[NUMERORUTADELIVERY]` | `getDeliverylist().getNumber()` |
| `[SHIPPERNAME]` / `[CONSIGNEENAME]` | shipper / receiver |
| `[SHIPPERADDRESS]` | shipper.adrdefault.address |
| `[ELEMENTTYPE]` | `"Warehouse"` (traducido) |
| `[NOMBREEMPRESA]` / `[URLEMPRESA]` | maincompany |
| `[NOMBREAGENCIA]` | agency.name |
| `[NUMERO]` | `getNumber()` |
| `[ENLACEFRIMA]` | URL `whrec_signpublic` |
| `[CAMBIOTIPOENVIO]` | URL `whrec_instruction` |
| `[ENLACETRACKING]` / `[ENLACEPICKUP]` | URLs fijas homepage |
| `[DELIVERYDATE]` | `getDelidate()` |
| `[DELIVERYCOMMENT]` | `getDelicomment()` |
| `[PDF_URL]` | URL `pdf_public` (table=WHrec) |
| Tags destinatario / remitente / agencia | vía receiver, shipper, agency |
| `[NOTAWR]` | `getNote()` |
| `[REFERENCIAWR]` | `getAux()` |
| `[AUXDATE]` / `[FECHAAUX]` | `getAuxdate()` |
| `[LOCATION]` | `getLocation().getCode()` |
| `[NOMBREAGENTE]` | `getAgent().getComplete()` |
| `[TOTALPACK]` … `[TARIFFWEIGHT]` | npack, weight, volume, volweight, pTariff |
| `[SHIPPERCITY]` / `[CONSIGNEECITY]` | cityname |
| `[LINKPOBOXLOGIN]` / `[LINKPOBOXNEW]` | URLs maincompany |

**No aplican en WHrec** (siempre N/A): `[PACKAGETRACKING]`, `[PACKAGEWEIGHT]`, `[PACKAGEVOLUME]`, `[NUMERORUTAPICKUP]`, tags factura, tags cliente, `[DOCID]`, `[CUSTYPE]`, `[LINKPAGO]`.

### 4.2 Solo `new_warehouse`

| Parámetro | Comportamiento |
|-----------|----------------|
| Imagen `'1'` | Primera de `getImagepacks()` → `storage/{acronym}/images/{file}` |
| PDF `'10'` | `pdfcreate('WHrec', entity)` |
| Tags exclusivos | Ninguno adicional de texto; los de creación comparten tabla común |

### 4.3 Solo `status_change`

Requiere objeto `$status` pasado a `getValueParams()`.

| Tag | Origen |
|-----|--------|
| `[NOMBREESTATUS]` | `status.step.name` |
| `[FECHAESTATUS]` | `status.date` formateada |
| `[CIUDADESTATUS]` | `status.place.name` |
| `[COMENTARIOESTATUS]` | `status.comment` o N/A |

| Parámetro | Comportamiento |
|-----------|----------------|
| Imagen `'1'` | Sin case → solo fallback (logo agencia / empresa / no-image.png) |
| PDF `'10'` | Sin case → `tmp/no-pdf.pdf` |

### 4.4 Solo `completation`

| Tag | Origen (distinto a status_change) |
|-----|-----------------------------------|
| `[NOMBREESTATUS]` | Traducción fija: `"Finalizado"` |
| `[FECHAESTATUS]` | `entity.getDelidate()` (no usa status.date) |
| `[CIUDADESTATUS]` | `status.place.name` (si hay status) |
| `[COMENTARIOESTATUS]` | `status.comment` (si hay status) |

| Parámetro | Comportamiento |
|-----------|----------------|
| Imagen `'1'` | `getEndimage()` → `storage/{acronym}/endimages/{file}` |
| PDF `'10'` | Sin case → `tmp/no-pdf.pdf` |

---

## 5. Receipt (Paquete)

| Campo | Valor |
|-------|-------|
| Entidad | `NvCarga\Bundle\Entity\Receipt` |
| Acciones | `new_package`, `status_change`, `completation` |
| Invocación | ReceiptController, UtilsController, StatusController |

### 5.1 Tags comunes (las 3 acciones)

| Tag | Origen en Receipt |
|-----|-------------------|
| `[FECHACREACION]` | `getCreationdate()` |
| `[TIPOENVIO]` | `getShippingtype()` |
| `[NUMEROCONSOLIDADO]` / `[CONSOLIDADOALTERNATIVO]` | consol |
| `[NUMERORUTADELIVERY]` | `getDeliverylist().getNumber()` |
| `[PACKAGETRACKING]` | `getTracking()` |
| `[PACKAGEWEIGHT]` | `getWeight()` redondeado |
| `[PACKAGEVOLUME]` | `getVolume()` redondeado |
| `[SHIPPERNAME]` … remitente/destinatario | shipper / receiver |
| `[ELEMENTTYPE]` | `"Paquete"` (traducido) |
| `[NOMBREEMPRESA]` / `[URLEMPRESA]` | maincompany |
| `[NOMBREAGENCIA]` / tags agencia | agency |
| `[NUMERO]` | `getNumber()` |
| `[ENLACETRACKING]` / `[ENLACEPICKUP]` | URLs fijas |
| `[DELIVERYDATE]` / `[DELIVERYCOMMENT]` | delidate / delicomment |
| `[PDF_URL]` | URL `pdf_public` (table=Receipt) |
| `[LOCATION]` / `[NOMBREAGENTE]` | location / agent |
| `[TOTALPACK]` … `[TARIFFWEIGHT]` | npack, weight, volume, volweight, pTariff |
| `[SHIPPERCITY]` / `[CONSIGNEECITY]` | cityname |
| `[LINKPOBOXLOGIN]` / `[LINKPOBOXNEW]` | URLs maincompany |

**No aplican en Receipt:** `[ENLACEFRIMA]`, `[CAMBIOTIPOENVIO]`, `[NOTAWR]`, `[REFERENCIAWR]`, tags factura, tags cliente, `[AUXDATE]`, `[FECHAAUX]`, `[DOCID]`, `[CUSTYPE]`, `[LINKPAGO]`, `[NUMERORUTAPICKUP]`.

### 5.2 Solo `new_package`

| Parámetro | Comportamiento |
|-----------|----------------|
| Imagen `'1'` | `getImage()` → `storage/{acronym}/images/{image}` |
| PDF `'10'` | `pdfcreate('Receipt', entity)` |

### 5.3 Solo `status_change`

| Tag | Origen |
|-----|--------|
| `[NOMBREESTATUS]` | `status.step.name` |
| `[FECHAESTATUS]` | `status.date` |
| `[CIUDADESTATUS]` | `status.place.name` |
| `[COMENTARIOESTATUS]` | `status.comment` |

| Parámetro | Comportamiento |
|-----------|----------------|
| Imagen `'1'` | Solo fallback |
| PDF `'10'` | `tmp/no-pdf.pdf` |

### 5.4 Solo `completation`

| Tag | Origen |
|-----|--------|
| `[NOMBREESTATUS]` | `"Finalizado"` |
| `[FECHAESTATUS]` | `getDelidate()` |
| `[CIUDADESTATUS]` | `status.place.name` |
| `[COMENTARIOESTATUS]` | `status.comment` |

| Parámetro | Comportamiento |
|-----------|----------------|
| Imagen `'1'` | `getEndimage()` → `storage/{acronym}/endimages/{file}` |
| PDF `'10'` | `tmp/no-pdf.pdf` |

---

## 6. Guide (Guía)

| Campo | Valor |
|-------|-------|
| Entidad | `NvCarga\Bundle\Entity\Guide` |
| Acciones | `new_guide`, `status_change`, `completation` |
| Invocación | GuideController, StatusController |

### 6.1 Tags comunes (las 3 acciones)

| Tag | Origen en Guide |
|-----|-----------------|
| `[FECHACREACION]` | `getCreationdate()` |
| `[TIPOENVIO]` | `getShippingtype().getName()` |
| `[NUMEROCONSOLIDADO]` / `[CONSOLIDADOALTERNATIVO]` | consol |
| `[NUMERORUTADELIVERY]` | `getDeliverylist().getNumber()` |
| `[SHIPPERNAME]` … remitente/destinatario | shipper / receiver |
| `[ELEMENTTYPE]` | `"Guía"` (traducido) |
| `[NOMBREEMPRESA]` / `[URLEMPRESA]` | maincompany |
| `[NOMBREAGENCIA]` / tags agencia | agency |
| `[NUMERO]` | `getNumber()` |
| `[ENLACEFRIMA]` | URL `guide_signpublic` |
| `[ENLACETRACKING]` / `[ENLACEPICKUP]` | URLs fijas |
| `[DELIVERYDATE]` / `[DELIVERYCOMMENT]` | delidate / delicomment |
| `[PDF_URL]` | URL `pdf_public` (table=Guide) |
| `[AUXDATE]` / `[FECHAAUX]` | `getAuxdate()` |
| `[LOCATION]` / `[NOMBREAGENTE]` | location / agent |
| `[TOTALPACK]` … `[TARIFFWEIGHT]` | npack, weight, volume, volweight, pTariff |
| `[SHIPPERCITY]` / `[CONSIGNEECITY]` | cityname |
| `[LINKPOBOXLOGIN]` / `[LINKPOBOXNEW]` | URLs maincompany |

**No aplican en Guide:** tags paquete individual, `[CAMBIOTIPOENVIO]`, `[NOTAWR]`, `[REFERENCIAWR]`, tags factura, tags cliente, `[DOCID]`, `[CUSTYPE]`, `[LINKPAGO]`, `[NUMERORUTAPICKUP]`.

### 6.2 Solo `new_guide`

| Parámetro | Comportamiento |
|-----------|----------------|
| Imagen `'1'` | Primera de `getImagepacks()` |
| PDF `'10'` | `pdfcreate('Guide', entity)` |

### 6.3 Solo `status_change`

Igual estructura que WHrec §4.3 (tags de status + fallback imagen/PDF).

### 6.4 Solo `completation`

Igual estructura que WHrec §4.4 (Finalizado, delidate, endimage).

---

## 7. Bill (Factura / Invoice)

| Campo | Valor |
|-------|-------|
| Entidad | `NvCarga\Bundle\Entity\Bill` |
| Acciones | `new_invoice` |
| Invocación | BillController, WHrecController, GuideController |

### 7.1 Tags comunes (`new_invoice`)

| Tag | Origen en Bill |
|-----|----------------|
| `[FECHACREACION]` / `[FECHAFACTURA]` | `getCreationdate()` |
| `[ELEMENTTYPE]` | `"Factura"` (traducido) |
| `[NOMBREEMPRESA]` / `[URLEMPRESA]` | maincompany |
| `[NOMBREAGENCIA]` / tags agencia | agency |
| `[NUMERO]` | `getNumber()` |
| `[LINKPAGO]` | Stripe o Square (id + tokenpublic) |
| `[ENLACETRACKING]` / `[ENLACEPICKUP]` | URLs fijas |
| `[MONTOFACTURA]` | `getTotal()` formateado |
| `[MONTOPENDIENTE]` | `total - paid` |
| `[MONTOPAGADO]` | `getPaid()` |
| `[STATUSFACTURA]` | `getStatus()` |
| `[NOMBREAGENTE]` | `getAgent().getComplete()` |

**No aplican en Bill:** shipper/receiver, consolidado, delivery, tags paquete, tags status, tags cliente, pesos/volúmenes, `[ENLACEFRIMA]`, `[CAMBIOTIPOENVIO]`, `[PDF_URL]` (Bill no tiene `getPubtoken()` — riesgo de error si se usa el tag).

### 7.2 Solo `new_invoice` — multimedia

| Parámetro | Comportamiento |
|-----------|----------------|
| Imagen `'1'` | Sin case → solo fallback |
| PDF `'10'` | `pdfcreate('Bill', entity)` |

---

## 8. Customer (Cliente)

| Campo | Valor |
|-------|-------|
| Entidad | `NvCarga\Bundle\Entity\Customer` |
| Acciones | `new_customer` |
| Invocación | CustomerController (con `selector = custype`) |

### 8.1 Tags comunes (`new_customer`)

| Tag | Origen en Customer |
|-----|-------------------|
| `[FECHACREACION]` | `getCreationdate()` |
| `[NOMBREEMPRESA]` / `[URLEMPRESA]` | maincompany (usuario logueado) |
| `[NOMBREAGENCIA]` / tags agencia | agency |
| `[NUMERO]` | `getNumber()` |
| `[DOCID]` | `adrdefault.docid` |
| `[AUXDATE]` / `[FECHAAUX]` | `getAuxdate()` |
| `[CUSTYPE]` | `getCustype()` |
| `[LOCATION]` | `getLocation().getCode()` |
| `[NOMBREAGENTE]` | `getAgent().getComplete()` |
| `[NOMBRECLIENTE]` / `[APELLIDOCLIENTE]` | name / lastname |
| `[DIRECCIONCLIENTE]` … `[CASILLEROCLIENTE]` | adrdefault, pobox |
| `[EMAILCLIENTE]` | `getEmail()` |
| `[LINKPOBOXLOGIN]` / `[LINKPOBOXNEW]` | URLs maincompany del customer |

**No aplican en Customer:** shipper/receiver, consolidado, delivery, tags paquete/guía/warehouse, tags factura, tags status, `[ELEMENTTYPE]` (no hay case), `[LINKPAGO]`, `[PDF_URL]` (sin pubtoken).

### 8.2 Solo `new_customer` — multimedia

| Parámetro | Comportamiento |
|-----------|----------------|
| Imagen `'1'` | Sin case → solo fallback |
| PDF `'10'` | Sin case → `tmp/no-pdf.pdf` |

---

## 9. Matriz acción × multimedia

Referencia rápida de qué genera imagen/PDF real por acción (sin contar fallback).

| Acción | Entidad típica | Imagen primaria | PDF generado |
|--------|----------------|-----------------|--------------|
| `new_warehouse` | WHrec | imagepacks | WHrec |
| `new_guide` | Guide | imagepacks | Guide |
| `new_package` | Receipt | entity.image | Receipt |
| `new_invoice` | Bill | — | Bill |
| `new_customer` | Customer | — | — |
| `status_change` | WHrec / Guide / Receipt | — | — |
| `completation` | WHrec / Guide / Receipt | endimage | — |

---

## 10. Matriz acción × tags de estatus

| Tag | `status_change` | `completation` |
|-----|-----------------|----------------|
| `[NOMBREESTATUS]` | `status.step.name` | `"Finalizado"` |
| `[FECHAESTATUS]` | `status.date` | `entity.getDelidate()` |
| `[CIUDADESTATUS]` | `status.place.name` | `status.place.name` |
| `[COMENTARIOESTATUS]` | `status.comment` | `status.comment` |

En acciones de creación (`new_*`) estos tags devuelven `N/A` salvo que se pase un `$status` (no ocurre en el flujo actual).

---

## 11. Notas para refactorización

1. **`[NOMBREAGENCIA]` duplicado** en el switch (misma lógica dos veces).
2. **Valores `"0"`** en pesos/cantidades pueden convertirse en `N/A` por el check `if (!$name)`.
3. **`[PDF_URL]` vs PDF adjunto (`'10'`)** son mecanismos distintos.
4. **Bill y Customer** no tienen `getPubtoken()`; evitar `[PDF_URL]` en sus plantillas.
5. **`templateID > 0`** fuerza siempre imagen y PDF de prueba.
6. **`status_change`** puede enviar `$entity` como array (`$list_entities`) para concatenar `[NUMERO]`.
