Añadir sección al Back Office de pedidos en Prestashop 1.6

Prestashop ofrece unos cuantos hooks para que los módulos puedan poner su contenido en el detalle de un pedido dentro de lo que es el Back Office de Prestashop. El mas usado es displayAdminOrder y es un buen sitio para añadir contenido. Mas información acerca de hooks aquí

Cuando se trata de hacer una personalización muy concreta para un proyecto Prestashop, siempre hay la posibilidad de hacer uso de overrides y operar directamente con el código fuente.

Esto tiene sus ventajas e inconvenientes:

  • Como ventajas tenemos  que obviamente puedes hacer lo que te de la gana y aquí estamos hablando de algo tan sencillo como es elegir donde poner tu contenido. Los hooks que ofrece Prestashop están en unos puntos concretos y no tiene porque ser donde a ti te guste. También se trabaja mas rápido operando de esta manera.
  • Por contrapartida, la distribución/aplicación de la solución es un desastre. Si se ha introducido un cambio en la sección de pedidos en una nueva versión de Prestahsop, hay que reescribir, o como mínimo revisar, la receta para la nueva versión.

Entonces si trabajamos directamente con el código fuente de Prestashop tenemos que trabajar mediante overrides.

Lo que sigue se ha testeado en un prestashop 1.6.0.14 y 1.6.1.4.

Añadir campo al modelo de datos de pedido. Order.php

Imaginemos que necesitamos añadir al pedido una nota interna para nuestro uso particular. Lo primero sería añadir al modelo de datos de la entidad Pedido este campo de texto. En base de datos se añade mediante la sentencia

Luego en \override\classes\order, añadimos el fichero Order.php con el nuevo campo nota_interna en la clase.

Modificando la plantilla de pedidos.

La plantilla principal de pedidos se encuentra en tu_carpeta_admin\themes\default\template\controllers\orders\helpers\view\view.tpl

copiamos el fichero view.tpl en override\controllers\admin\templates\orders\helpers\view\

Vamos a meter la nueva sección justo debajo del bloque donde están los estados de pedidos. En la linea 262 aprox. justo encima de un bloque script.

Captura

Metemos la siguiente sección

Efectivamente aparece una caja de texto justo donde queríamos. Tener en cuenta de tener activado “Recompilar las plantillas cuando los archivos sean modificados” en el apartado rendimiento para ver los cambios.

Captura2

Guardar datos, override de AdminOrdersController.

Ahora falta que guarde los datos que pongamos. El controlador que se ocupa de esto es AdminOrdersController.php. Entonces en override\controllers\admin\ añadimos el fichero AdminOrdersController.php

 

Seguidamente borramos el fichero cache\class_index.php para que coja las clases sobrescritas.

De esta forma ya se guarda y lee correctamente este nuevo campo.

 

 

 

  • Víctor

    Una pregunta, si en vez de una caja de texto quiero poner un select, por ejemplo con SI o NO, como se haría? Gracias.

    • http://pelechano.es/ Enrique Gómez

      Hola Victor
      No te puedo dar ningún código conreto porque hay diferencias en lo que es guardar un valor de texto y un booleano (checkbox, radio si/no). Te puedo comentar que en la misma plantilla hay un caso de un campo booleano visibility que a nivel de tpl es

      {l s=’Display to customer?’}

      {l s=’Yes’}

      {l s=’No’}


      Luego a nivel de modelo de datos en Order.php un booleano se define

      array(‘type’ => self::TYPE_BOOL, ‘validate’ => ‘isBool’)

      y en base de datos ya no es un varchar, es un tinyint(1) unsigned con un valor predeterminado de 0

      • Víctor

        Buenas, he seguido tu ejemplo y me sale el select, pero no guarda, he hecho lo siguiente:

        En Order.php

        class Order extends OrderCore
        {
        public $nota_interna;
        public $order_source;
        public function __construct($id = null, $id_lang = null)
        {
        self::$definition[‘fields’][‘nota_interna’] = array(‘type’ => self::TYPE_STRING);
        self::$definition[‘fields’][‘zona_canarias’] = array(‘type’ => self::TYPE_INT);
        self::$definition[‘fields’][‘factura_individual’] = array(‘type’ => self::TYPE_INT);
        parent::__construct($id,$id_lang);
        }

        En el view.tpl

        {* egp mod nueva seccion – Incidencia*}


        {l s=”Nota interna pedido”}


        {l s=’Incidencia’}

        {if isset($smarty.post.nota_interna)}{$smarty.post.nota_interna}{else}{$order->nota_interna}{/if}
        id}” />

        {l s=’Guardar’}

        {* egp mod fin*}

        {* egp mod nueva seccion – Factura Individual*}


        {l s=”Factura Individual”}


        {l s=’Seleccionar’}

        Normal / Individual

        Normal
        Individual

        id}” />

        {l s=’Guardar’}

        {* egp mod fin*}

        {* egp mod nueva seccion – Canarias*}


        {l s=”Zona Canarias”}


        {l s=’Seleccionar’}

        No Canarias / Si Canarias

        Normal
        Canrias

        id}” />

        {l s=’Guardar’}

        {* egp mod fin*}

        Y en el AdminOrderController.php

        public function postProcess()
        {
        parent::postProcess();
        $order = new Order(Tools::getValue(‘id_order’));
        if (Tools::isSubmit(‘submitNotaInterna’) && isset($order)) //gestión nota interna
        {
        $nota_interna=Tools::getValue(‘nota_interna’,”);
        $res =false;
        $valid=true;//dejamos preparado por si hay que validar alguna cosa
        if(!$valid){
        $this->errors[] = Tools::displayError(‘Error de formato’);
        }else{
        $order->nota_interna=$nota_interna;
        $res = $order->update();
        }
        if ($res)
        Tools::redirectAdmin(self::$currentIndex.’&id_order=’.$order->id.’&vieworder&conf=4&token=’.$this->token);
        else
        $this->errors[] = Tools::displayError(‘Un error ha pasado al guardar la nota interna’);
        }

        parent::postProcess();
        $order = new Order(Tools::getValue(‘id_order’));
        if (Tools::isSubmit(‘submitFacturaIndividual’) && isset($order)) //gestión nota interna
        {
        $factura_individual=Tools::getValue(‘factura_individual’,”);
        $res =false;
        $valid=true;//dejamos preparado por si hay que validar alguna cosa
        if(!$valid){
        $this->errors[] = Tools::displayError(‘Error de formato’);
        }else{
        $order->factura_individual=$factura_individual;
        $res = $order->update();
        }
        if ($res)
        Tools::redirectAdmin(self::$currentIndex.’&id_order=’.$order->id.’&vieworder&conf=4&token=’.$this->token);
        else
        $this->errors[] = Tools::displayError(‘Un error ha pasado al guardar el tipo de factura’);
        }

        parent::postProcess();
        $order = new Order(Tools::getValue(‘id_order’));
        if (Tools::isSubmit(‘submitZonaCanarias’) && isset($order)) //gestión nota interna
        {
        $zona_canarias=Tools::getValue(‘zona_canarias’,”);
        $res =false;
        $valid=true;//dejamos preparado por si hay que validar alguna cosa
        if(!$valid){
        $this->errors[] = Tools::displayError(‘Error de formato’);
        }else{
        $order->zona_canarias=$zona_canarias;
        $res = $order->update();
        }

        Creo que el problema viene en el AdminOrderController.php ya que los select funcionan difernete a los campos de texto, pero no hay forma de dar con la solución.

        El ejemplo que me has puesto si que lo he visto, pero nada, no doy con la tecla para hacerlo funcionar ya que en esa caja envía un mensaje al cliente, no es guardar simplemente en la base de datos, por lo que la cosa se complica para entenderlo.

        Gracias.

        • http://pelechano.es/ Enrique Gómez

          En el controlador no llames tres veces a

          parent::postProcess();
          $order = new Order(Tools::getValue(‘id_order’));

          con que este arriba del todo es suficiente

          En Order.php es necesario como campos

          public $zona_canarias

          public $factura_individual

          en la plantilla view.tpl

          el nombre del selector (select name=”XXXX”) debe ser para cada caso zona_canarias y factura_individual respectivamente

          a parte de checkear el valor de smarty se debe hacer tambien con $order->zona_canarias y $order->factura_individual para checkear o no un selector.

  • Víctor

    Otra pregunta Enrique, tras hacer esto aparecen problemas en la tienda, no se pueden hacer pedidos manuales desde el back office y el módulo de paypal deja de funcionar. Supongo que es debido a los nuevos campos y algo más hay que añadir en alguna otra parte de Prestashop.

    ¿Alguna idea de porque puede pasar esto?

  • Eugenio Fernandez

    hola!!!…. tengo una consulta…
    bueno para empezar lo que pones me funciono de maravillas, sin problemas, pero me gustaria agregar un campo, en el cual vaya mostrando el o los registros (no editable) que voy ingresando a la nota interna de pedido… como se podria hacer, o que cambios tendria que hacer…trabajo con varias personas y que sea editable a armado un poco de problemas…. ya que la utilizamos para comunicarnos… y me gustaria que quede grabado y que no sea modificable, gracias!