Saltar a contenido

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.md
  • PDF-010H-B2B-RUNTIME-DRY-RUN-DESIGN.md
  • PDF-010I-B2B-PRICING-ENGINE-LOCAL-PROTOTYPE.md
  • PDF-009M-WOOCOMMERCE-PRODUCT-DRAFT-PILOT-WRITE.md
  • docs/PROJECT-STATE.md
  • docs/ROADMAP.md
  • docs/governance/ACTIVE-CONTEXT.md
  • docs/tenants/alpuntodeventa/business-observer/production/README.md
  • mkdocs.yml

C. Archivos tecnicos creados/modificados

Extensiones locales agregadas dentro de infra/business-observer/production/b2b-pricing/PDF-010I/:

  • b2b_customer_mapping_store.py
  • b2b_catalog_pricing_dry_run.py
  • b2b_cart_checkout_dry_run.py
  • run_b2b_cart_checkout_dry_run.py
  • test_b2b_customer_mapping_store.py
  • test_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: PrecioListaFinal como regular_price y estado PUBLIC_DEFAULT;
  • cliente B2B activo: precio PrecioL{Lista_Precio} y estado B2B_PRICE_OK;
  • SKU inexistente, sin precio o precio <= 0: BLOCKED_PRICE_MISSING;
  • SKUs piloto de PDF-009M, incluyendo negativos 3995 y 4010.

F. Simulacion carrito implementada

b2b_cart_checkout_dry_run.py recalcula cada linea server-side desde el motor local. La salida por linea incluye:

  • sku
  • qty
  • price_list_code
  • applied_price
  • line_total
  • regular_price_reference
  • source_hash
  • pricing_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_id
  • sgc_customer_id
  • price_list_code
  • pricing_engine_version
  • source_hash
  • pricing_status

Metadata candidate por linea:

  • sku
  • qty
  • price_list_code
  • applied_price
  • regular_price_reference
  • source_hash
  • pricing_status

H. Tests creados

Se agregaron tests para:

  • visitante compra SKU valido con PrecioListaFinal;
  • cliente mapeado lista 1 compra SKU valido con PrecioL1;
  • cliente mapeado lista 5 compra SKU valido con PrecioL5;
  • cliente sin mapping bloquea;
  • cliente suspendido/de baja bloquea;
  • lista invalida bloquea;
  • SKU 3995 y 4010 bloquean 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.md
  • docs/PROJECT-STATE.md
  • docs/ROADMAP.md
  • docs/governance/ACTIVE-CONTEXT.md
  • mkdocs.yml

L. Validaciones requeridas

Validaciones de cierre:

  • git diff --check
  • pytest infra/business-observer/production/b2b-pricing/PDF-010I
  • python 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.