Sin impuesto Con impuesto

Acción masiva propia en el listado de pedidos de PrestaShop 8/9

Gustavo no conseguía añadir una acción propia al listado de pedidos de PrestaShop 8 y la documentación no le ayudaba. Otro compañero compartió cómo lo hizo: un botón en las acciones masivas con el hook de la rejilla, un JavaScript que recoge los pedidos marcados y un controlador del módulo.

Equipo Rekire
Actualizado: 14/12/2025 8
Acción masiva propia en el listado de pedidos de PrestaShop 8/9
Compartir:

Añadir una acción propia al listado de pedidos de PrestaShop 8 y 9 («exportar los marcados», «imprimir etiquetas») tiene truco. Gustavo lo preguntó en el grupo después de pelearse con la documentación y con varias IA que no daban con ello. La solución que funcionó: un botón en las acciones masivas con el hook actionOrderGridDefinitionModifier, un JavaScript que recoge los pedidos marcados y un controlador del módulo que hace el trabajo.

Por qué no es inmediato

Desde PrestaShop 1.7.7 el listado de pedidos es una rejilla de Symfony. Sus acciones masivas son objetos con distintos tipos, y no todos funcionan igual:

  • SubmitBulkAction envía un formulario con los pedidos marcados a una ruta de Symfony (opción submit_route, obligatoria). Necesitas que tu módulo declare esa ruta y que la página procese ese tipo de acción.
  • ButtonBulkAction solo pinta el botón. Lo que pase al pulsarlo lo decides tú con JavaScript.

Gustavo se preguntaba por qué la IA se empeñaba en añadir un JavaScript. La respuesta está en el propio núcleo: en el listado de pedidos, PrestaShop usa un formulario en ventana modal para «cambiar estado» y un botón con JavaScript para «abrir en pestañas nuevas». El camino del JavaScript no es un capricho.

1. El botón

use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\ButtonBulkAction;

public function hookActionOrderGridDefinitionModifier(array $params)
{
    $definition = $params['definition'];

    $definition->getBulkActions()->add(
        (new ButtonBulkAction('mimodulo_exportar'))
            ->setName($this->l('Exportar seleccionados'))
            ->setOptions(['class' => 'js-mimodulo-exportar'])
    );
}

Registra el hook en el install() del módulo. Es el mismo patrón para otras rejillas: el nombre del hook lleva el id de la rejilla (actionCustomerGridDefinitionModifier, etc.).

2. El JavaScript y la URL del controlador

El compañero cargaba el JavaScript solo en la página de pedidos desde displayBackOfficeHeader, y le pasaba la URL del controlador del módulo, que ya incluye el token de seguridad:

public function hookDisplayBackOfficeHeader()
{
    if ($this->context->controller->controller_name !== 'AdminOrders') {
        return;
    }
    $this->context->controller->addJS($this->_path . 'views/js/bulk.js');
    Media::addJsDef([
        'mimoduloBulkUrl' => $this->context->link->getAdminLink('AdminMiModuloBulk'),
    ]);
}

En views/js/bulk.js, al pulsar el botón se recogen los pedidos marcados y se envían por POST:

document.addEventListener('click', function (e) {
  var boton = e.target.closest('.js-mimodulo-exportar');
  if (!boton) {
    return;
  }
  e.preventDefault();
  var marcados = document.querySelectorAll('input[name="order_orders_bulk[]"]:checked');
  if (!marcados.length) {
    return;
  }
  var form = document.createElement('form');
  form.method = 'POST';
  form.action = mimoduloBulkUrl;
  marcados.forEach(function (casilla) {
    var campo = document.createElement('input');
    campo.type = 'hidden';
    campo.name = 'ids[]';
    campo.value = casilla.value;
    form.appendChild(campo);
  });
  document.body.appendChild(form);
  form.submit();
});

3. El controlador

AdminMiModuloBulk es un ModuleAdminController del módulo, dado de alta como pestaña oculta para que getAdminLink lo encuentre. Recoge los IDs como enteros (array_map('intval', (array) Tools::getValue('ids'))), comprueba que el empleado tiene permiso y hace el trabajo. Al terminar, redirige de vuelta al listado.

Lo que hay que comprobar

  • El nombre de las casillas sigue el patrón id de la rejilla + columna; en pedidos es order_orders_bulk[]. Míralo con el inspector del navegador en tu versión.
  • Si prefieres SubmitBulkAction con una ruta de Symfony del módulo, prueba que la página de pedidos la procesa antes de dar el trabajo por hecho.
  • Valida en el servidor todo lo que llega: el JavaScript se puede saltar.
  • Pruébalo antes en una copia de la tienda, en tu versión exacta: la comprobación de controller_name y la carga del JavaScript en una página de Symfony cambian por dentro entre PrestaShop 8 y 9.

Esto salió en @PrestashopEsp, la mayor comunidad PrestaShop de España en Telegram. Ver la conversación

Cargando...
Cookies
Volver arriba