Especificación Maestra — «Planter Full 2.0» (Inspirado y Superando a Mercado Libre Full)
<!-- ESTADO-VIVO:INICIO -->
⚡ ÚLTIMO ESTADO VIVO (Actualizado: 2026-10-29 19:13 · Orden Cronológico Inverso: Más Nuevo Arriba)
- Entrada (wacli · 𝗘𝗟𝗘𝗩𝗔𝗥 𝗖𝗢𝗡𝗖𝗜𝗘𝗡𝗖𝗜𝗔 · Niké): 📌 *AUDITORÍA FORENSE Y CONEXIÓN OMNICANAL:
AUTORIZAR DESCUENTO(providerDiscount) +PRECIOS PARA ML+PLANT HUB* ━━━━━━━━━━━━━━ Corrimos el escuadrón completo (claude --model opus --effort high+codexgpt-6.1-sol, sesión01a189ae-1ed6-7650-a2a1-31635c31e628+ QA Playwright E2E) auditando el có... - Entrada (wacli · 𝗘𝗟𝗘𝗩𝗔𝗥 𝗖𝗢𝗡𝗖𝗜𝗘𝗡𝗖𝗜𝗔 · Niké): 📌 *ESTADO EXACTO DE LAS MEJORAS EN PORTAL PLANTER (
SELLERS.PLANTINTERNO.COM·PLANTER FULL 2.0)* ━━━━━━━━━━━━━━ Acabo de auditar el código en vivo desellers.plantinterno.com(worker/build_sellers.py, sección#stock) contra la especificación maestra de *Planter Full 2.0*. Acá tenés exactamente qué es... - Entrada (wacli · 𝗘𝗟𝗘𝗩𝗔𝗥 𝗖𝗢𝗡𝗖𝗜𝗘𝗡𝗖𝗜𝗔 · Niké): 📚 *PLAN MAESTRO RADICAL 2.0 (
OPUS · CODEX · GROK) · 1.000 LIBROS EN 90 DÍAS (++$16,8MNETOS CON 0% TIEMPO TUYO)* ━━━━━━━━━━━━━━ *1. El hallazgo en Ezeiza que duplica la velocidad de recupero* • Auditamos el stock físico hoy en Ezeiza y encontramos que tenés **1.120 ejemplaresde *El Arte de Dirigir* ya i...
<!-- ESTADO-VIVO:FIN -->
Acuerdos Sellers Beta y Autogestión Planter (2026-10-30 · 16:22 hs)
- Referencia: reunion-presencial-cyber-navidad-vivet-2026-10-30 (
30/10/2026 · 16:22 a 17:38 hs). - Fin de OC manuales → Orden de Envío Sugerido (
49 díasde cobertura,00:14:22 – 00:17:20): - En
Sellers -> Stock -> Beta (Envío Turnos), cada marca Planter (*Mami Keto*, *Almirante*, *Íntegra*, *Zafran*, *HiPro*) visualiza su envío sugerido para cubrir49 díasde stock, carga la fecha de vencimiento mínima recomendada, selecciona turno en el calendario y emite la Orden de Envío, disparando la OC interna para recepción en depósito. - Auditoría de Tabla de Vida Útil (
00:16:18): Revisar con mauro-stoessel|Mauro Stoessel de dónde toma la vida útil el sugerido (a yogures de35–40 díasles exigía vencimiento febrero 2027). - Autogestión de Descuentos en Mongo + Selector por Unidad de Negocio (
00:17:25 – 00:21:45,01:12:43): - Las marcas ven alertas de vencimiento según ritmo de venta (
1,6x) y pueden tocar «Autorizar descuento» o sumarse a dinámicas3x2(33%) y campañas (*Cyber Saludable*, *Black Friday*, *Fiestas*, *Plan B Day*), impactando directo en Mongo (plant.com.ar,BusinessyMercado Libre) sin negociación manual de gaspi|Gaspi. - Mejora solicitada por nacho-ramon|Nacho Ramon (
00:19:20/01:13:20): permitir que la marca elija qué porcentaje aplicar en cada unidad de negocio (ej.10%en Comercio/Business para cuidar la cadena de valor y30%en Consumidor Final). - Próximas evoluciones definidas:
- Reserva de mercadería en tránsito (
pedido de Lucas Cunil,00:22:12): estilo Amazon, permitir a comercios/consumidores reservar productos sin stock cuando la marca Planter ya tiene turno confirmado de entrega. - Alquiler de depósito >60 días (
propuesta de Mauro Stoessel,00:23:38): evaluar para próxima etapa cobrar1% diariosobre pallets Planter que superen 60 días sin rotar. - Integración de Google Calendar de Turnos + OpenKey en plant-hub (
01:14:00).
Última actualización: 2026-10-28 (Auditoría técnica de Mercado Libre Full API + sellers.plantinterno.com + Plant Hub + MongoDB vivet-web + Reglas de Negocio de Gabriel Busso y Mauro Stoessel)
Estado: Especificación Funcional y Técnica Completa — Lista para Implementación en sellers.plantinterno.com (Fase 1 Inmediata) y Plant Hub (apps/supplier · Fase 2)
Responsables: Gabriel Busso · Mauro Stoessel (Compras & Supply Chain) · Recepción Ezeiza
1. Resumen Ejecutivo: El Cambio de Paradigma Operativo
En el esquema tradicional de compras, el equipo de Compras persigue manualmente a las marcas en consignación (Planter), emite Órdenes de Compra (OCs) a mano, negocia cantidades por WhatsApp y reclama entregas atrasadas.
Con «Planter Full 2.0», Plant invierte el flujo exactamente igual que Mercado Libre Full (Envíos a Full), pero adaptado a alimentos y productos con vencimiento real en nuestro centro de distribución de Ezeiza:
- Compras deja de emitir OCs manuales y de perseguir marcas Planter: El portal (
sellers.plantinterno.comhoy, yapps/supplierenPlant Hub) audita continuamente el stock físico en Ezeiza, las ventas omnicanal (Web B2C + Business B2B + Mercado Libre Full) y el stock en tránsito, y dispara alertas automáticas de reposición desdePortal Planter <avisos@plant.com.ar>. - Recomendación inteligente para cubrir
45 a 49 díasde venta real des-censurada: El sistema sugiere la cantidad exacta (redondeada a bulto cerradoUxBulto) para cubrir entre 45 y 49 días de demanda real (excluyendo días en quiebre para no subestimar productos estrella agotados, y descontando órdenes ya en tránsito). - Idea de Mauro · Calculadora Dinámica en Vivo de Fecha de Vencimiento Mínima Exigida según Cantidad: A medida que la marca edita cuántas unidades quiere mandar en su Orden de Envío, el sistema calcula en tiempo real cuántos días tardarán en venderse esas unidades sumadas al stock actual (
(Stock Actual + En Tránsito + Cantidad a Enviar) ÷ Venta Diaria Real) +30 díasde margen mínimo de vida útil para el consumidor final, y le muestra en vivo la Fecha de Vencimiento Mínima Exigida para aceptar ese lote en Ezeiza (o cuántas unidades máximas puede mandar si su lote vence antes, o el compromiso de promoción atada al lote). - Idea de Gaby 1 · Simulador Persuasivo en Vivo de Pérdida de Ventas por Sub-Envío: Si un SKU vende
10 u./día(sugerido450 u.para 45 días) y la marca tipea10 u., el portal le advierte en vivo en rojo/ámbar antes de confirmar: *«Con 10 u. vas a quebrar stock en 1 día y vas a dejar de facturar $XXX.XXX este mes (quedando sin stock durante 44 días del ciclo)»*. - Idea de Gaby 2 · Integración Directa con el Google Calendar de Recepción Ezeiza de Mauro + Puente Automático a
purchaseOrders+ Seguimiento 100% Automatizado por Mail:
- Al crear la Orden de Envío, la marca elige su turno de entrega directamente sobre la misma agenda de Google Calendar de Recepción Ezeiza que hoy usa Mauro (embebida y sincronizada vía Google Calendar API), evitando tener dos agendas paralelas entre proveedores de Compra Firme y marcas Planter.
- Al confirmar, el portal inyecta automáticamente la
purchaseOrderen Producción (Firestore vivet-web→MongoDB purchaseOrders+ evento en Google Calendar de Ezeiza) con las unidades declaradas, el turno agendado y el vencimiento mínimo exigido por SKU. - Recepción Ezeiza ve la orden en su pantalla habitual, tilda las unidades recibidas y carga el lote y fecha de vencimiento real (
inventoryAdjustments.data.controlReason.lotsTimestamps), que se refleja automáticamente en el portal de la marca. - Si pasa el turno agendado en Google Calendar y la
purchaseOrdersigue en estadopendingen MongoDB, el bot envía automáticamente un correo amable desdeavisos@plant.com.arpara que la marca reprograme su turno en 1 clic, sin intervención humana de Compras.
2. Auditoría Exhaustiva de Mercado Libre Full (Envíos a Full)
Para diseñar «Planter Full 2.0», auditamos tanto la experiencia de usuario de Mercado Libre Full como la estructura técnica real de su API (/marketplace/fbm/user-products/{up}/replenishment y /inventories/{inv}/stock/fulfillment), que ya consumimos en scripts/ml_reposicion.py y worker/build_ml.py (750 productos auditados en vivo en ml:repo).
2.1. Pantallas y Flujo Operativo de Mercado Libre Full
| Etapa en ML Full | Qué ve y hace el Seller en Mercado Libre | Datos Técnicos en la API de ML (/replenishment y /stock/fulfillment) |
|---|---|---|
| 1. Panel de Salud y Gestión de Stock Full | Tablero con semáforo de urgencia de envío, métricas de cobertura en días, filtros rápidos (*«Enviar esta semana»*, *«Enviar la próxima semana»*, *«Sin urgencia»*, *«Excedente»*, *«Restringidos»*) y buscador por SKU/EAN. | • stock.shipping_urgency: THIS_WEEK (121 SKUs hoy en Plant), NEXT_WEEK (131), IN_TWO_WEEKS (72), NO_URGENCY (341), EXCEDENT (85).<br>• recommendation.recommendation_type: REPLENISH (227), NO_REPLENISHMENT (514), NO_REPLENISHMENT_BY_RESTRICTION (61). |
| 2. Cálculo de Demanda y Sugerencia de Envío | Para cada SKU, ML muestra las ventas de los últimos 30 días (unidades y $) y las últimas 6 semanas, descontando los días agotados para calcular la velocidad real, y sugiere cuántas unidades enviar antes de una fecha límite (replenishment_deadline). | • sales.sales_totals: { gmv, quantity } (30d).<br>• sales.sales_history: array de 6 semanas con { units_sold, days_out_of_stock, campaigns }.<br>• recommendation.suggested_quantity: { value, measure_unit }.<br>• recommendation.replenishment_deadline: fecha tope de llegada al depósito.<br>• recommendation.replenishment_frequency: cada cuántos días conviene mandar (ej. 28 o 45 días). |
| 3. Simulador de Cantidad a Enviar y Penalidades / Beneficios | El seller puede aceptar la cantidad sugerida o modificarla. Si intenta mandar más del tope permitido o si tiene baja rotación, ML le bloquea el envío (NO_REPLENISHMENT_BY_RESTRICTION) o le advierte de cargos por almacenamiento prolongado (*stock antiguo > 60/90 días*). Si manda lo sugerido a tiempo, le otorga beneficios (eligibility_benefits, descuentos en colecta/almacenamiento). | • stock.minimum_distributable_stock: stock mínimo de seguridad.<br>• eligibility_benefits: { type, discount }.<br>• Bloqueo duro cuando el seller supera su cupo de m³ o unidades en bodega. |
| 4. Control de Productos con Vencimiento (Regla FEFO de ML Full) | Para alimentos, suplementos y cosmética, ML exige que el producto ingrese al centro de distribución con una vida útil remanente mínima (típicamente 90 días mínimos al momento de la recepción + lote y fecha de vencimiento impresos de fábrica en cada unidad). Si vence antes de venderse, pasa a No apto para la venta (not_available: expired / soon_to_expire) y el seller debe retirarlo pagando cargo o autorizar descarte. | • En /inventories/{inv}/stock/fulfillment?include_attributes=conditions: desglosa available_quantity vs not_available_quantity con condiciones damaged, expired, soon_to_expire, lost, transfer, withdrawal. |
5. Preparación de Productos y Bultos Master (Master Case) | Paso obligatorio donde el seller declara:<br>1) Si cada unidad tiene código universal legible (EAN-13 / GTIN) o si debe imprimir etiquetas de producto ML.<br>2) Cómo agrupa las unidades: Cajas Master (packages_master_case = unidades por bulto) o Pallets, e imprime las Etiquetas de Bulto / Caja Master (código de barras/QR por caja que dice qué OC/Envío es y cuántas cajas son: Caja 1 de N). | • product.packages_master_case: unidades por bulto cerrado.<br>• Generación de PDF térmico ZPL / A4 con etiquetas de unidad (si no tiene EAN) y etiquetas de bulto/pallet. |
| 6. Reserva de Turno en Muelle y Datos del Transporte (ASN) | El seller elige modalidad de ingreso (Vehículo propio, Expreso/Transporte, Correo) y selecciona fecha y franja horaria de descarga en el calendario del depósito. Antes de ir, carga Patente, Chofer, DNI y N° de Remito. Si llega sin turno o fuera de ventana, el muelle rechaza el camión; si no asiste (No-Show), ML penaliza su cupo. | • Agenda de turnos vinculada al Inbound Shipment ID (Envío #).<br>• Pase de ingreso con QR para portería y rampa de recepción. |
| 7. Recepción, Conciliación y Reclamos de Ingreso | A medida que el depósito escanea los bultos, el estado cambia de *«Programado»* → *«En proceso de ingreso»* → *«Ingresado»* (o *«Ingresado con diferencias»* si hubo faltantes, sobrantes o rechazo por vencimiento corto/rotura). | • Conciliación línea por línea: Declarado vs. Recibido vs. Rechazado (motivo: vencimiento corto / daño / sin EAN). |
3. Cómo «Planter Full 2.0» Supera a Mercado Libre Full
Mercado Libre Full usa una regla rígida de vencimiento (ej. *«mínimo 90 días de vida útil para todo»*), que tiene dos fallas graves en alimentos saludables:
- Falla A (Exceso con vencimiento corto): Si un seller manda 120 días de venta de un producto que vence en 95 días, ML Full lo deja entrar (porque supera los 90 días fijos), pero los últimos 25 días de stock se van a vencer adentro del depósito.
- Falla B (Falso rechazo en alta rotación): Si un producto fresco/alta rotación (ej. Hummus, Tofu o Kombucha) vende lo que manda en 15 días y tiene 65 días de vida útil, una regla fija de 90 días lo rechaza injustamente cuando en realidad sobra margen para el consumidor.
Con las reglas diseñadas por Gabriel Busso y Mauro Stoessel, Planter Full 2.0 supera a Mercado Libre Full en 6 dimensiones clave:
| Dimensión | Cómo funciona en Mercado Libre Full | Cómo lo supera «Planter Full 2.0» (Reglas Gaby + Mauro) |
|---|---|---|
| 1. Regla de Vencimiento en Recepción | Estática / Fija (ej. 90 días fijos sin importar si mandás para 10 días o para 180 días de venta). | Dinámica según Cantidad Enviada (Idea de Mauro):<br>Vto Mínimo Exigido = Fecha Turno Entrega + Días que tardará en venderse (Stock Actual + En Tránsito + Cantidad a Enviar) + 30 días de vida útil para el consumidor final.<br>• Si mandás para 60 días de venta, te exige vencimiento > 90 días.<br>• Si tu lote vence en 70 días, el sistema te dice en vivo: *«Con ese vencimiento podés mandar máximo X unidades (40 días de venta), o tenés que dejar pre-aprobada una promo de liquidación atada a este lote»*. |
| 2. Persuasión Comercial ante Sub-Envíos | Si el seller cambia de 450 u. sugeridas a 10 u., ML simplemente guarda 10 u. sin explicarle cuánto dinero va a perder. | Simulador Persuasivo de Plata Perdida en Vivo (Idea de Gaby 1):<br>Si el SKU vende 10 u./día (sugerido 450 u. para 45 días) y la marca pone 10 u., aparece un banner interactivo inmediato:<br>⚠️ *«Con 10 u. vas a cubrir solo 1 día de venta. Vas a quebrar stock el [Fecha] y vas a dejar de facturar $XXX.XXX este ciclo (44 días con stock en cero).»* |
| 3. Horizonte de Cobertura Omnicanal | Solo mira las ventas dentro de Mercado Libre. | Omnicanal 360° (45 a 49 días):<br>Suma la velocidad real de los 3 canales que abastece Ezeiza (plant.com.ar B2C + Business B2B + Mercado Libre Full), des-censurando los días sin stock y aplicando estacionalidad real. |
| 4. Agenda de Recepción Unificada | Turnera cerrada exclusiva de ML. | Sincronización Bidireccional con el Google Calendar de Recepción Ezeiza de Mauro (Idea de Gaby 2):<br>Unifica en un solo calendario los camiones de Compra Firme y los de Planter Full. La marca agenda desde sellers.plantinterno.com directamente sobre los huecos reales del Google Calendar de Ezeiza. |
| 5. Emisión y Conciliación de OC en ERP/WMS | Separado del ERP interno de Plant. | Inyección Automática en purchaseOrders (vivet-web + Plant Hub):<br>La Orden de Envío creada por la marca nace automáticamente como purchaseOrder oficial en Producción. Recepción Ezeiza recibe sobre esa misma orden y carga los vencimientos por lote (lotsTimestamps). |
| 6. Reclamo y Reprogramación de Turnos Vencidos | Penalización punitiva seca o cancelación automática. | Seguimiento Relacional 100% Automatizado (avisos@plant.com.ar):<br>Si pasa la fecha del turno y la purchaseOrder sigue pendiente de ingreso en MongoDB, el bot manda un mail institucional cálido y persuasivo cuantificando la pérdida por quiebre y ofreciendo reprogramar el turno en 1 clic sin que Compras pierda 1 minuto. |
4. Auditoría del Código Actual en nuestros Repositorios (sellers.plantinterno.com vs. Plant Hub)
Cumpliendo el pedido de Gaby (3BF7E90CC193B9C6F7C4), auditamos línea por línea qué existe hoy en sellers.plantinterno.com (worker/build_sellers.py) y qué armó Juanchi en Plant Hub (apps/supplier y packages/business-logic/src/logistics/supplier-portal.ts).
4.1. Estado actual de la Turnera y Envíos en Plant Hub (Código de Juanchi)
En el repositorio /Users/gabrielbusso/Proyectos/plant-hub, existen dos capas construidas en momentos distintos:
- La UI del Portal de Proveedores (
apps/supplier/app/(supplier)/envios/):
- Lo que YA está hecho y funciona muy bien visualmente:
NewShipmentForm.tsx/envios/nuevo/NewShipmentForm.tsx): Tiene un Wizard de 4 pasos muy prolijo:- Paso 1: Selección de productos (vinculado a una OC abierta o catálogo libre si
provider.consignment === true), con validación de tolerancia (+5%). - Paso 2: Carga obligatoria de Lote y Fecha de Vencimiento FEFO por variante (
lotData[variantId] = { lotNumber, expirationDate }), validando que la fecha sea mayor a hoy. - Paso 3: Estructura de bultos (
BOX/PALLET), cantidad de cajas, peso y generación en vivo de Etiquetas Térmicas GS1-128 / SSCC (AsnThermalLabel+ código ZPL). - Paso 4: Carga de N° de Remito AFIP (
000X-XXXXXXXX), subida de foto/PDF del remito a Firebase Storage, nombre de Expreso/Transporte, Chofer y Notas. Al confirmar, llama acreateSupplierPurchaseOrderque crea laPurchaseOrderen MongoDB y elStockPicking(INCOMING) en el WMS. ReservationModal.tsx/envios/[id]/ReservationModal.tsx) yBulkReservationModal.tsx/envios/BulkReservationModal.tsx): Modales con calendario interactivo para reservar turno individual o agrupar varias órdenes en un mismo turno.- Los 4 problemas técnicos detectados hoy en la Turnera de
Plant Hub(por qué NO está lista para prender sola sin ajustes):
- Horarios 100% hardcodeados sin cupo real (
getSupplierSellerScheduleensupplier-portal.ts:2074-2093): La función ignora_sellerId, no consulta cuántos camiones ya reservaron y devuelve siempre un bucle fijo de 14 días hábiles con las horas[9, 11, 14, 16]. Si 15 proveedores eligen el lunes a las 09:00 hs, les da turno a los 15. - Desconexión total con el Google Calendar de Mauro: No lee ni escribe en Google Calendar. Si una marca saca turno en
Plant Hub, Mauro y Recepción Ezeiza no se enteran en su calendario actual. - El Wizard de Nuevo Envío (
NewShipmentForm.tsx) NO incluye la elección de turno: El proveedor crea el envío en 4 pasos sin elegir turno, y recién después tiene que entrar al detalle del envío (/envios/[id]) y tocar el botónRESERVAR UN TURNO(lo que hace que la mayoría se olvide de sacar turno). - Cableado pendiente en
actions.tscon el modeloSupplierAdvanceShippingNotice: Aunque enasn-shipment.tsya se programó el modelo nuevoSupplierAdvanceShippingNotice(con estadosDRAFT → ANNOUNCED → IN_TRANSIT → ARRIVED_AT_DOCK → RECEIVING → PARTIALLY_RECEIVED / RECEIVED / REJECTEDymergeDeliverySlotpara no pisarpurchaseOrder.received), el archivo [apps/supplier/app/(supplier)/envios/[id]/actions.ts](file:///Users/gabrielbusso/Proyectos/plant-hub/apps/supplier/app/(supplier)/envios/[id]/actions.ts#L41) todavía sigue llamando a la función viejareserveSupplierShipmentTurnque pisareceived: { t: timestamp }.
4.2. Estado actual de sellers.plantinterno.com (worker/build_sellers.py)
- Lo que ya tiene en producción hoy:
- Pestaña
#stock(Stock en depósito) con semáforo de cobertura (Urgente ≤14d,Reponer 15–30d,Cubierto >30d,Sin rotación) y columna+45d. - Pestaña
#fillratecon historial depurchaseOrdersy lectura en vivo depurchaseOrderspendientes desdemongoAggregate(fillRateVivo()). - Motor de correo transaccional propio (
mandar()en líneas2177–2280) saliendo desdePortal Planter <avisos@plant.com.ar>vía Gmail API OAuth2 con diseño institucional<table bgcolor>y logo embebido (cid:logo-plant).
- Lo que le falta hoy a
sellers.plantinterno.com(y que agregamos en «Planter Full 2.0»):
- Trampa 1 en velocidad de venta actual (
build_sellers.py:4406): Hoy calculaxd = (v.u.b2c[0] + v.u.b2b[0]) / diasVent. No suma las unidades vendidas en Mercado Libre (v.u.ml) (cuando Ezeiza abastece a ML Full) y divide por días calendario totales sin descontar los días en que el SKU estuvo agotado (stock = 0). - Trampa 2 en sugerido actual (
build_sellers.py:4423): Hoy hacesug = Math.max(0, Math.ceil(xd * 45 - s.av)). No descuenta las unidades que ya vienen en camino en OCs abiertas (enTransito), ni redondea a bulto cerrado (UxBulto), y apunta a45dclavados en lugar de la banda óptima de45 a 49 días. - Es 100% pasivo (solo lectura): La marca ve la tabla pero no tiene inputs para armar su Orden de Envío, no tiene la Calculadora Dinámica de Vencimiento Mínimo de Mauro, no tiene el Simulador de Ventas Perdidas de Gaby, no muestra los vencimientos reales de los lotes en stock (
lotsTimestampsdeinventoryAdjustments), ni permite agendar turno en el Google Calendar de Ezeiza e inyectar lapurchaseOrder.
4.3. Decisión Arquitectónica Recomendada (El Camino Óptimo)
- Fase 1 Inmediata (Esta semana en
sellers.plantinterno.com+ Google Calendar de Mauro + MongoDBvivet-web):
- Como las 72 marcas Planter ya están entrando hoy a
sellers.plantinterno.comcon su link mágico y Ezeiza sigue operando la recepción diaria sobrevivet-web(que replica en tiempo real a MongoDBpurchaseOrderseinventoryAdjustments) y mirando el Google Calendar de Recepción Ezeiza de Mauro, implementamos «Planter Full 2.0» directamente ensellers.plantinterno.comconectado por API al Google Calendar de Mauro y a Firestore/MongoDBpurchaseOrders. - Ventaja clave: Cero fricción para Mauro y para Recepción Ezeiza (siguen viendo un único Google Calendar con todos los turnos de Compra Firme + Planter Full y siguen recibiendo las OCs en la misma pantalla de Recepción que usan hoy).
- Fase 2 Unificación en
Plant Hub(apps/supplier):
- En paralelo, conectamos la turnera de
Plant Hub(NewShipmentForm.tsx+announceSupplierShipment) al mismo Google Calendar de Recepción Ezeiza y sumamos al Paso 1 y Paso 2 deNewShipmentForm.tsxla Calculadora Dinámica de Vencimiento Mínimo de Mauro y el Simulador de Pérdida de Ventas de Gaby, para que cuando se apague Legacy el flujo sea 100% idéntico.
5. Especificación Funcional y Matemática de «Planter Full 2.0»
5.1. Motor de Demanda Real Des-Censurada y Sugerencia 45 a 49 Días
Para cada SKU activo de la marca en Ezeiza, el motor calcula:
- Venta Diaria Real Omnicanal Des-Censurada (
V_diaria_real):
- Se toman los últimos
60 días(o el ciclo actual + anterior) de ventas entregadas/confirmadas (excluyendo órdenes condata.shipmentState == "canceled"):
$$\text{Unidades Vendidas}_{60d} = U_{\text{Web B2C}} + U_{\text{Business B2B}} + U_{\text{ML Full}}$$
- Se descuentan los días con stock 0 en Ezeiza ($\text{DíasAgotado}_{60d}$, auditados desde los snapshots diarios de stock / movimientos de inventario, igual que
days_out_of_stocken ML Full):
$$\text{DíasActivos}_{60d} = \max\left(7,\; 60 - \text{DíasAgotado}_{60d}\right)$$
- Se aplica el Coeficiente Estacional del Mes Actual ($K_{\text{estacional}}$, ej. bebidas en primavera/verano vs. chocolates, con tope prudencial $[0.70,\; 1.35]$ acordado con Mauro):
$$V_{\text{diaria\_real}} = \frac{\text{Unidades Vendidas}_{60d}}{\text{DíasActivos}_{60d}} \times K_{\text{estacional}}$$
- *(Regla de protección de Mauro para Alta Rotación Agotada: si un SKU Clase A/B estuvo agotado los últimos $\ge 15$ días, jamás cae en velocidad 0; conserva su $V_{\text{diaria\_real}}$ de los últimos 30 días previos al quiebre).*
- Stock Disponible Real + Stock en Tránsito Válido (
Stock_Proyectado):
- $\text{StockDisponible} = \text{StockFísicoEzeiza} - \text{StockReservadoPedidosAbiertos}$ (
s.av). - $\text{StockEnTránsito} = \sum \text{UnidadesPendientes}$ en
purchaseOrdersconstatus == "pending"cuya antigüedad desde creación/turno sea $\le 45\text{ días}$ (las OCs fantasma $> 45\text{ días}$ se excluyen automáticamente y se marcan para cierre). - $\text{CoberturaActualDías} = \dfrac{\text{StockDisponible} + \text{StockEnTránsito}}{V_{\text{diaria\_real}}}$.
- Estados de Urgencia y Salud de Stock (inspirados en ML Full):
- 🔴
URGENTE · ENVIAR ESTA SEMANA(THIS_WEEK): $\text{CoberturaActualDías} \le 14\text{ días}$ (o agotado con demanda activa). - 🟠
REPONER PRÓXIMA SEMANA(NEXT_WEEK): $14 < \text{CoberturaActualDías} \le 28\text{ días}$. - 🟡
PLANIFICAR ENVÍO(IN_TWO_WEEKS): $28 < \text{CoberturaActualDías} < 45\text{ días}$. - 🟢
ÓPTIMO · CUBIERTO (45–49d)(NO_URGENCY): $45 \le \text{CoberturaActualDías} \le 60\text{ días}$. - 🟣
EXCEDENTE / SOBRE-STOCK(EXCEDENT): $\text{CoberturaActualDías} > 60\text{ días}$ (bloquea envío nuevo o sugiere activar promo). - ⛔
ENVÍO RESTRINGIDO(NO_REPLENISHMENT_BY_RESTRICTION): SKU inactivo, o con lote actual en depósito próximo a vencer ($< 60\text{ días}$) que requiere evacuación previa antes de recibir mercadería nueva.
- Cálculo de Cantidad Sugerida para cubrir entre
45 y 49 días(Q_sugerida):
- Nuestro objetivo de cobertura tras el envío es ubicarnos en la banda de 45 a 49 días (punto medio objetivo: 47 días, o el múltiplo de bulto cerrado
UxBultoque deje la cobertura dentro del rango $[45,\; 49]$ días):
$$Q_{\text{bruta\_45}} = \max\left(0,\; \lceil 45 \times V_{\text{diaria\_real}} - (\text{StockDisponible} + \text{StockEnTránsito}) \rceil\right)$$
$$Q_{\text{bruta\_49}} = \max\left(0,\; \lfloor 49 \times V_{\text{diaria\_real}} - (\text{StockDisponible} + \text{StockEnTránsito}) \rfloor\right)$$
- Redondeo Inteligente a Bulto Cerrado (
UxBulto/pack): - Si el producto viene en cajas master de $B = \text{UxBulto}$ unidades:
- Buscamos el múltiplo de $B$ ($k \times B$) que caiga dentro de $[Q_{\text{bruta\_45}},\; Q_{\text{bruta\_49}}]$. Si el tamaño de caja salta el rango de 4 días, tomamos $\lceil Q_{\text{bruta\_45}} / B \rceil \times B$ siempre que no supere el tope de vida útil ni 52 días de cobertura.
5.2. Idea de Mauro · Calculadora Dinámica en Vivo de Fecha de Vencimiento Mínima Exigida según Cantidad
Este es el corazón técnico del control de calidad en Ezeiza. En lugar de pedir una fecha de vencimiento estática, la Fecha de Vencimiento Mínima Exigida es una función matemática en vivo de cuántas unidades quiere enviar la marca:
A. Fórmula Matemática Exacta
Cuando la marca ingresa una cantidad a enviar $Q_{\text{enviar}}$ para un SKU y selecciona una fecha de entrega en Ezeiza $F_{\text{entrega}}$ (por defecto, el próximo turno hábil disponible o Hoy + 3 días):
- Días totales que tardará en venderse todo el stock acumulado en Ezeiza ($D_{\text{agotamiento}}$):
$$D_{\text{agotamiento}}(Q_{\text{enviar}}) = \left\lceil \frac{\text{StockDisponible} + \text{StockEnTránsito} + Q_{\text{enviar}}}{V_{\text{diaria\_real}}} \right\rceil$$
- Margen de Vida Útil Mínima para el Consumidor Final ($M_{\text{consumidor}}$):
- Regla general estándar acordada por Mauro: $M_{\text{consumidor}} = 30\text{ días}$ de margen mínimo desde el día en que se vende la última unidad en Plant hasta que vence el producto en la alacena del cliente.
- *(Piso absoluto de recepción en Ezeiza: ninguna mercadería seca/general puede ingresar con menos de $\max(60\text{ días},\; D_{\text{agotamiento}} + 30\text{ días})$, salvo productos ultra-frescos de heladera con acuerdo específico).*
- Días Mínimos de Vida Útil Exigidos desde la Recepción ($D_{\text{vto\_mín}}$):
$$D_{\text{vto\_mín}}(Q_{\text{enviar}}) = D_{\text{agotamiento}}(Q_{\text{enviar}}) + 30\text{ días}$$
- Fecha de Vencimiento Mínima Exigida en el Envase ($F_{\text{vto\_mín}}$):
$$F_{\text{vto\_mín}}(Q_{\text{enviar}}) = F_{\text{entrega}} + D_{\text{vto\_mín}}(Q_{\text{enviar}})\text{ días}$$
B. Ejemplo Numérico Real (Cómo reacciona la UI al instante)
Supongamos un SKU que vende $10\text{ u./día}$, hoy tiene $50\text{ u.}$ en stock (5 días de cobertura), $0$ en tránsito, y la marca va a entregar el 02/11/2026:
- Caso 1 (La marca acepta el sugerido de
420 u.para llegar a 47 días de stock): - Stock total tras recibir = $50 + 420 = 470\text{ u.}$ → Tardará $47\text{ días}$ en venderse.
- Sumando los $30\text{ días}$ de margen para el consumidor: $47 + 30 = \mathbf{77\text{ días}}$ mínimos de vida útil desde la entrega.
- La columna
Vto. Mínimo Exigidomuestra en verde:≥ 18/01/2027 (77 días). - Caso 2 (La marca sube la cantidad a
600 u.porque quiere mandar un pallet entero): - Stock total tras recibir = $50 + 600 = 650\text{ u.}$ → Tardará $65\text{ días}$ en venderse.
- Sumando los $30\text{ días}$ para el consumidor: $65 + 30 = \mathbf{95\text{ días}}$ mínimos de vida útil.
- En el mismo milisegundo en que tipea
600, la etiqueta cambia a ámbar y le avisa:
📅 Vto. Mínimo Exigido para 600 u.:≥ 05/02/2027(95 díasdesde la entrega)
*Porque 650 u. totales tardarán 65 días en venderse + 30 días de margen para el consumidor.*
C. Calculadora Inversa cuando el Lote de la Marca vence antes (Doble Salida Inteligente)
En la misma fila, la marca puede ingresar la Fecha de Vencimiento real de su lote ($F_{\text{lote\_marca}}$). Si $F_{\text{lote\_marca}} < F_{\text{vto\_mín}}(Q_{\text{enviar}})$:
- El sistema calcula instantáneamente el Tope Máximo de Unidades Aceptables sin Promo ($Q_{\text{máx\_lote}}$):
$$\text{DíasDisponiblesParaVender} = (F_{\text{lote\_marca}} - F_{\text{entrega}}) - 30$$
$$Q_{\text{máx\_lote}} = \max\left(0,\; \lfloor \text{DíasDisponiblesParaVender} \times V_{\text{diaria\_real}} - (\text{StockDisponible} + \text{StockEnTránsito}) \rfloor\right)$$
- Y le presenta un modal/alerta interactiva con 2 botones de resolución inmediata:
- Opción A · Ajustar cantidad al giro real del lote (1 clic):
[ Ajustar envío a {Q_máx_lote} u. ] *(Cantidad exacta que se venderá 30 días antes del vencimiento de tu lote sin riesgo de merma).*- Opción B · Mantener las
{Q_enviar} u.firmando Compromiso de Promo FEFO atada al lote:
[ Mandar {Q_enviar} u. y pre-autorizar Promo 20% / 30% OFF a los 60/45 días antes del vto ]*(Acelera la velocidad de venta estimada en $\times 1.6$ para evacuar el lote a tiempo; queda grabado en lapurchaseOrdercomo acuerdo comercial pre-aprobado).*
5.3. Idea de Gaby 1 · Simulador Persuasivo en Vivo de Pérdida de Ventas por Sub-Envío
Muchas veces una marca Planter tiene miedo de enviar 45 días de mercadería o envía "un poquito para probar" (ej. el sistema le pide 450 u. porque vende 10 u./día, y la marca escribe 10 u. o 50 u.).
A. Fórmula del Simulador de Lucro Cesante (Valorizado a Precio de Liquidación de la Marca)
Cada vez que la marca modifica $Q_{\text{enviar}}$ por debajo de $Q_{\text{sugerida\_45d}}$ (o deja en 0 un SKU en estado URGENTE / REPONER):
- Días cubiertos con ese envío ($D_{\text{cubiertos}}$):
$$D_{\text{cubiertos}} = \frac{\text{StockDisponible} + \text{StockEnTránsito} + Q_{\text{enviar}}}{V_{\text{diaria\_real}}}$$
- Fecha exacta en que se quedará sin stock ($F_{\text{quiebre}}$):
$$F_{\text{quiebre}} = \text{Hoy} + \lfloor D_{\text{cubiertos}} \rfloor\text{ días}$$
- Días que estará apagado/sin stock dentro del ciclo de 45 días ($D_{\text{sin\_stock}}$):
$$D_{\text{sin\_stock}} = \max\left(0,\; 45 - D_{\text{cubiertos}}\right)$$
- Unidades y Facturación Neta que la marca perderá de cobrar en el ciclo ($\text{PlataPerdidaMarca}$):
$$\text{UnidadesPerdidas} = \text{round}(D_{\text{sin\_stock}} \times V_{\text{diaria\_real}})$$
$$\text{PlataPerdidaMarca} = \text{UnidadesPerdidas} \times \text{PrecioCompraVigenteSinIVA}$$
*(Nota de seguridad de datos: Siempre se multiplica por el costo de liquidación de la marca purchasePrice neto de IVA, jamás exponiendo el margen de Plant).*
B. Comportamiento Visual en Vivo en la Fila y en el Resumen del Envío
- Si el SKU vende
10 u./día, el costo neto de la marca es$4.500, tiene0 u.en stock, el sistema le sugiere450 u.($2.025.000de ingreso futuro para la marca) y el usuario tipea10 u.: - Debajo del input aparece instantáneamente una píldora persuasiva en rojo intenso con animación suave:
🚨 ¡Vas a quebrar en 1 día! Con 10 u. te quedás sin stock el miércoles 29/10 y dejás de facturar$1.980.000este ciclo (440 u.perdidas durante 44 días sin stock en Web, B2B y Mercado Libre Full).
[ Subir a 450 u. sugeridas (+$1.980.000) ]- Además, en el Footer Flotante de Confirmación de la Orden de Envío, antes de pasar a elegir el turno, el resumen muestra dos números lado a lado:
- 💰 Facturación proyectada de este envío para tu marca:
$X.XXX.XXX - 📉 Ventas que estás dejando en la mesa por enviar de menos en N productos:
-$X.XXX.XXX / mes*(con botón[ Completar sugerido 45d en todos ])*.
5.4. Visor de Vencimientos Actuales en Depósito (lotsTimestamps) + Botón de Promo FEFO
Gracias al hallazgo en la base de producción (inventoryAdjustments), sabemos que Recepción Ezeiza ya guarda hoy la fecha de vencimiento exacta de cada lote ingresado en data.controlReason.lotsTimestamps[pid][lotId] = { e: "YYYY-MM-DD", q: cantidad }.
En la pestaña Stock en depósito de sellers.plantinterno.com:
- Cruzamos en el generador (
build_sellers.pyy en vivo víamongoAggregate) los últimosinventoryAdjustmentsde tiporeceiveconfirmados del proveedor para mostrar en cada SKU su Desglose de Lotes y Vencimientos en Ezeiza:
- Ej.:
Lote 2410 · Vence 15/12/2026 (48 días) · 84 u.
- Semáforo FEFO y Escalera de Acción Comercial:
- Si un lote en stock vence en
< 75 díasy al ritmo actual de venta (V_diaria_real) no se va a terminar de vender 30 días antes de su vencimiento ($\text{UnidadesEnRiesgoDeVencer} > 0$), aparece una alerta destacada arriba de la tabla de Stock:
⏳ Tenés84 u.deHummus Clásicoque vencen el15/12/2026(48 días) y al ritmo actual sobrarán36 u.sin vender.
[ Activar Promo 25% OFF en este lote para liquidarlo a tiempo ]- Al hacer clic, la marca deja pre-autorizada la promoción en
sellers.plantinterno.com(que avisa automáticamente a Comercial/Compras y se cruza con la pestañaPromociones).
5.5. Idea de Gaby 2 · Integración con el Google Calendar de Recepción Ezeiza de Mauro + Puente a purchaseOrders + Bot de Seguimiento
Paso 1: Creación de la Orden de Envío y Agendamiento en el Google Calendar de Mauro
Cuando la marca termina de armar su Orden de Envío en sellers.plantinterno.com:
- Validación de Datos de Despacho:
- Cantidad de bultos / cajas master o pallets estimados.
- Fecha de vencimiento declarada por lote (validada contra la calculadora de Mauro).
- Datos opcionales de transporte (Expreso/Flete, Remito si ya lo tiene).
- Selección de Turno en el Google Calendar de Recepción Ezeiza (Unificado con Mauro):
- El Worker de
sellers.plantinterno.comconsulta en vivo vía Google Calendar API (freebusy/events.list) el calendario de Recepción Ezeiza de Mauro para los próximos 14 días hábiles (franjas configurables, ej. Lunes a Viernes de08:30 a 15:30 hsen bloques de 1 hora o 30 min según cupo de rampa). - La marca elige el día y la franja horaria libre directamente en el selector visual del portal (y también ve el botón para abrir/sumar el evento a su propio Google Calendar).
- Impacto Triple Automático al Confirmar el Envío (
POST /api/envio/crear):
- Impacto 1 · Creación automática de la
purchaseOrderen Producción (Firestore vivet-web+MongoDB purchaseOrders): - Obtiene el próximo número correlativo (
data.number, ej.18315). - Crea el documento en
purchaseOrderscon: status: "pending",seller: "v"provider:objectIDdel proveedor en PlantproviderName: nombre del proveedor,brandsNames: marcasdate: fecha de hoy (DD/MM/YYYY),date_timestamp: epoch msexpirationDate: fecha del turno elegido en Ezeiza (DD/MM/YYYY),expirationDate_timestamp: epoch ms del turnoreceived:{ t: slotUnixSeconds, slotWindow: "10:00-11:00", googleCalendarEventId: "...", source: "planter_full_2_0", minRequiredExpirations: { [pid]: "YYYY-MM-DD" }, declaredLots: { [pid]: { lot, exp, qty } }, boxesCount: N }items:{ [pid]: { q, title, purchasePrice, iva } }yitemsArraycompleto para que Recepción Ezeiza lo vea exactamente igual que una OC creada por Compras.- Impacto 2 · Creación automática del Evento en el Google Calendar de Recepción Ezeiza de Mauro:
- Crea el evento en el Google Calendar de Recepción Ezeiza con título estandarizado:
📦 [PLANTER FULL] {Marca} — OC #{number} ({totalUnits} u. · {boxesCount} bultos)
- En la descripción del evento de Google Calendar deja el link directo a la OC, el detalle de SKUs/bultos y la Fecha de Vencimiento Mínima Exigida por SKU para que el operario de Ezeiza la vea hasta desde el celular.
- Invita al correo de la marca (
attendees) para que le quede agendado en su propio calendario. - Impacto 3 · Generación de Etiquetas QR de Bulto y Comprobante PDF de Orden de Envío:
- Genera instantáneamente un PDF imprimible con:
- Carátula / Remito Interno Planter Full (
OC #18315) con código de barras/QR de la OC, turno confirmado en Ezeiza (Fecha + Hora + Dirección del Centro de Distribución Ezeiza) y tabla de SKUs con el Vencimiento Mínimo Exigido impreso en cada renglón. - Etiquetas de Bulto / Caja Master (
Bulto 1 de N ... Bulto N de N) listas para pegar en las cajas externas.
Paso 2: Control en Muelle de Recepción Ezeiza
- Cuando llega el transporte de la marca a Ezeiza en el turno agendado, el equipo de Recepción abre la
OC #18315en su pantalla habitual de Recepción. - El operario controla las unidades físicas, la temperatura y carga la fecha de vencimiento del lote en
lotsTimestamps. - Si algún lote físico tiene vencimiento menor al
Vto. Mínimo Exigidoque declaró la marca, Recepción tiene el respaldo inmediato en la orden para rechazar el lote en rampa o exigir autorización de promoción. - Al confirmar la recepción en Ezeiza (
status: "received"), el sistema dispara automáticamente el mail de «Confirmación de Ingreso Exitoso en Ezeiza» detallando unidades pedidas vs. recibidas y los vencimientos registrados.
Paso 3: Máquina de Estados de Seguimiento 100% Automatizado por Mail (Portal Planter <avisos@plant.com.ar>)
Compras nunca más persigue a una marca Planter por teléfono o WhatsApp. Un cron diario (08:30 hs y 18:00 hs AR) en el Worker audita el estado de stock y de turnos y ejecuta 5 flujos automáticos de correo institucional (siempre redactados en plural como Equipo de Plant, nunca a nombre personal de Gabriel):
| Disparador Automático | Asunto del Correo (avisos@plant.com.ar) | Contenido Ejecutivo y Botón de Acción (CTA) |
|---|---|---|
1. Alerta Semanal / Quiebre Inminente (≥ 1 SKU con cobertura < 21 días y sin OC en tránsito) | ⚠️ {Marca}: tenés {N} productos por quebrar stock en Plant (dejás de facturar ${MontoPerdido}/mes) | Tabla visual con los SKUs urgentes, cuántas unidades sugiere enviar para cubrir 45–49 días, cuánto dinero pierde la marca por cada semana sin stock y botón directo:<br>[ Armar Orden de Envío y Reservar Turno en Ezeiza ] |
| 2. Confirmación de Orden de Envío + Turno + Etiquetas (Al confirmar en el portal) | ✅ Turno confirmado en Ezeiza — Orden de Envío #{OC} ({FechaTurno} {HoraTurno} hs) | Resumen de la OC #{OC}, dirección y mapa del depósito de Ezeiza, tabla de SKUs con sus Fechas de Vencimiento Mínimas Exigidas en muelle, PDF adjunto con etiquetas de bulto y botón:<br>[ Descargar Etiquetas de Bulto / Reprogramar Turno ] |
3. Recordatorio Preventivo 24 hs antes del Turno (Turno = Mañana y status == "pending") | 🚚 Recordatorio de entrega mañana en Ezeiza — Orden #{OC} ({HoraTurno} hs) | Recordatorio amable de que mañana los esperamos en Ezeiza en la franja reservada, recordando traer Remito y verificar que los lotes cumplan el vencimiento mínimo exigido. Si tuvieron un imprevisto:<br>[ Confirmar Asistencia ] · [ Reprogramar Turno en 1 Clic ] |
4. Seguimiento Automático por Atraso / No-Show (Día +1 a las 09:00 hs) (FechaTurno < Hoy y purchaseOrder.status == "pending" en MongoDB) | 📅 ¿Reprogramamos tu entrega en Ezeiza? — Orden de Envío #{OC} pendiente de ingreso | Tono 100% empático y profesional: *«Notamos que ayer no pudimos recibir tu Orden de Envío #{OC} en el centro de distribución de Ezeiza. Para evitar que tus productos entren en quiebre de stock (lo que representaría una pérdida estimada de ${MontoPerdido} en ventas para {Marca} este mes), habilitamos nuevos horarios prioritarios para esta semana.»*<br>[ Elegir Nuevo Día de Entrega en 1 Clic ] |
5. Escalamiento Automático por Atraso Crítico (Día +4) (FechaTurno + 4d < Hoy y status == "pending", con copia a compras@plant.com.ar) | 🚨 {Marca}: tus productos están entrando en quiebre — reprogramá tu Orden #{OC} | Muestra los SKUs que ya quebraron o quiebran esta semana, el impacto acumulado en pesos y el link de reprogramación inmediata. Si pasan 10 días sin respuesta ni reprogramación, archiva la OC vencida y alerta a Compras. |
6. Especificación Técnica de Implementación (sellers.plantinterno.com + Plant Hub)
6.1. Arquitectura de Datos y Endpoints en sellers.plantinterno.com (Cloudflare Worker + KV + MongoDB/Calendar Bridge)
- Enriquecimiento del Payload por Marca (
armar_marca()enbuild_sellers.py):
- Corrección de
xd(Velocidad Diaria Omnicanal Des-Censurada): - Sumar
v.u.b2c + v.u.b2b + v.u.mlen cada SKU. - Cruzar con la serie histórica de stock para descontar los días con stock
0(diasActivos = max(7, diasVent - diasSinStock)). - Multiplicar por el factor estacional del mes ($K_{\text{estacional}}$).
- Corrección de
enTransitoysug(45–49 díasen bulto cerrado): - Sumar por
pidlas unidades pendientes enpurchaseOrdersconstatus == "pending"y antigüedad $\le 45\text{ días}$. - Calcular
sug45 = max(0, ceil(xd * 47 - (s.av + enTransito)))redondeado al múltiplo depack(UxBulto) que deje la cobertura entre 45 y 49 días. - Inyección de Vencimientos Reales en Stock (
lotsTimestampsdeinventoryAdjustments): - Consultar en
mongoAggregatela coleccióninventoryAdjustmentsfiltrandodata.type == "receive",data.confirmed == trueydata.purchaseOrderdentro de las OCs recibidas de la marca en los últimos 180 días. - Extraer
data.controlReason.lotsTimestamps[pid][lotId]({ e: "YYYY-MM-DD", q: qty }) y adjuntarlo a cada SKU enstkcomolotes: [{ lote, vto, q }]ordenado por FEFO (primero el que vence antes).
- Nuevas Rutas Backend en el Worker de
sellers.plantinterno.com:
GET /<slug>/turnos-ezeiza:- Consulta mediante Service Account / OAuth2 el Google Calendar de Recepción Ezeiza de Mauro (
calendarIdconfigurado en variables de entorno del Worker) usandofreebusy.query/events.listpara los próximos 14 días hábiles, y devuelve los slots disponibles descontando los eventos ya agendados en ese calendario. POST /<slug>/orden-envio:- Recibe
{ items: [{ pid, qty, lotNumber, expDate, promoCommitted }], slotStartIso, slotEndIso, boxesCount, carrierName, remitoNumber, notes }. - Valida en servidor la Regla de Mauro: Para cada ítem, verifica que
expDate >= slotDate + ceil((stockActual + enTransito + qty) / xd) + 30(o quepromoCommitted == trueyexpDate >= slotDate + 45). - Crea el evento en el Google Calendar de Recepción Ezeiza de Mauro (
POST https://www.googleapis.com/calendar/v3/calendars/{EZEIZA_CALENDAR_ID}/events?sendUpdates=all). - Inyecta la
purchaseOrderen Producción (escribiendo en Firestorevivet-web/purchaseOrders/{objectID}para que la Cloud Function oficial la sincronice instantáneamente a MongoDBpurchaseOrdersy Recepción Ezeiza la vea en su pantalla, y guardando copia en KVsellers:envios:{slug}). - Envía el correo de confirmación (
mandar()) desdePortal Planter <avisos@plant.com.ar>con el resumen, el link al evento de Google Calendar y las etiquetas de bulto listas para imprimir. POST /<slug>/orden-envio/reprogramar:- Permite a la marca (desde el portal o desde el link de 1 clic del mail de seguimiento) mover su turno a un nuevo hueco libre del Google Calendar de Mauro, actualizando tanto el evento en Google Calendar (
PATCH /events/{eventId}) comoexpirationDateyreceived.ten lapurchaseOrderde Producción. Cron TriggerDiario en el Worker (scheduled()):- Corre a las
08:30 hsy18:00 hsAR:
- Cruza las
purchaseOrdersconsource == "planter_full_2_0"ystatus == "pending"enmongoAggregate. - Si
slotDate == Mañana, dispara el Recordatorio 24 hs antes y guarda el sello anti-duplicado en KV (mail:rem24:{poId}). - Si
slotDate < Hoyy siguestatus == "pending", dispara el Mail Amable de Reprogramación Día +1 / Día +4 cuantificando la pérdida por quiebre y guarda el sello en KV (mail:late1:{poId}). - Los lunes a las
09:00 hs, para toda marca con SKUs en estadoURGENTEsin OC en tránsito y sin mail en los últimos 7 días, dispara el Mail Semanal de Reposición Sugerida 45–49d.
6.2. Diseño UI/UX en la Pestaña #stock de sellers.plantinterno.com
La pestaña Stock en depósito de sellers.plantinterno.com evoluciona de una tabla estática a un Centro Interactivo de Reposición Full:
- Kpis Superiores Interactivos (Píldoras de Filtro estilo ML Full):
Todos (N)·🔴 Enviar esta semana (N)·🟠 Reponer próx. semana (N)·🟢 Cubiertos 45–49d (N)·⏳ Lotes por vencer <75d (N)·🚚 En camino a Ezeiza (N).
- Columnas de la Tabla Interactiva de Reposición:
- Producto / SKU / UxBulto: Nombre, código interno, EAN y tamaño de bulto master.
- Stock Actual + En Camino: Unidades disponibles en Ezeiza + badge azul
+X u. en OC #18290 (Turno 04/11)+ píldora de vencimiento del lote actual en Ezeiza (Vto: 15/03/2027leído delotsTimestamps). - Venta Real (
30dyu./día): Velocidad diaria omnicanal (Web + B2B + ML) sin sesgo de quiebre. - Cobertura Actual: Días de stock actuales con barra de progreso y estado.
- Sugerido Plant (
45–49d): Cantidad sugerida en unidades y bultos cerrados (ej. 450 u. · 15 cajas). - Input
Cantidad a Enviar+ Simulador Persuasivo de Gaby en Vivo: - Input numérico editable (precargado por defecto con el sugerido en los SKUs urgentes/a reponer, con botones
- / + 1 bulto). - Si el usuario baja la cantidad por debajo de los 45 días, se despliega en vivo debajo de la celda la alerta roja:
⚠️ Quebrás en X días y perdés de facturar $XXX.XXX este mes.
- Columna
Vto. Mínimo Exigido(Calculadora Dinámica de Mauro en Vivo): - Muestra en vivo la fecha mínima que debe tener el lote según la cantidad tipeada:
📅 Exigido: ≥ DD/MM/AAAA (X días) (= Xd de venta + 30d margen consumidor).
- Input opcional al lado:
Vto. de tu lote: [ DD/MM/AAAA ]. Si la marca ingresa un vencimiento más corto que el exigido, calcula en el acto el tope máximo de unidades aceptables para ese lote o le ofrece tildar[✓] Comprometer Promo FEFO -25% a 45d del vto.
- Barra Inferior Flotante (
Sticky Action Bar) + Modal de Turno en Google Calendar de Ezeiza:
- Muestra en tiempo real:
📦 Orden de Envío: {SKUs} productos · {Unidades} u. ({Bultos} bultos) · Facturación proyectada: ${MontoTotal}
*(+ Alerta ámbar si está dejando plata en la mesa por sub-envío en algún SKU)*.
- Botón principal:
Continuar y Elegir Turno en Ezeiza →. - Al hacer clic, abre el modal de Reserva de Turno conectado al Google Calendar de Recepción Ezeiza de Mauro, pide confirmar cantidad de bultos/transporte y genera la
purchaseOrder+ el evento de calendario + las etiquetas PDF.
7. Plan de Ejecución e Hitos de Despliegue
- Paso 1 (Configuración del Calendario con Mauro): Obtener el ID del Google Calendar de Recepción Ezeiza que hoy usa Mauro (o compartirlo con permisos de edición a
avisos@plant.com.ar/ Service Account de Plant) para que el Worker lea los huecos libres y cree los turnos ahí mismo. - Paso 2 (Despliegue en
sellers.plantinterno.com—worker/build_sellers.py):
- Activar la velocidad omnicanal des-censurada (
B2C + B2B + ML Fullsin días en quiebre) y el sugerido de 45–49 días descontando stock en tránsito. - Mostrar los vencimientos reales de Ezeiza (
inventoryAdjustments.lotsTimestamps) en la tabla de Stock. - Incorporar en la pestaña
#stockla Calculadora Dinámica en Vivo de Vencimiento Mínimo de Mauro y el Simulador Persuasivo de Pérdida de Ventas de Gaby. - Habilitar el flujo de Confirmar Orden de Envío + Reserva de Turno en el Google Calendar de Mauro + Inyección de
purchaseOrder+ Bots de Correo (avisos@plant.com.ar).
- Paso 3 (Sincronización en
Plant Hub—apps/supplier):
- Reemplazar
getSupplierSellerSchedule(hardcodeado) por la lectura del Google Calendar de Ezeiza +SupplierAdvanceShippingNotice. - Agregar la elección de turno como Paso 5 dentro de
NewShipmentForm.tsxy sumar la validación dinámica de vencimiento mínimo de Mauro en el Paso 2 (Lotes y Vencimientos FEFO).
8. Distinción Legal y Operativa sobre Vencimientos: Planter (Consignación) vs. Compra-Venta Tradicional y Auditoría de la Presentación / Acuerdo Planter
Fuentes verificadas:
- Audio de Gaspar Howlin del
2026-10-28 14:48 hs(5491123492819@s.whatsapp.net). - Mail de Mauro Stoessel a Gaspar Howlin del
2026-10-26 10:19 hs(messageId: 1a177b87c93eebb3, Asunto:"Marcas Planter con Corto VTO"). - Base maestra Planter
DB Clientes(scripts/planter_reglas.py) ysellers.plantinterno.com. - Presentación PPTX/PDF (
Drive/Compras/Gaspar Howlin/PLANTER/Modelo Planter _ Productores Conscientes 2026.pptx.pdf), Web Oficial (https://plant-modelo-planter.pages.dev/·masters/plant_modelo_planter_v1_backup.htmlyv2.html), Planillas de Alta (Drive/Compras/ALTAS PLANT/Alta Proveedor 2026 - Plant.xlsx) ydocs/PLANTER-liquidacion.md.
8.1. Hallazgo Forense Crítico: HM Granola (Homemade) y Yasmín (Jasmine) SÍ son Marcas Planter (100% Consignación)
- El lunes
26/10/2026 a las 10:19 hs, Mauro Stoessel le envió a Gaspar un correo con el asunto literal"Marcas Planter con Corto VTO"(1a177b87c93eebb3), listando 9 marcas Planter:
Homemade(HM Granola, Entidad1678,comercial@homemadegranola.com.ar/info@homemadegranola.com.ar):GRRRANHO(800g: 3 u vto03/11/26+ 47 u vto10/11/26) yCEREALLHOM(300g: 21 u vto03/11/26). Tiene 29 SKUs activos en Planter consiPlant: 0, siML: 0(0 unidades compradas en firme antes de Planter; 100% consignación).Jasmine(Yasmín, Entidad1660,medranocesar280374@gmail.com):JASMGGRA(Granola Castañas y Cacao 250g: 13 u vto12/11/26). Tiene 14 SKUs activos en Planter consiPlant: 0, siML: 0(100% consignación).- Junto con:
La Zaranda(ent 1688),Mami Keto(ent 3450),Trantefu(ent 1669),Frank'S(ent 1723),Natural Bread(ent 263),Onneg(ent 1272) yMolino De Piedra(ent 1640).
- **Por qué es un error conceptual decir *"intento negociar un descuento y que no tengamos que absorber todo eso nosotros"* en una marca Planter:**
- Si el lote Planter vence en Ezeiza sin venderse: Como el liquidador de Planter (
worker/build_sellers.py) sólo liquida unidades efectivamente entregadas (shipmentState == "delivered"), las unidades vencidas no vendidas jamás entran en la liquidación del día 20 y Plant paga$0. La pérdida del producto vencido es 100% de la marca, nunca de Plant. - Si se activa una promo de liquidación por corto vencimiento (
-30%/-50%OFF): En el motor actual desellers.plantinterno.com(docs/PLANTER-liquidacion.md§1 y §3.5), cada unidad vendida se liquida alpurchasePriceneto (lista de costo de compra de la marca en MongoDB) + IVA 21%. Por eso, cuando un lote Planter entra en corto vencimiento, no se "negocia para que el proveedor nos reconozca algo", sino que se le notifica a la marca que su mercadería está por vencer (y que si vence cobrará$0) para que elija entre:
- Retirar inmediatamente su lote de Ezeiza a su cargo, o
- Activar una liquidación por corto vencimiento (
-30%a-50%OFF) bajando en igual proporción elpurchasePricede liquidación de ese lote, de modo que la marca recupere el 50%–70% de su mercadería antes de que venza y el margen de Plant quede 100% intacto.
8.2. Qué Dicen Textualmente Hoy la Presentación, la Web y el Alta del Modelo Planter (y qué Cláusula se Agrega)
- Presentación PPTX/PDF (
Modelo Planter Productores Conscientes 2026.pptx): - Slide 4 (Paso 1): *"La mercadería sigue siendo tuya hasta que se vende. No hay compra anticipada ni compromiso mínimo."*
- Slide 5 (Paso 6): *"Cierre el día 20 de cada mes. Recibís el informe y facturás lo vendido. Plant paga a 30 días mediante echeq."*
- *(No menciona vencimientos ni mermas).*
- Web Oficial (
https://plant-modelo-planter.pages.dev/·masters/plant_modelo_planter_v1_backup.htmlyv2.html): - Paso 01: *"La mercadería sigue siendo tuya hasta que se vende. Sin compra anticipada ni compromiso mínimo."*
- Blindaje 6 (
v2): *"Tu mercadería es legal y operativamente tuya hasta el segundo en que se entrega."* - FAQ 1 (
¿Y si un producto no rota?): *"Si algo no funciona, lo trabajamos juntos — y el stock es tuyo, siempre: lo retirás cuando quieras. Los vencimientos se gestionan con alertas anticipadas."* - FAQ 4 (
¿Quién controla mis precios?): *"Vos. Los precios se definen de común acuerdo y cualquier acción de promo se conversa antes. La mercadería sigue siendo tuya hasta que se vende."* - FAQ 5 (
¿Cómo y cuándo cobro?): *"Se dispara solo por lo vendido, con la trazabilidad del reporte semanal."* - Cláusula Explícita de Corto Vencimiento Planter a Incorporar en Web y Alta Proveedor:
*"Como la mercadería permanece en propiedad de la marca hasta su entrega efectiva, las unidades que alcancen su vencimiento sin haberse vendido no generan liquidación ni pago alguno por parte de Plant y quedan a disposición de la marca para su retiro. Cuando un lote alcance menos de 60 días de vida útil remanente, el sistema notificará a la marca para que en un plazo de 48 hs opte entre: (a) retirar el lote de Ezeiza, o (b) activar descuentos de liquidación rápida (-30% a -50% OFF), reduciéndose en igual proporción el valor neto de liquidación (purchasePrice) de las unidades vendidas bajo dicha acción para recuperar capital antes del vencimiento."*8.3. Matriz de Blindaje de Vencimientos según Modalidad Comercial (Riesgo $0 para Plant)
| Dimensión | Modalidad Planter Full 2.0 (Consignación) (Homemade, Jasmine, La Zaranda, Mami Keto, etc.) | Modalidad Compra-Venta Tradicional |
|---|---|---|
| Propiedad legal del stock en Ezeiza | 100% de la marca (Seller) hasta que se vende (StockQuant.ownerId = sellerEntityId). Si vence sin venderse, no entra en liquidación y Plant paga $0. | Propiedad de Plant una vez recibida y facturada la Orden de Compra. |
| Barrera 1 · En la Puerta de Entrada (Pre-Envío y Recepción Ezeiza) | Calculadora Dinámica de Mauro en el Portal (sellers.plantinterno.com):<br>Al turnar el envío, exige que el lote tenga como mínimo:<br>FechaVto ≥ FechaTurno + DíasAgotamiento(StockActual + EnTránsito + CantidadAEnviar) + 30 días (margen consumidor final).<br>Si el lote vence antes, el portal bloquea el excedente (limitando las unidades a lo que se vende 30d antes del vto) o exige que la marca deje firmada y pre-aprobada una Promo FEFO atada a ese lote. | Techo Duro de Cobertura del Motor de Compras 2.0:<br>Se prohíbe comprar más de 30 días de cobertura total en productos secos/generales y 21 días en perecederos/vida útil corta, más validación de vida útil mínima en muelle contra lotsTimestamps. |
| Barrera 2 · Durante la Estadía en Ezeiza (Escalera Automática FEFO) | Regla Automática contractual (Cero negociación de absorción):<br>• A los 60 días del vto: Alerta automática en el portal y por mail (avisos@plant.com.ar) para que la marca elija en 48 hs entre retirar su lote o autorizar liquidación FEFO.<br>• A los 45 días del vto (si el stock remanente supera lo vendible antes de Vto - 30d): Se activa la liquidación FEFO reduciendo en el mismo % el purchasePrice de liquidación de ese lote, o se pasa a retiro obligatorio de la marca.<br>• A los 30 días del vto (piso de calidad al consumidor): El lote se bloquea automáticamente para la venta (QUARANTINED / SOON_TO_EXPIRE) y queda a disposición de retiro de la marca (pago $0 de Plant). | Alerta Temprana FEFO a los 75/60 días (lotsTimestamps):<br>Si un lote de compra firme cae por debajo de su curva de evacuación, dispara acción promocional inmediata y reclamo automático temprano al proveedor 60 días antes de vencer (y no sobre la hora). |
Novedades
- Aclaración de Gaspar Howlin y blindaje legal/operativo de vencimientos Planter vs. Compra-Venta (2026-10-28 14:48 hs · WhatsApp
5491123492819@s.whatsapp.net): Gaspar aclaró que nunca indicó que Plant absorba los vencimientos, sino que Mauro le pasa los lotes próximos a vencer (comoHM Granola,PolibrayYasmín) para que él llame al proveedor e intente negociar un descuento o reconocimiento. Queda asentado por escrito en la especificación de Planter Full 2.0 que en Planter (Consignación) la mercadería es 100% propiedad del seller hasta su venta, por lo que no depende de negociación manual: el portal exige (1) vida útil mínima dinámica al turnar (DíasAgotamiento + 30d margen consumidor) y (2) regla automática FEFO a los 60/45 días del vencimiento (descuento absorbido por la liquidación de la marca o retiro del lote por el proveedor, riesgo$0para Plant); mientras que en Compra-Venta tradicional el blindaje lo da el nuevo techo de cobertura de30 días(21 díasen perecederos) del Motor de Compras 2.0. · 👥 Personas/gaspi|gaspi, Personas/mauro-stoessel-vivet|mauro-stoessel-vivet · 🔗 auto-calculo-compras-reposicion-stock, motor-compras-2-0-plan-maestro-noviembre
- Decisión: Igualación de semanas de stock al lead time con ajuste de fill rate (2026-10-28 · 🎙️ Reuniones/2026-10-28 motor-de-compras-y-optimizacion-de-stock-gaby-ma.md|Motor de Compras y Optimización de Stock (Gaby \+ Mauro)): Se acuerda igualar las semanas de stock al lead time del proveedor combinándolo con un colchón de seguridad por producto basado en el fill rate. · 👥 Personas/mauro-stoessel-vivet|mauro-stoessel-vivet, Personas/gaspi|gaspi, Personas/juanchi-busso|juanchi-busso · 🔗 auto-calculo-compras-reposicion-stock, motor-compras-2-0-plan-maestro-noviembre
Novedades
- Decisión: Conservación de incrementos de stock manuales con estacionalidad (2026-10-28 · 🎙️ Reuniones/2026-10-28 motor-de-compras-y-optimizacion-de-stock-gaby-ma.md|Motor de Compras y Optimización de Stock (Gaby \+ Mauro)): Se decide mantener la opción de incrementos manuales de stock para excepciones operativas del proveedor, complementándolos con factores de estacionalidad por ítem. · 👥 Personas/mauro-stoessel-vivet|mauro-stoessel-vivet, Personas/gaspi|gaspi, Personas/juanchi-busso|juanchi-busso · 🔗 motor-compras-2-0-plan-maestro-noviembre, auto-calculo-compras-reposicion-stock
Novedades
- Decisión: Inclusión de datos en promedios de venta (2026-10-28 · 🎙️ Reuniones/2026-10-28 motor-de-compras-y-optimizacion-de-stock-gaby-ma.md|Motor de Compras y Optimización de Stock (Gaby \+ Mauro)): Se acordó considerar todos los datos de venta de los días en que el producto tuvo stock en lugar de desestimarlos. · 👥 Personas/mauro-stoessel-vivet|mauro-stoessel-vivet, Personas/gaspi|gaspi, Personas/juanchi-busso|juanchi-busso · 🔗 motor-compras-2-0-plan-maestro-noviembre, auto-calculo-compras-reposicion-stock
Novedades
- Compromiso (Gaspi) (2026-10-29 · 🎙️ Reuniones/2026-10-29 acciones-comerciales.md|Acciones comerciales): Pedir stock — Solicitar a los proveedores el medio palet de los tres sabores de productos pendientes para cubrir la demanda. · 👥 Personas/gaspi|gaspi · 🔗 acuerdos-comerciales, salud-dental-alineadores, motor-compras-2-0-plan-maestro-noviembre, auto-calculo-compras-reposicion-stock · #marca:pura-frutta #evento:cajas-navidenas #objetivo:habilitacion-municipal-ezeiza
Novedades Recientes
- 2026-10-29 13:08 — Interacción con mauro-stoessel-vivet, portal-planter-avisos-plant-com-ar: 📌 *ESTADO EXACTO DE LAS MEJORAS EN PORTAL PLANTER (
SELLERS.PLANTINTERNO.COM·PLANTER FULL 2.0)*
━━━━━━━━━━━━━━
Acabo de auditar el código en vivo de sellers.plantinterno.com (worker/build_sellers.py, sección #stock) contra la especificación maestra de *Planter Full 2.0*. Acá tenés exactamente qué está subido hoy y qué quedó en diseño listo para desplegar:
*1. Qué YA está en vivo hoy en el portal (sellers.plantinterno.com)*
• *Tabla «Stock y envíos» (#stock)*: Hoy tiene 4 columnas activas (*Producto*, *Stock en Plant + Full ML*, *Cobertura en días* y *Sugerido a 45 días*) más el cartel superior de alerta de quiebre (*«Para hacer: X producto se queda sin stock en N días. Mandá Y u.»*).
• *Limitación actual*: Ese Sugerido hoy es solo un número estático (calculado sobre B2C + B2B sin sumar ML ni descontar días quebrados) y *todavía no tiene la columna de vencimiento ni el flujo interactivo*.
━━━━━━━━━━━━━━
*2. Qué quedó diseñado en «Planter Full 2.0» pero AÚN NO se inyectó en producción*
• *1) Columna Vto. por lote al lado del Stock*: Quedó especificada y maquetada en el prototipo, pero falta conectarla en build_sellers.py leyendo la pestaña *Stock y Vencimiento* de la planilla de Mauro (Armar Pedido Cálculos) + lotsTimestamps de Ezeiza para que la marca vea la fecha exacta de vencimiento de su stock actual.
• *2) Alertas de Corto de Fecha (<60d / <45d) con decisión a cargo de la marca*: Hoy el portal solo alerta por *falta de stock* (<14 días), pero aún no muestra el banner de *lote próximo a vencer* para que el seller elija con un clic entre *autorizar un descuento de liquidación a su cargo* (bajando su liquidación en igual %) o *programar el retiro*.
• *3) Sugerencia y Orden de Envío interactiva desde el portal*: Falta convertir el número fijo de Sugerido en el flujo interactivo donde el seller:
— Ve el sugerido real omnicanal a *45–49 días* (*Plant + Business + ML Full*, descontando días en stock cero) y cuánta venta pierde en pesos si manda de menos.
— Carga qué cantidad va a enviar y qué *fecha de vencimiento* tiene el lote nuevo, validado en vivo contra la *calculadora de vencimiento mínimo de Mauro* (Días hasta agotar stock actual y nuevo + 30 días de margen al consumidor).
━━━━━━━━━━━━━━
👉 *¿Querés que pongamos ahora mismo a inyectar y desplegar estas 3 mejoras directo en el worker productivo de sellers.plantinterno.com conectadas a la hoja de Stock y Vencimiento de Mauro?* · 🔗 auditoria-vivet-vencimientos-plant-hub, monitores-planter, monitores-plantinterno, acuerdos-comerciales, radar-marketing, plant-cyber-2026, camaras-frio-ezeiza-reemplazo-compresor, motor-compras-2-0-plan-maestro-noviembre, arqueologia-comunidad-gabriel-busso-instagram, activacion-patrimonio-camaras-tixo-vivet, fabrica-multimedia-autor-omnicanal, auto-calculo-compras-reposicion-stock, biblioteca-viva-del-super-cerebro · 2026-10-29
- Entrada (wacli · 𝗘𝗟𝗘𝗩𝗔𝗥 𝗖𝗢𝗡𝗖𝗜𝗘𝗡𝗖𝗜𝗔 · Niké): 📚 *PLAN MAESTRO RADICAL 2.0 (
OPUS · CODEX · GROK) · 1.000 LIBROS EN 90 DÍAS (++$16,8MNETOS CON 0% TIEMPO TUYO)* ━━━━━━━━━━━━━━ *1. El hallazgo en Ezeiza que duplica la velocidad de recupero* • Auditamos el stock físico hoy en Ezeiza y encontramos que tenés **1.120 ejemplaresde *El Arte de Dirigir* ya impresos y 100% pagados** (más32 u.de *Ser la Mejor Versión* y21 combos). • *La jugada maestra*: Al armar en Mercado Libre Full el **Pack Dúo (*Ser la Mejor Versión* + *El Arte de Dirigir*) a$44.900con Envío Gratis*, el segundo libro tiene *costo de caja$0*. Cada Pack Dúo te · 2026-10-27 18:31
- Entrada (wacli · 𝗘𝗟𝗘𝗩𝗔𝗥 𝗖𝗢𝗡𝗖𝗜𝗘𝗡𝗖𝗜𝗔 · Niké): 📌 *ESTADO EXACTO DE LAS MEJORAS EN PORTAL PLANTER (
SELLERS.PLANTINTERNO.COM·PLANTER FULL 2.0)* ━━━━━━━━━━━━━━ Acabo de auditar el código en vivo desellers.plantinterno.com(worker/build_sellers.py, sección#stock) contra la especificación maestra de *Planter Full 2.0*. Acá tenés exactamente qué está subido hoy y qué quedó en diseño listo para desplegar: *1. Qué YA está en vivo hoy en el portal (sellers.plantinterno.com)* • *Tabla «Stock y envíos» (#stock)*: Hoy tiene 4 columnas activas (*Producto*, *Stock en Plant + Full ML*, *Cobertura en días* y *Sugerido a 45 días*) más el · 2026-10-29 13:08
Novedades Recientes
- 2026-10-29 19:11 — Interacción con martina-ramundo, gaspi, juanchi-busso: 📌 *AUDITORÍA FORENSE Y CONEXIÓN OMNICANAL:
AUTORIZAR DESCUENTO(providerDiscount) +PRECIOS PARA ML+PLANT HUB*
━━━━━━━━━━━━━━
Corrimos el escuadrón completo (claude --model opus --effort high + codex gpt-6.1-sol, sesión 01a189ae-1ed6-7650-a2a1-31635c31e628 + QA Playwright E2E) auditando el código de sellers.plantinterno.com, las colecciones reales de MongoDB Producción (campaigns, products, orders), la planilla de Marti y Gaspi (*"Datos Mercado Libre" → "Precios para ML"*) y el repositorio de *Plant Hub*.
*1. ¿Qué hacía hasta hoy el botón Autorizar descuento en sellers.plantinterno.com?*
• *El punto ciego que tenía*: cuando apretabas Autorizar descuento, el worker (stockBetaGuardar) *sólo guardaba un registro en el KV sellers:beta:promos* y el cartel decía que ya estaba activo en los 3 canales, pero *en realidad no tocaba nada*:
- Ni siquiera la función
liquidar()(pdParaML) del propio portal leía ese KV (sellers:beta:promos). - No creaba la campaña en MongoDB (
campaignsconarea: "compras") ni bajaba el precio enplant.com.ar/business.plant.com.ar(maxDiscounts). - No le avisaba a *Marti Ramundo* ni a *Gaspi Howlin*, ni actualizaba la hoja *"Precios para ML"*, ni cambiaba el precio en *Mercado Libre* (ni en la publicación individual
1xni en los packsNN-CODIGO).
*2. ¿Cómo funciona de verdad hoy el circuito en plant.com.ar, Business y Mercado Libre?*
• *En plant.com.ar (B2C) y business.plant.com.ar (B2B)*: son *dos pasos separados* en MongoDB Producción (lo verificamos con las 10 campañas de Cyber que cargaron hoy mismo):
- *Gaspi* crea el documento en
campaignscondata.area: "compras". Eso hace que cada orden entregada salga estampada conitems.<pid>.providerDiscount = { id, d }, para que la liquidación Planter le descuente ese porcentaje al proveedor. - *Marti* actualiza en
productslos camposdata.maxDiscounts: { g, d }ydata.priceWithDiscount: { g, d }para que el descuento se vea reflejado en el precio al público enplant.com.ar(g) ybusiness.plant.com.ar(d).
• *En Mercado Libre (la planilla de Marti y Gaspi)*:
- Hoy operan sobre la Google Sheet *"Datos Mercado Libre"* → pestaña *"Precios para ML"* (
3.295publicacionesMLAmapeadas, incluyendo unidades1xy packsNN-CODIGOcomo06-o12-). - En la *Columna E (
CAMPAÑA ACTIVA)*, Gaspi escribe el formato exacto"{desc}% - ${costo_con_dto}"(hoy hay 575 filas activas así). *Detalle clave de packs*: en esa planilla, la fila del pack12-CODIGOya tiene en la Columna D el costo multiplicado por 12, por lo que en la Columna E de cada pack también hay que escribir el costo del pack con descuento ("{desc}% - ${costo_pack_con_dto}"). - Con esa Columna E, la planilla recalcula la *Columna R (
PRECIO ML CON DTO)* descontando Comisión ML (18,6%), IVA, Percepciones y escalas de$ ENVIOFull para bajar el precio en Mercado Libre manteniendo *100% intacto el margen de Plant*.
*3. ¿Qué dejamos conectado y desplegado YA MISMO en sellers.plantinterno.com?*
• *1) Estado real autorizado → aplicado con tope por lote (unidadesLote)*: como detectó Claude Opus, si liquidáramos el descuento apenas la marca aprieta "Autorizar" pero antes de que Marti/Gaspi bajen el precio al público, le cobraríamos a la marca un descuento que el cliente nunca vio. Ahora nace como autorizado y, cuando se activa (aplicadoDesde), liquidar() (pdParaML) lo descuenta automáticamente en las ventas de Mercado Libre y Plant hasta agotar las unidadesLote de ese lote.
• *2) Cruce automático de todas las publicaciones MLA (1x y packs NN-CODIGO)*: al abrir o confirmar un descuento en sellers.plantinterno.com, el modal cruza el SKU contra ml:mapa y stockmap y muestra la *tabla completa de publicaciones MLA alcanzadas (individual y packs)* con el texto exacto listo para copiar y pegar en la *Columna E (CAMPAÑA ACTIVA: "25% - $3300")* de la planilla de Marti + el botón *«Copiar Col E para Precios para ML»*.
• *3) Capa persistente ml:mapa:camp*: guarda el costo promocional de cada MLA en una clave separada (ml:mapa:camp) que se superpone sobre ml:mapa, para que el cron de las 08:00 AM (refrescarMapaML) no lo pise si todavía no lo cargaron en el Excel.
*4. ¿Juanchi contempló eliminar el Excel de Marti y Gaspi en Plant Hub? (Los 4 huecos encontrados)*
• Auditamos todo packages/business-logic/src/mercadolibre/ en Plant Hub. Juanchi armó una base excelente (listing-prices.ts, listing-profitability.ts, listing-promotions.ts, omnichannel-price.ts), *PERO hoy NO puede jubilar el Excel de Marti y Gaspi* porque le faltan *4 piezas críticas*:
- *No existe
providerDiscounten la base de datos dePlant Hub*: niPromotion(marketing.prisma), niOrderItem(order.prisma), niSellerSettlementtienenproviderDiscountBps(descuento absorbido por la marca). Hoy si creás una promo enPlant Hub, Plant absorbe el 100% de la pérdida y no se descuenta de la liquidación Planter. - *Los guardrails de margen de
Plant Hubbloquean los descuentos de proveedores*: tantoassertPromotionGrossMargincomocalculateListingProfitabilityvalidan el precio con descuento contrapurchasePricebruto en vez depurchasePrice * (1 - providerDiscountBps). Si una marca autoriza-35%para salvar un lote,Plant Hubcree que Plant vende a pérdida (InsufficientListingMarginError) y *bloquea la promoción*. - *
listing-promotions.tsenPlant Hubes 100% de solo lectura (GET)*: sólo lee promociones de ML (GET /seller-promotions/items/{id}), pero *no tiene elPOST /seller-promotions/items/{id}* para activar unPRICE_DISCOUNTcon precio tachado en Mercado Libre ni propagarlo automáticamente a los packsNN-CODIGO(unitsPerListing). - *La fórmula de rentabilidad ML (
listing-profitability.ts) tiene un bug de IVA y le faltan Percepciones y Envío Full*: en la línea 26 el propio código tiene un comentario admitiendo que compara el precio ML *con IVA* contra el costo *sin IVA* (inflando el margen ~17 puntos), no resta *Percepciones (~3-5%)* y tienefreeShippingCostCents = 0en vez de las escalas de envío Full de la planilla de Marti.
*5. Especificación lista para mandarle a Juanchi (¿querés que se la mande?)*
• Armamos el instructivo técnico exacto de 4 puntos para Juanchi (modelo SupplierDiscountAuthorization + providerDiscountBps en Promotion/OrderItem/SellerSettlement, costo efectivo en listing-profitability.ts corrigiendo IVA/Percepciones/Envío Full, y mutación POST en listing-promotions.ts propagando a packs NN-CODIGO) para que cuando una marca autorice un descuento o cambie un costo, impacte directo en Plant, Business y Mercado Libre y *jubilemos para siempre el Excel "Precios para ML" de Marti y Gaspi*. ¿Te parece bien que le mande esta especificación a Juanchi? · 🔗 plant-cyber-2026, monitores-planter, monitores-plantinterno, acuerdos-comerciales, radar-marketing, procedimiento-campanas-plant, planter, lunes-05-octubre-plan-ejecucion-gaby, estado-vivo-marcas-proveedores, motor-compras-2-0-plan-maestro-noviembre, mercado-libre-flex-congelados-simulador-mcp, arqueologia-comunidad-gabriel-busso-instagram, fabrica-multimedia-autor-omnicanal, auto-calculo-compras-reposicion-stock, envio-a-full-ml-estrategia-cyber, plant-hub, biblioteca-viva-del-super-cerebro #estrategia:cyber-2026 #objetivo:liquidacion-planter · 2026-10-29
- Entrada (wacli · 𝗘𝗟𝗘𝗩𝗔𝗥 𝗖𝗢𝗡𝗖𝗜𝗘𝗡𝗖𝗜𝗔 · Niké): 📌 *AUDITORÍA FORENSE Y CONEXIÓN OMNICANAL:
AUTORIZAR DESCUENTO(providerDiscount) +PRECIOS PARA ML+PLANT HUB* ━━━━━━━━━━━━━━ Corrimos el escuadrón completo (claude --model opus --effort high+codexgpt-6.1-sol, sesión01a189ae-1ed6-7650-a2a1-31635c31e628+ QA Playwright E2E) auditando el código desellers.plantinterno.com, las colecciones reales de MongoDB Producción (campaigns,products,orders), la planilla de Marti y Gaspi (*"Datos Mercado Libre" → "Precios para ML"*) y el repositorio de *Plant Hub*. *1. ¿Qué hacía hasta hoy el botónAutorizar descuentoen `s · 2026-10-29 19:11
Temas/planter-full-2-0-especificacion-maestra