82f9fa5d25
Preparación para la sesión del 21-ago. Todo solo lectura + dry-run. FAC-106 (creado por Pedro el 20-ago, asignado a Araceli) trae el formulario nuevo con request type "Cotización Bind". Servicio/Producto, Cantidad, IVA y Cliente ya son campos estructurados: el hueco de conceptos/partidas que bloqueaba B7 queda resuelto en el origen. Diagnóstico del 500 del 12-ago, leyendo 4 cotizaciones reales de BIND: - VATRate va como fracción (0.16), no como 16 - el VAT de partida es un MONTO, no una tasa (Price*Qty*0.16) - cada cotización usa un PriceListID distinto y ninguno coincide con el único que devuelve GET /api/PriceLists; conviene omitirlo Dry-run corregido ejecutado (operación #18); el body queda en el informe. Tres preguntas nuevas para la sesión: Empresa origen tiene 3 valores y hay un solo token; el combo IVA no ofrece 0% aunque hay clientes de exportación; y "Servicio de Enlace" existe 5 veces en BIND con unidad, unidad SAT y ChargeVAT distintos, sin mapeo definido. Bind:Mode está en Write fuera de sesión — hay que regresarlo a ReadOnly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
109 lines
7.8 KiB
Markdown
109 lines
7.8 KiB
Markdown
# Sondeo de `FAC-106` y payload de cotización — 20-ago-2026, noche
|
||
|
||
Preparación para la sesión del **viernes 21-ago, 7:00 am**. Todo lo de aquí es **solo lectura**: sondeo del ticket por API de Jira, lectura de catálogos de BIND y **dry-run** del endpoint de emisión (ninguna escritura). Ver [REGISTRO #65](../bitacora/REGISTRO.md) (la sesión del 12-ago que terminó en 500) y [#67](../bitacora/REGISTRO.md).
|
||
|
||
---
|
||
|
||
## 1 · `FAC-106` — el formulario nuevo existe y es mucho mejor de lo esperado
|
||
|
||
Creado por **Pedro** el 20-ago 4:12 pm, asignado a **Araceli**. Request type nuevo: **`Cotización Bind`** (id 1196, portal 35). Estatus `Open` (⚠️ **no** `En proceso de facturación`: mañana el disparo es manual, como estaba previsto).
|
||
|
||
| Campo | ID | Tipo | Valor en FAC-106 |
|
||
|---|---|---|---|
|
||
| Empresa origen | `customfield_11423` | select | **Balam** |
|
||
| Cliente | `customfield_11598` | **select** | **CEMEX** |
|
||
| Servicio/Producto | `customfield_11599` | **select** | **Servicio de Enlace** |
|
||
| Cantidad | `customfield_11600` | number | **1.0** |
|
||
| Monto sin IVA | `customfield_11556` | number | **1234.0** |
|
||
| IVA | `customfield_11601` | select | **16%** |
|
||
| Tipo de Moneda | `customfield_10053` | select | **MXN** |
|
||
| Fecha de vencimiento | `customfield_11597` | date | **2026-08-27** |
|
||
|
||
⭐ **El hueco de conceptos/partidas quedó resuelto.** `Servicio/Producto` + `Cantidad` + `IVA` son campos estructurados: ya hay con qué armar una partida sin parsear texto ni adjuntos.
|
||
|
||
⭐ **`Cliente` dejó de ser ADF y ahora es combo** con **17 opciones** que corresponden a los clientes de BIND: ACUNTIA S.A.U. · ATC CONSOLIDADOS · BANCA AFIRME · CEMEX · DEACERO · FRISA FORJADOS · (persona física) · HELMSTONE · IAMCFORWARDER · PLAN CREDI · Público en General · REGIOTURK · SERVICIOS COMPARTIDOS TSM · SERVICIOS LOGISTICOS DYLO · TRANSPORTES LOGISTICOS ESPECIALIZADOS · TRASLADOS Y LOGISTICA ESPECIALIZADA · VictTec LLC.
|
||
|
||
⭐ **Las 17 categorías de servicio de Pedro, confirmadas** en `Servicio/Producto`: Consultoría y Administración Corporativa · Servicios Profesionales Generales · Gestión de Proyectos Senior / PMO · Gestión de Mesa de Servicio (SDM) · Soporte Especializado L1 · Soporte Especializado L2 · Gestión de Incidentes · Gestión de Cambios · Gestión de Capacidad · Mesa de Ayuda / Service Desk · Desarrollo de Software · Reclutamiento (Headhunting) · Servicio de Enlace · Horas Extraordinarias · Viáticos · Licencias y Software · Liquidaciones y Finiquitos.
|
||
|
||
### Pendientes que deja el formulario
|
||
|
||
- 🔴 **`Empresa origen` tiene 3 valores: Balam, RegioTurk y Helmstone.** ¿La cotización se emite siempre en la misma cuenta de BIND, o hay una por empresa? El token actual es uno solo. **Preguntarlo mañana.**
|
||
- 🔴 **`IVA` solo ofrece `16%`.** No hay `0%` — y hay clientes de exportación en el combo (ACUNTIA S.A.U., VictTec LLC, IAMCFORWARDER). El Discovery registró **IVA 16%/0%**. Además, en BIND existe al menos una cotización real con `VAT = 0` pese a `VATRate = 0.16`. **Falta la opción 0%.**
|
||
- ⚠️ **Sobrevive `Nombre del cliente` (`customfield_11596`, texto libre)** además del combo `11598`. Dos campos de cliente en el mismo sitio: hay que fijar por escrito que **manda el combo**.
|
||
- ⚠️ **`customfield_10202`, el campo de cliente que la plataforma leía, ya no aplica.** Era la causa de que el 12-ago *"el cliente no se detectó"*. **Corregido** en `appsettings.Development.json` → `customfield_11598`.
|
||
|
||
---
|
||
|
||
## 2 · El catálogo de BIND está peor de lo que se vio en la sesión
|
||
|
||
`GET /api/Services` devuelve **67 servicios**; `GET /api/Products`, **3 productos**. Buscando el que trae el ticket:
|
||
|
||
**"SERVICIO DE ENLACE" existe 5 veces**, con IDs distintos y **atributos fiscales que no coinciden entre sí**:
|
||
|
||
| Code | Unit | SATUnit | ChargeVAT |
|
||
|---|---|---|---|
|
||
| `81111500` | *(vacío)* | 3984 | **true** |
|
||
| `Código - 00000` | E48 | 4376 | false |
|
||
| `Código - 00000` | E48 | 4376 | false |
|
||
| `Código - 00000` | Servicio | 4376 | false |
|
||
| `027` | E48 | 3984 | false |
|
||
|
||
> 🔴 **Riesgo directo para mañana:** el combo de Jira manda **una etiqueta**, "Servicio de Enlace", y en BIND hay **cinco filas** que difieren en unidad, unidad SAT e incluso en si cobran IVA. **La correspondencia etiqueta → ítem de BIND es ambigua y nadie la ha definido.** Es la segunda mitad de la depuración que Araceli pidió el 12-ago: se depuró el combo de Jira, **falta depurar BIND y fijar el mapeo**.
|
||
|
||
---
|
||
|
||
## 3 · Los tres errores que explican el 500 del 12-ago
|
||
|
||
Verificado leyendo **4 cotizaciones reales** de BIND (folios 1001, 1005, 1012, 1021):
|
||
|
||
1. 🔴 **`VATRate` va como fracción, no como porcentaje.** Todas las cotizaciones reales traen **`VATRate = 0.16`**. Mandar `16` es un factor de 100 de diferencia.
|
||
2. 🔴 **`VAT` de partida es un MONTO, no una tasa.** Comprobado en 3 de 4: `Price × Qty × 0.16 = VAT` (p. ej. 32,422.04 → 5,187.5264). El endpoint **pasa el valor tal cual**, así que quien llame tiene que calcularlo. Para FAC-106: 1234 × 1 × 0.16 = **197.44**.
|
||
3. 🟠 **`PriceListID`: cada cotización real usa una lista distinta** (`041d4514…`, `0c4bb05e…`, `0dfbe083…`, `1087dac9…`) y **ninguna coincide** con la única que devuelve `GET /api/PriceLists` (`03e4bb2d…`, "A"). Mandar la lista equivocada es candidato serio al 500. **Recomendación: omitirlo** y dejar que BIND aplique su default — el cliente ya omite los nulos.
|
||
|
||
Además, sin confirmar:
|
||
|
||
- ⚠️ **`ID` de partida.** El read model distingue `ID` (renglón) de `ProductID` (ítem del catálogo); el write model **solo tiene `ID`**. Mandar el GUID del servicio en `ID` puede ser justo lo que BIND rechaza. El body de abajo **omite `ID`** y manda la partida como texto con `Title`/`Unit` — que además es como Araceli captura.
|
||
- ⚠️ `Type` y `SelectedUnit` siguen sin documentar; van omitidos.
|
||
|
||
---
|
||
|
||
## 4 · Body listo para mañana (dry-run ejecutado, operación #18)
|
||
|
||
IDs resueltos contra BIND en vivo: **MXN** `b7e2c065-bd52-40ca-b508-3accdd538860` · **Matriz** `65ee189a-a163-4f23-8466-87627a5ba776` (única ubicación) · **CEMEX** `6f17c5bd-e7a0-4152-9702-4a486c1b7c69` (RFC `CEM880726UZA`, 90 días de crédito).
|
||
|
||
```json
|
||
{
|
||
"LocationID": "65ee189a-a163-4f23-8466-87627a5ba776",
|
||
"CurrencyID": "b7e2c065-bd52-40ca-b508-3accdd538860",
|
||
"ExchangeRate": 1.0,
|
||
"Items": [
|
||
{ "Title": "SERVICIO DE ENLACE", "Unit": "E48", "Price": 1234.0,
|
||
"Qty": 1.0, "VAT": 197.44, "IEPS": 0, "IndexNumber": 1 }
|
||
],
|
||
"ClientProspect": {
|
||
"isNew": false,
|
||
"Client": { "ClientId": "6f17c5bd-…", "ClientName": "CEMEX" }
|
||
},
|
||
"VATRate": 0.16,
|
||
"Comments": "Generada desde el ticket FAC-106 (prueba acompañada)."
|
||
}
|
||
```
|
||
|
||
**Si BIND vuelve a rechazar**, el orden de ataque es: (1) agregar `PriceListID` con el de una cotización reciente del mismo cliente; (2) mandar el GUID del servicio en `ID`; (3) probar `Type`. El endpoint ya expone `ex.Body` de BIND en el 502, así que el diagnóstico se lee en pantalla — no se repite el 500 ciego del 12-ago.
|
||
|
||
---
|
||
|
||
## 5 · ⚠️ Seguridad: `Bind:Mode` está en **Write** ahora mismo
|
||
|
||
`GET /api/emision/estado` responde `{"modo":"Write"}` — el candado de ADR-001 está **abierto** fuera de la sesión acompañada, contra lo que se le prometió a Noé ([REGISTRO #31a](../bitacora/REGISTRO.md)). Una confirmación accidental escribiría en producción. **Regresarlo a `ReadOnly`** y encenderlo solo durante la sesión:
|
||
|
||
```bash
|
||
dotnet user-secrets set "Bind:Mode" "ReadOnly" --project src/Balam.Api
|
||
```
|
||
|
||
---
|
||
|
||
## 6 · Lo que falta cablear (no bloquea la prueba manual)
|
||
|
||
El dry-run de arriba se armó **a mano** con los datos de `FAC-106`. Para que la pantalla lo arme sola faltan cuatro campos en la configuración y en el DTO de detalle: `Servicio/Producto` (11599), `Cantidad` (11600), `IVA` (11601) y `Fecha de vencimiento` (11597). Con eso el wizard prellena la partida completa desde el ticket.
|