PDF-010J - B2B Customer Mapping Cart Checkout Dry-Run¶
Fecha: 2026-06-23
Estado: PROTOTIPO TECNICO LOCAL + TESTS + COMMIT / SIN RUNTIME / SIN WRITES
portal_visible = yes
Scope: tenant
tenant_id: alpuntodeventa
Destino funcional: SOURCE-001 Clientes + SOURCE-002 Productos -> WooCommerce La Directa
Owner: Gabi / Carlos Canu
A. SAFE POINT inicial¶
| Control | Resultado |
|---|---|
git status -sb |
## main...origin/main |
git rev-parse HEAD |
1ff199530552935c4c105174047807e49eca0583 |
git rev-parse origin/main |
1ff199530552935c4c105174047807e49eca0583 |
git log -3 --oneline |
1ff1995 feat: add pdf-010i b2b pricing engine prototype; a6536f2 docs: add pdf-010h b2b runtime dry-run design; d17fb94 docs: add pdf-010g b2b commercial price rules approval |
git diff --check inicial |
PASS |
B. Documentacion leida¶
PDF-010G-B2B-COMMERCIAL-PRICE-RULES-APPROVAL.mdPDF-010H-B2B-RUNTIME-DRY-RUN-DESIGN.mdPDF-010I-B2B-PRICING-ENGINE-LOCAL-PROTOTYPE.mdPDF-009M-WOOCOMMERCE-PRODUCT-DRAFT-PILOT-WRITE.mddocs/PROJECT-STATE.mddocs/ROADMAP.mddocs/governance/ACTIVE-CONTEXT.mddocs/tenants/alpuntodeventa/business-observer/production/README.mdmkdocs.yml
C. Archivos tecnicos creados/modificados¶
Extensiones locales agregadas dentro de
infra/business-observer/production/b2b-pricing/PDF-010I/:
b2b_customer_mapping_store.pyb2b_catalog_pricing_dry_run.pyb2b_cart_checkout_dry_run.pyrun_b2b_cart_checkout_dry_run.pytest_b2b_customer_mapping_store.pytest_b2b_cart_checkout_flow.py
Impacto: el prototipo PDF-010I queda extendido a mapping local, catalogo,
carrito, checkout y payload candidate de orden. No se conecta a WooCommerce,
PostgreSQL, .env, SQL ni runtime.
D. Store de mapping implementado¶
Se implemento un store local/simulado no sensible:
- input candidate:
wc_customer_id,sgc_customer_id,customer_status,price_list_code,mapping_status; - cliente visitante sin
wc_customer_id:PUBLIC_DEFAULT; - mapping unico y activo:
MAPPED; - mapping ausente o ambiguo:
BLOCKED_CUSTOMER_MAPPING; - cliente suspendido o de baja:
BLOCKED_CUSTOMER_STATUS; - lista fuera de
1..9:BLOCKED_PRICE_LIST.
Los IDs usados son sinteticos (1001, 1005, etc.) y las referencias SGC son
sanitizadas (SOURCE-001-...-CANDIDATE). No se imprime CUIT, email, telefono,
direccion ni secretos.
E. Simulacion catalogo implementada¶
b2b_catalog_pricing_dry_run.py resuelve:
- visitante:
PrecioListaFinalcomoregular_pricey estadoPUBLIC_DEFAULT; - cliente B2B activo: precio
PrecioL{Lista_Precio}y estadoB2B_PRICE_OK; - SKU inexistente, sin precio o precio
<= 0:BLOCKED_PRICE_MISSING; - SKUs piloto de
PDF-009M, incluyendo negativos3995y4010.
F. Simulacion carrito implementada¶
b2b_cart_checkout_dry_run.py recalcula cada linea server-side desde el motor
local. La salida por linea incluye:
skuqtyprice_list_codeapplied_priceline_totalregular_price_referencesource_hashpricing_status
G. Simulacion checkout/orden implementada¶
Checkout revalida todas las lineas antes de generar payload:
- si una linea queda bloqueada, no genera orden;
- si una linea cambia precio/lista/hash entre carrito y checkout, devuelve
BLOCKED_ORDER_INCONSISTENCY; - si todas las lineas pasan, genera
order_payload_candidate.
Metadata candidate de orden:
wc_customer_idsgc_customer_idprice_list_codepricing_engine_versionsource_hashpricing_status
Metadata candidate por linea:
skuqtyprice_list_codeapplied_priceregular_price_referencesource_hashpricing_status
H. Tests creados¶
Se agregaron tests para:
- visitante compra SKU valido con
PrecioListaFinal; - cliente mapeado lista
1compra SKU valido conPrecioL1; - cliente mapeado lista
5compra SKU valido conPrecioL5; - cliente sin mapping bloquea;
- cliente suspendido/de baja bloquea;
- lista invalida bloquea;
- SKU
3995y4010bloquean por precio faltante; - carrito mixto con linea bloqueada bloquea checkout;
- carrito todo OK genera payload de orden candidate;
- metadata de orden incluye lista, precio y
source_hash; - mapping ambiguo queda bloqueado.
I. Tests ejecutados¶
Comando:
powershell
pytest infra/business-observer/production/b2b-pricing/PDF-010I
Resultado:
24 passed in 0.29s
J. Dry-run ejecutado¶
Comando:
powershell
python infra/business-observer/production/b2b-pricing/PDF-010I/run_b2b_cart_checkout_dry_run.py
Resumen no sensible:
| status | casos |
|---|---|
PUBLIC_DEFAULT |
1 |
B2B_PRICE_OK |
2 |
CHECKOUT_READY |
1 |
BLOCKED_CUSTOMER_MAPPING |
1 |
BLOCKED_CUSTOMER_STATUS |
1 |
BLOCKED_PRICE_LIST |
1 |
BLOCKED_PRICE_MISSING |
2 |
BLOCKED_ORDER_INCONSISTENCY |
1 |
K. Documento PDF-010J creado¶
Documento oficial:
docs/tenants/alpuntodeventa/business-observer/production/PDF-010J-B2B-CUSTOMER-MAPPING-CART-CHECKOUT-DRY-RUN.md
Tambien se actualizan:
docs/tenants/alpuntodeventa/business-observer/production/README.mddocs/PROJECT-STATE.mddocs/ROADMAP.mddocs/governance/ACTIVE-CONTEXT.mdmkdocs.yml
L. Validaciones requeridas¶
Validaciones de cierre:
git diff --checkpytest infra/business-observer/production/b2b-pricing/PDF-010Ipython infra/business-observer/production/b2b-pricing/PDF-010I/run_b2b_cart_checkout_dry_run.py.\.venv-portal\Scripts\mkdocs.exe build --strict
M. Estado final esperado¶
- commit local creado;
- sin push;
- sin deploy;
- sin runtime WooCommerce;
- sin PostgreSQL;
- sin sync, scheduler, cron ni pipelines.
N. Proximo paso recomendado¶
Abrir PDF-010K para disenar el contrato persistente real del mapping
wc_customer_id -> sgc_customer_id en PostgreSQL/OpenClaw, todavia sin writes
operativos y con migracion/DDL candidate revisable antes de runtime.
O. Restricciones preservadas¶
Durante este gate:
- no se toco WooCommerce API;
- no se toco
.env; - no se imprimieron secretos;
- no se toco PostgreSQL;
- no se ejecuto SQL;
- no se modifico runtime WooCommerce;
- no se ejecuto sync, scheduler, cron ni pipelines;
- no se instalo plugin;
- no se modifico theme;
- no se crearon clientes;
- no se crearon productos;
- no se modificaron productos ni precios reales;
- no se hizo push ni deploy.