📦 Multi-Shipment System — PrestaShop 9.1

Actualizado: 2026-04
ℹ️
Feature Flag — Beta

El Multi-Shipment System esta disponible en PS 9.1 bajo el feature flag improved_shipment. Desactivado por defecto. Activalo en Parametros Avanzados → Feature Flags para probar.

#Introduccion al Multi-Shipment

Históricamente, PrestaShop funcionaba con un modelo 1 pedido = 1 transportista. Esto generaba problemas cuando un cliente queria productos enviados por diferentes transportistas (ej: un producto pesado por mensajeria y otro digital por email).

El nuevo sistema de Multi-Shipment cambia el paradigma: 1 pedido = N envios, donde cada envio puede tener su propio transportista, direccion de envio y productos asignados.

#Activar el feature flag

Activar Multi-Shipment via SQL
sql
-- Activar el feature flag de shipment
UPDATE ps_feature_flag SET state = 1 WHERE name = 'improved_shipment';

-- Tambien disponible en:
-- Back Office → Parametros Avanzados → Feature Flags → Improved Shipment

Tambien se puede activar desde el Back Office en Parametros Avanzados → Experimental Features (Feature Flags).

#Arquitectura del sistema

El modelo pasa de ser centrado en el pedido a ser centrado en el envio (shipment):

Diagrama de relacion
text
┌──────────┐     ┌───────────────┐     ┌─────────────────────┐
│  Order   │ 1:N │   Shipment    │ 1:N │  Shipment_Product   │
│          │────→│               │────→│                     │
│ id_order │     │ id_shipment   │     │ id_shipment_product │
│ reference│     │ id_order      │     │ id_shipment         │
│ total    │     │ id_carrier    │     │ id_order_detail     │
│          │     │ id_address    │     │ quantity            │
│          │     │ shipping_cost │     └─────────────────────┘
│          │     │ tracking_num  │
│          │     │ date_shipped  │
│          │     │ date_delivered│
└──────────┘     └───────────────┘

#Nuevas tablas de base de datos

ps_shipment — tabla principal de envios
sql
CREATE TABLE IF NOT EXISTS `PREFIX_shipment` (
    `id_shipment`           INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `id_order`              INT(10) UNSIGNED NOT NULL,
    `reference`             VARCHAR(64) DEFAULT NULL,
    `id_carrier`            INT(10) UNSIGNED NOT NULL DEFAULT 0,
    `id_address_delivery`   INT(10) UNSIGNED NOT NULL DEFAULT 0,
    `shipping_cost_tax_excl` DECIMAL(20,6) NOT NULL DEFAULT 0.000000,
    `shipping_cost_tax_incl` DECIMAL(20,6) NOT NULL DEFAULT 0.000000,
    `date_packing`          DATETIME DEFAULT NULL,
    `date_shipping`         DATETIME DEFAULT NULL,
    `date_delivery`         DATETIME DEFAULT NULL,
    `date_cancel`           DATETIME DEFAULT NULL,
    `tracking_number`       VARCHAR(255) DEFAULT NULL,
    `date_add`              DATETIME NOT NULL,
    `date_upd`              DATETIME NOT NULL,
    PRIMARY KEY (`id_shipment`),
    KEY `id_order` (`id_order`),
    KEY `id_carrier` (`id_carrier`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ps_shipment_product — productos por envio
sql
CREATE TABLE IF NOT EXISTS `PREFIX_shipment_product` (
    `id_shipment_product`   INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `id_shipment`           INT(10) UNSIGNED NOT NULL,
    `id_order_detail`       INT(10) UNSIGNED NOT NULL,
    `quantity`              INT(10) UNSIGNED NOT NULL DEFAULT 0,
    PRIMARY KEY (`id_shipment_product`),
    KEY `id_shipment` (`id_shipment`),
    KEY `id_order_detail` (`id_order_detail`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

#Flujo de un pedido multi-envio

#Back Office — gestion de envios

En la pagina de detalle del pedido (Order View V2), aparece una nueva seccion Shipments que muestra cada envio con:

#Checkout multicarrier

El checkout ahora agrupa productos por transportista disponible. Si un producto solo puede enviarse por un carrier especifico, aparecera en un grupo separado. El cliente ve el desglose de costes por envio.

#Hooks relacionados

PS 9.1 añade hooks especificos para el sistema de envios:

HookTipoDescripcion
actionOverrideShippingFreePriceActionPermite sobreescribir el calculo de envio gratis por precio
actionOverrideShippingFreeWeightActionPermite sobreescribir el calculo de envio gratis por peso
displayAdminOrderMainDisplaySeccion principal donde se muestra la info de shipments
displayAdminOrderSideDisplaySidebar del pedido — info complementaria de envios
💡
Hooks futuros

El sistema de Multi-Shipment esta en desarrollo activo. Se esperan mas hooks especificos para shipment events (actionShipmentStatusUpdate, displayShipmentDetail, etc.) en proximas versiones.

#Impacto en modulos existentes

Si tu modulo interactua con pedidos, envios o transportistas, necesitas adaptarlo:

Modulo / FuncionalidadImpactoAccion requerida
Modulos de carrierAltoSoportar multiples shipments por pedido. El carrier ya no es unico por order.
Modulos de trackingAltoCada shipment tiene su tracking_number independiente. No asumir 1 tracking por pedido.
Modulos de facturacionMedioLos albaranes pueden generarse por shipment, no solo por pedido.
Modulos de emailMedioLos emails de envio deben referenciar el shipment especifico.
Modulos de dashboardBajoLas estadisticas de envio pueden desglosarse por shipment.
Modulos de pagoBajoEl flujo de pago no cambia significativamente.

#Migracion desde sistema legacy

Al activar el feature flag, los pedidos existentes se migran automaticamente: se crea un Shipment por cada pedido existente con todos sus productos. No se pierde informacion.

Detectar si Multi-Shipment esta activo
php
// Verificar si el feature flag esta activo
use PrestaShop\PrestaShop\Core\FeatureFlag\FeatureFlagManager;

// Via servicio (PS 9)
$featureFlagManager = $this->get('prestashop.core.feature_flag.manager');
if ($featureFlagManager->isEnabled('improved_shipment')) {
    // Multi-Shipment activo — usar nueva logica
} else {
    // Modo legacy — 1 carrier por pedido
}

// Via SQL directo (compatible PS 8+9)
$isEnabled = (bool) Db::getInstance()->getValue(
    'SELECT state FROM ' . _DB_PREFIX_ . 'feature_flag WHERE name = "improved_shipment"'
);
Descargar en Markdown Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.