Mostrar el nombre de los productos en la lista de los pedidos del Back-office en Prestashop 1.5

08 febrero, 2015 |

Si te gusta, compártelo ;)

Vista previa añadir múliples productos al carrito en Prestashop

En este tutorial vamos a ver cómo mostrar el nombre de los productos en la lista de los pedidos del Back-office en Prestashop 1.5, tal que así:

Lista de los pedidos del Back-office en Prestashop 1.5

También habilitaremos el filtrado de búsqueda por el nombre de producto. Para conseguir esto bastará con hacer un override sobre el archivo AdminOrdersController.php.


Compatibilidad: Prestashop 1.5

Descargar los archivos del proyecto

Override sobre el archivo AdminOrdersController.php

Para empezar debemos crear un archivo en ../prestashop/override/controllers/admin y llamarlo AdminOrdersController.php. Tenemos que sobreescibir el método construct(); por lo tanto insertar el siguiente código dentro de la etiqueta <?php:

class AdminOrdersController extends AdminOrdersControllerCore
{
 
    public function __construct()
    {
 
    }
}

Ahora vamos a añadir algún parámetro base:

class AdminOrdersController extends AdminOrdersControllerCore
{
 
    public function __construct()
    {
        $this->table = 'order';
        $this->className = 'Order';
        $this->lang = false;
        $this->addRowAction('view');
        $this->explicitSelect = true;
        $this->allow_export = true;
        $this->deleted = false;
        $this->context = Context::getContext();
    }
}

No hay nada especial en este código. Solo la creación de conceptos básicos del módulo a partir del método original. El método original se encuentra en el archivo homónimo de la ruta ../prestashop/controllers/admin. Ahora debemos extender la instrucción SELECT.

La consulta SQL para seleccionar los productos

Justo después de la definción del objeto que añadimos antes, tenemos que extender la variable $this->_select, con el fin de tomar la información de los productos de la base de datos de Prestashop. Así que, copiar este código y añadirlo justo después de las últimas líneas que escribimos:

$this->_select = '
a.id_currency,
a.id_order AS id_pdf,
CONCAT(LEFT(c.`firstname`, 1), \'. \', c.`lastname`) AS `customer`,
osl.`name` AS `osname`,
os.`color`,
(SELECT GROUP_CONCAT(odd.product_name SEPARATOR ", ") FROM `'._DB_PREFIX_.'order_detail` odd WHERE odd.id_order = a.id_order) as products,
IF((SELECT COUNT(so.id_order) FROM `'._DB_PREFIX_.'orders` so WHERE so.id_customer = a.id_customer) > 1, 0, 1) as new';

La siguiente consulta es la encargada de mostrar la información de los productos en la tabla de pedidos del Back-office:
(SELECT GROUP_CONCAT(odd.product_name SEPARATOR ", ") FROM `'._DB_PREFIX_.'order_detail` odd WHERE odd.id_order = a.id_order) as products,

Ahora justo después de la variable $this->_select, agregamos el siguiente código:

$this->_join = '
LEFT JOIN `'._DB_PREFIX_.'customer` c ON (c.`id_customer` = a.`id_customer`)
LEFT JOIN `'._DB_PREFIX_.'order_state` os ON (os.`id_order_state` = a.`current_state`)
LEFT JOIN `'._DB_PREFIX_.'order_state_lang` osl ON (os.`id_order_state` = osl.`id_order_state` AND osl.`id_lang` = '.(int)$this->context->language->id.')';
$this->_orderBy = 'id_order';
$this->_orderWay = 'DESC';
 
$statuses_array = array();
$statuses = OrderState::getOrderStates((int)$this->context->language->id);
 
foreach ($statuses as $status)
    $statuses_array[$status['id_order_state']] = $status['name'];

Hasta ahora nuestro override se vería así:

class AdminOrdersController extends AdminOrdersControllerCore
{
 
    public function __construct()
    {
  $this->table = 'order';
        $this->className = 'Order';
        $this->lang = false;
        $this->addRowAction('view');
        $this->explicitSelect = true;
        $this->allow_export = true;
        $this->deleted = false;
        $this->context = Context::getContext();
  
  $this->_select = '
  a.id_currency,
  a.id_order AS id_pdf,
  CONCAT(LEFT(c.`firstname`, 1), \'. \', c.`lastname`) AS `customer`,
  osl.`name` AS `osname`,
  os.`color`,
  (SELECT GROUP_CONCAT(odd.product_name SEPARATOR ", ") FROM `'._DB_PREFIX_.'order_detail` odd WHERE odd.id_order = a.id_order) 
  as products,IF((SELECT COUNT(so.id_order) FROM `'._DB_PREFIX_.'orders` so WHERE so.id_customer = a.id_customer) > 1, 0, 1) as new';
  
  $this->_join = '
  LEFT JOIN `'._DB_PREFIX_.'customer` c ON (c.`id_customer` = a.`id_customer`)
  LEFT JOIN `'._DB_PREFIX_.'order_state` os ON (os.`id_order_state` = a.`current_state`)
  LEFT JOIN `'._DB_PREFIX_.'order_state_lang` osl ON (os.`id_order_state` = osl.`id_order_state` AND osl.`id_lang` = '.(int)$this-> context->language->id.')';
  $this->_orderBy = 'id_order';
  $this->_orderWay = 'DESC';
 
  $statuses_array = array();
  $statuses = OrderState::getOrderStates((int)$this->context->language->id);
 
  foreach ($statuses as $status)
      $statuses_array[$status['id_order_state']] = $status['name'];

Mostrar los productos en la tabla de pedidos

Para añadir nuevos campos en la tabla de pedidos, necesitamos extender la variable $this->fields_list. Por lo tanto, tomaremos esta variable del controlador original, que recordábamos, se encuentra en ../prestashop/controllers/admin; y la pegaremos a continuación del último foreach. Este sería el código, (tomado de prestashop 1.5.5.0):

$this->fields_list = array(
'id_order' => array(
    'title' => $this->l('ID'),
    'align' => 'center',
    'width' => 25
),
'reference' => array(
    'title' => $this->l('Reference'),
    'align' => 'center',
    'width' => 65
),
'new' => array(
    'title' => $this->l('New'),
    'width' => 25,
    'align' => 'center',
    'type' => 'bool',
    'tmpTableFilter' => true,
    'icon' => array(
        0 => 'blank.gif',
        1 => array(
            'src' => 'note.png',
            'alt' => $this->l('First customer order'),
        )
    ),
    'orderby' => false
),
'customer' => array(
    'title' => $this->l('Customer'),
    'havingFilter' => true,
),
'total_paid_tax_incl' => array(
    'title' => $this->l('Total'),
    'width' => 70,
    'align' => 'right',
    'prefix' => '',
    'suffix' => '',
    'type' => 'price',
    'currency' => true
),
'payment' => array(
    'title' => $this->l('Payment: '),
    'width' => 100
),
'osname' => array(
    'title' => $this->l('Status'),
    'color' => 'color',
    'width' => 280,
    'type' => 'select',
    'list' => $statuses_array,
    'filter_key' => 'os!id_order_state',
    'filter_type' => 'int',
    'order_key' => 'osname'
),
'date_add' => array(
    'title' => $this->l('Date'),
    'width' => 130,
    'align' => 'right',
    'type' => 'datetime',
    'filter_key' => 'a!date_add'
),
'id_pdf' => array(
    'title' => $this->l('PDF'),
    'width' => 35,
    'align' => 'center',
    'callback' => 'printPDFIcons',
    'orderby' => false,
    'search' => false,
    'remove_onclick' => true)
);

¿Dónde añadiremos la lista de productos? No estaría mal añadirla después del nombre del cliente, por lo tanto, tenemos que añadir el nuevo campo como un array:

'products' => array(
    'title' => $this->l('Products'),
    'havingFilter' => true,
    'filter_key' => 'products',
    'width' => 210,
),

Como primer elemento del array tenemos el nombre de la columna, la posibilidad de filtrar dichos parámetros, el nombre de la key del filtro, y el ancho de la columna en pixels.

Como habíamos dicho, añadiremos este array después del nombre del cliente:

$this->fields_list = array(
'id_order' => array(
    'title' => $this->l('ID'),
    'align' => 'center',
    'width' => 25
),
'reference' => array(
    'title' => $this->l('Reference'),
    'align' => 'center',
    'width' => 65
),
'new' => array(
    'title' => $this->l('New'),
    'width' => 25,
    'align' => 'center',
    'type' => 'bool',
    'tmpTableFilter' => true,
    'icon' => array(
        0 => 'blank.gif',
        1 => array(
            'src' => 'note.png',
            'alt' => $this->l('First customer order'),
        )
    ),
    'orderby' => false
),
'customer' => array(
    'title' => $this->l('Customer'),
    'havingFilter' => true,
    'width' => 75,
),

'products' => array(
    'title' => $this->l('Products'),
    'havingFilter' => true,
    'filter_key' => 'products',
    'width' => 210,
),  
'total_paid_tax_incl' => array(
    'title' => $this->l('Total'),
    'width' => 70,
    'align' => 'right',
    'prefix' => '',
    'suffix' => '',
    'type' => 'price',
    'currency' => true
),
'payment' => array(
    'title' => $this->l('Payment: '),
    'width' => 100
),
'osname' => array(
    'title' => $this->l('Status'),
    'color' => 'color',
    'width' => 280,
    'type' => 'select',
    'list' => $statuses_array,
    'filter_key' => 'os!id_order_state',
    'filter_type' => 'int',
    'order_key' => 'osname'
),
'date_add' => array(
    'title' => $this->l('Date'),
    'width' => 130,
    'align' => 'right',
    'type' => 'datetime',
    'filter_key' => 'a!date_add'
),
'id_pdf' => array(
    'title' => $this->l('PDF'),
    'width' => 35,
    'align' => 'center',
    'callback' => 'printPDFIcons',
    'orderby' => false,
    'search' => false,
    'remove_onclick' => true)
);
Como podéis observar en el código de arriba, al array correspondiente al cliente, le he añadido un elemento para que la columna tenga un anchura de 75 pixels. Esto es opcional, y cada uno puede hacerlo como más le convenga, por lo tanto, se puede eliminar ese elemento o darle más o menos anchura.

Terminando el override...

El resto del override es básicamente idéntico al archivo original, por lo que, tomar el código del archivo original después de la variable $this->fields_list (dentro de los límites del método construct()), y pegarlo en el override.

Este sería el código que debemos pegar a continuación de $this->fields_list:

$this->shopLinkType = 'shop';
$this->shopShareDatas = Shop::SHARE_ORDER;
 
if (Tools::isSubmit('id_order'))
{
    // Save context (in order to apply cart rule)
    $order = new Order((int)Tools::getValue('id_order'));
    if (!Validate::isLoadedObject($order))
        throw new PrestaShopException('Cannot load Order object');
    $this->context->cart = new Cart($order->id_cart);
    $this->context->customer = new Customer($order->id_customer);
}
 
AdminController::__construct();

Como no queremos que la variable $this->fields_list sea anulada por la original, hemos cambiado el parent::__construct(); del archivo original a AdminController::__construct();

Para terminar, y muy IMPORTANTE!, borrar el archivo class_index.php de ../prestashop/cache para que el override pueda tener lugar.

1 comentario:

  1. aunque tuve que hacer modificaciones y pruevas, con su explicación me solucionó mucho a entender como llamar a "nombre de productos" además de modificar la plantilla en éste apartado. POR FIN puedo cerrar caja diaria de lo que se vende en TPV físico!!!

    ResponderEliminar