🚚 Modulo de transportista — desarrollo completo
Actualizado: 2024-12-01
Un modulo de transportista en PrestaShop implementa el calculo dinamico de costos de envio consultando APIs externas o aplicando logica propia. Extiende la clase Module y usa el hook getOrderShippingCost para devolver el precio del envio.
#Extender la clase de carrier
mycarrier.php — modulo de transportista
php
<?php
if (!defined('_PS_VERSION_')) { exit; }
class MyCarrier extends Module
{
/** ID del carrier creado por el modulo — se guarda en Configuration */
const CARRIER_NAME = 'MyCarrier Express';
const CARRIER_DELAY = 'Entrega en 24-48h horas';
public function __construct()
{
$this->name = 'mycarrier';
$this->tab = 'shipping_logistics';
$this->version = '1.0.0';
$this->author = 'gmartos.es';
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->trans('Mi Transportista', [], 'Modules.Mycarrier.Admin');
}
public function install(): bool
{
return parent::install()
&& $this->registerHook('actionCarrierUpdate')
&& $this->createCarrier();
}
public function uninstall(): bool
{
return $this->deleteCarrier() && parent::uninstall();
}
}
#Calcular el costo de envio
getOrderShippingCost() — calcular el precio de envio
php
<?php
/**
* Calcula el costo de envio para un carrito dado.
* @param Cart $cart Carrito actual
* @param float $shipping_cost Costo base calculado por PS (segun rangos del carrier)
* @return float|bool Precio del envio, o false si no disponible
*/
public function getOrderShippingCost(Cart $cart, float $shipping_cost): float|bool
{
// Verificar si el carrito tiene productos
if (!$cart->id) {
return false;
}
// Obtener datos del carrito
$totalWeight = $cart->getTotalWeight(); // en kg
$totalPrice = $cart->getOrderTotal(true, Cart::ONLY_PRODUCTS);
$idAddress = $cart->id_address_delivery;
$address = new Address($idAddress);
$idCountry = (int) $address->id_country;
// Logica de calculo (puede llamar a una API externa)
try {
$rate = $this->getRateFromApi($totalWeight, $idCountry);
return (float) $rate;
} catch (Exception $e) {
// Si la API falla, usar tarifa de respaldo o false
return false;
}
}
/**
* Necesario ademas de getOrderShippingCost.
* Se llama cuando PS no puede calcular por rangos.
*/
public function getOrderShippingCostExternal(Cart $cart): float|bool
{
return $this->getOrderShippingCost($cart, 0);
}
#Registrar el carrier en install()
createCarrier() — crear el transportista en la DB
php
<?php
private function createCarrier(): bool
{
$carrier = new Carrier();
$carrier->name = self::CARRIER_NAME;
$carrier->active = true;
$carrier->deleted = false;
$carrier->shipping_handling = false;
$carrier->range_behavior = 0; // 0 = usar el mayor rango si supera
$carrier->is_module = true; // indica que es un carrier de modulo
$carrier->shipping_external = true; // calculo externo (usa nuestro getOrderShippingCost)
$carrier->need_range = true; // requiere rangos configurados
$carrier->external_module_name = $this->name;
$carrier->is_free = false;
$carrier->position = Carrier::getHigherPosition();
$carrier->max_weight = 30; // kg
$carrier->grade = 5; // velocidad de entrega 0-9
// Delays por idioma
foreach (Language::getLanguages() as $lang) {
$carrier->delay[$lang['id_lang']] = self::CARRIER_DELAY;
}
if (!$carrier->save()) {
return false;
}
// Guardar ID del carrier creado
Configuration::updateValue('MYCARRIER_ID', (int) $carrier->id);
// Copiar el logo del carrier
$logoSrc = _PS_MODULE_DIR_ . $this->name . '/views/img/carrier-logo.jpg';
if (file_exists($logoSrc)) {
copy($logoSrc, _PS_SHIP_IMG_DIR_ . $carrier->id . '.jpg');
}
// Asignar a todas las zonas activas
$zones = Zone::getZones(true);
foreach ($zones as $zone) {
$carrier->addZone((int) $zone['id_zone']);
}
return true;
}
private function deleteCarrier(): bool
{
$idCarrier = (int) Configuration::get('MYCARRIER_ID');
if ($idCarrier) {
$carrier = new Carrier($idCarrier);
$carrier->delete();
Configuration::deleteByName('MYCARRIER_ID');
}
return true;
}
Descargar en Markdown
Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.