Jump to content

agregar muestra al carrito


Recommended Posts

Posted (edited)

Buenas estoy tratando de modificar el listado de productos le he dado este formato:
image.thumb.png.2b61a34be49b74980461508ad3071870.png

la idea es que el botón pedir muestra gratuíta, agregue el producto al carrito, el producto tiene una variante para ser muestra. he visto que dentro de la página del producto, para agregarla al carrito tiene como un formulario donde puedo poner la cantidad del producto que quiero y esas cosas.

La cosa es que hacer de cada botón un formulario no se si funcionará yo había pensado en una api, he creado en el apartado de webservice una api que me da acceso al carrito, pero no me aclaro mucho a conseguir que ande y creo que el error lo tengo en la ruta, este es mi javascript:

 

 /*AGREGAR MUESTRAS AL CARRITO DESDE CATÁLOGO*/

      $('.product-table-cell').on('click', function() {
         var productId = $(this).data('product-id');
         var apiUrl = '/api/carts'; 
         var apiKey = 'api-key'; 
         var cartId = $(this).data('id-cart');

         // Verifica si los datos están presentes
         if (!productId || !apiKey || !cartId) {
            console.error('Datos faltantes: productId, apiKey o cartId no están definidos');
            return;
         }

         // Datos del nuevo producto a añadir
         var newProduct = {
            "cart": {
               "associations": {
                     "cart_rows": [{
                        "id_product": productId,
                        "id_product_attribute": 0,
                        "quantity": 1
                     }]
               }
            }
         };

         fetch(apiUrl + '/' + cartId, {
            method: 'PUT',
            headers: {
               'Content-Type': 'application/json',
               'Authorization': 'Basic ' + btoa(apiKey + ':')
            },
            body: JSON.stringify(newProduct)
         })
         .then(response => response.text()) // Cambia a text() temporalmente para depuración
         .then(text => {
            try {
               const data = JSON.parse(text);
               if (data.id) {
                     console.log('Producto agregado con éxito');
               } else {
                     console.error('Fallo al agregar el producto', data);
               }
            } catch (e) {
               console.error('Error al parsear JSON:', e);
               console.error('Respuesta del servidor:', text);
            }
         })
         .catch(error => {
            console.error('Error en la solicitud:', error);
         });
      });

Alguien podría echarme una mano? ha hecho algún caso similar, pasar documentación, conoce la ruta correcta, me puede explicar o pasar información sobre los hooks que no se si tiene algo que ver, la verdad es que voy perdido...

Gracias, un saludo

Edited by PepeFernandez
hide api (see edit history)
Link to comment
Share on other sites

Me he puesto con el desarrollo del módulo, es mi primerito módulo 😂
de momento lo único que he hecho ha sido mover el javascript y el css al módulo y genial me lo coge desde ahí.
ahora mi intención es seguir volviendo a dejar como estaba la plantilla que edité que es : themes/child_classic/templates/catalog/_partials/miniatures/product.tpl

quiero que las modificaciones de la plantilla también sean a cargo del módulo, pero aquí me pierdo un poco, necesito saber que hook debo coger he mirado en la documentación y hay un par de hooks que mencionan la plantilla, pero por el nombre que tienen no me dejan convencido de que sea lo que debo hacer, los hooks serían los siguientes:
 

  • displayProductListReviews
  • displayProductPriceBlock

¿Alguien con experiencia que me pueda echar una mano? el objetivo es que el botón de pedir muestra gratuíta agregue al carro el producto. Bueno en realidad es un poco mas complejo, pero con esto creo que podría avanzar mucho ya.

un saludo.

Link to comment
Share on other sites

Creo que vas por el buen camino. Desde el hook de display asigna las variables y crear luego en el .tpl un formulario 

<form action="{$urls.pages.cart}" method="post" class="add-to-cart-or-refresh">
  <input type="hidden" name="token" value="{$static_token}">
  <input type="hidden" name="id_product" value="{$product.id_product}" class="product_page_product_id">
  {*
    <input type="hidden" name="id_product_attribute" value="{TBD}">
  *}
  <input type="hidden" name="qty" value="1">
  <button class="btn call_check" data-button-action="add-to-cart" type="submit">
  {l s='Comprar' d='Modules.MyModule.Shop'}
  </button>
</form>

faltará establecer la lógica que detecte el atributo en concreto de cada producto

Link to comment
Share on other sites

hace 22 horas, ventura dijo:

Creo que vas por el buen camino. Desde el hook de display asigna las variables y crear luego en el .tpl un formulario 

<form action="{$urls.pages.cart}" method="post" class="add-to-cart-or-refresh">
  <input type="hidden" name="token" value="{$static_token}">
  <input type="hidden" name="id_product" value="{$product.id_product}" class="product_page_product_id">
  {*
    <input type="hidden" name="id_product_attribute" value="{TBD}">
  *}
  <input type="hidden" name="qty" value="1">
  <button class="btn call_check" data-button-action="add-to-cart" type="submit">
  {l s='Comprar' d='Modules.MyModule.Shop'}
  </button>
</form>

faltará establecer la lógica que detecte el atributo en concreto de cada producto

he cambiado la forma de enfocarlo porque prestashop me pedía muchas cosas para la api y me he aventurado a crear mi primer módulo, todo iba guay he creado un hook en el cual el módulo pone la plantilla con el aspecto que quiero, coge el css y el javascript, el problema está en que por alguna razón cuando hago el ajax, me entra dentro del success pero en el else, es decir como si algo fallara, hago un console log de la respuesta y aparece vacía y en el network la respuesta es un 200 pero viene vacío, lo único que hace la función a la que trata de acceder la petición ajax es retornar el mensaje de 'estoy dentro', intento poner el código pero no se porque el foro me pone que estoy bloqueado.

Link to comment
Share on other sites

voy a intentar poner el código con imágenes:
modules/addsampleoncatalog/addsampleoncatalog.php este código es el que inserta en la plantilla los nuevos datos y manda la url del ajax, esto está funcionando:
image.png.a8e612aa96a381380f5e18910689394a.png

javascript aquí es lo que me huele raro, por un lado el ajax entra en el success por lo que entiendo que obtiene respuesta, pero va al else y me muestra un error vacío, también tengo un console.log de la respuesta pero aparece en blanco:
image.png.e161c913e727855b62bbbb538d10ffe0.png

modules/addsampleoncatalog/controllers/front/ajax.php aquí el código del controlador con la función addsampleaction que es a la que debe acceder el ajax, en teoría como me está dando un success, debería darme en la respuesta el mensaje 'estoy dentro' pero aparece vacía:
image.png.3ddbe5f83cb0f78762dc68c85576124d.png

Link to comment
Share on other sites

vale he encontrado una forma de que funcione pero sigue habiendo cosas que no entiendo, básicamente he tenido que agregar la llamada de mi función en el initContent del controlador,  pero ahora pasa una cosa que no entiendo si hago esto, recibo la respuesta bien:

 

    public function addSampleAction() {

        header('Content-Type: application/json');

        $response = [
            'success' => true, 
            'msg' => 'Estoy Dentro'
        ];
		echo json_encode($response);
		die();
	}

en cambio si hago esto recibo un error:
 

    public function addSampleAction() {

        header('Content-Type: application/json');

        $response = [
            'success' => true, 
            'msg' => 'Estoy Dentro'
        ];

        return json_encode($response);
}

este es el error que recibo:
image.png.3be3b18b593d42c1c189cf60a956809e.png

Link to comment
Share on other sites

Varias cosas, creo que deberias seguir probando con el formulario en el hook, pasando los parámetros del producto

 $product = $params['product'];

Si vas a  hacerlo con ajax con el controller 

Pasa la url del controller al js desde

hookActionFrontControllerSetMedia

con

Media::addJsDef([

'mymodule_url_controller' => $this->context->link->getModuleLink('mymodule', 'ajax'),

]);

En el front controller añade una función, con esta convención de nombre, displayAjaxNombreFuncion // en Camelcase

protected function displayAjaxProductToCart()

desde ahi tendrás que obtener los valores que necesites  obtenidos desde el js, ejemplo y aplicar la lógica que se requiera, ejemplo

        $productId = (int)Tools::getValue('id_product');
        $productAttributeId = (int)Tools::getValue('id_product_attribute');


        if ($productId) {
            $cart = $this->context->cart;
            $cart->updateQty(1, $productId, $productAttributeId);
            Tools::redirect('index.php?controller=cart');
        } else {
            Tools::redirect('index.php');
        }
    }

en el js

§.ajax({
type: 'POST',
url: mymodule_url_controller,
data: {
action: 'productToCart',
id product: productId,
id id_product_attribute: productAttributeId, // TBD


para este tipo de peticiones es siempre recomendable que se haga validación del token desde el controller  para evitar CSRF

 

Link to comment
Share on other sites

no si lo único que me queda hacer una vez entienda como funcionan los ajax en prestashop y porqué el return del json_encode me da error pero no un echo. lo único que me quedará por hacer es un servicio para que si tengo id de carrito me agregue el producto que le paso con id y si no, pues me crea carrito y le mete el producto, la lógica del backend ya me sabré apañar con ella, pero lo que no entiendo es el porqué me da tantas pegas el ciclo del ajax

Link to comment
Share on other sites

En 31/5/2024 a las 12:00 PM, ventura dijo:

Desde el js estas llamando a una action que no se corresponde con el controller ajax utilizado

yo entiendo que si que llama a la que toca porque entra en el controlador y en la función, lo que no se es porque me devuelve el número si la función hace un echo y un die, pero me da error si devuelvo el mensaje con un return

Link to comment
Share on other sites

hacer un echo no es la mejor práctica, mejor usar

$this->ajaxRender(json_encode($response)

// ajaxDie() deprecated since 1.7.5.0

Y para obtener los valores obtenidos por js sería mejor utilizar una función displayAjax  como se indica mas arriba

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...