📦 Multi-Shipment System — PrestaShop 9.1
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 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):
┌──────────┐ ┌───────────────┐ ┌─────────────────────┐
│ 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
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;
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:
| Hook | Tipo | Descripcion |
|---|---|---|
| actionOverrideShippingFreePrice | Action | Permite sobreescribir el calculo de envio gratis por precio |
| actionOverrideShippingFreeWeight | Action | Permite sobreescribir el calculo de envio gratis por peso |
| displayAdminOrderMain | Display | Seccion principal donde se muestra la info de shipments |
| displayAdminOrderSide | Display | Sidebar del pedido — info complementaria de envios |
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 / Funcionalidad | Impacto | Accion requerida |
|---|---|---|
| Modulos de carrier | Alto | Soportar multiples shipments por pedido. El carrier ya no es unico por order. |
| Modulos de tracking | Alto | Cada shipment tiene su tracking_number independiente. No asumir 1 tracking por pedido. |
| Modulos de facturacion | Medio | Los albaranes pueden generarse por shipment, no solo por pedido. |
| Modulos de email | Medio | Los emails de envio deben referenciar el shipment especifico. |
| Modulos de dashboard | Bajo | Las estadisticas de envio pueden desglosarse por shipment. |
| Modulos de pago | Bajo | El 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.
// 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"'
);