PepeFernandez Posted January 21 Share Posted January 21 Estoy intentando hacer en el carrito un calculador de los gastos de envío, en principio los gastos de envío van según el peso del envío, transportista y zona, pero además tengo un módulo llamado 'advanced shipping cost' (orderfees_shipping en la carpeta modules) al que puedes arreglar excepciones. no se si alguien lo ha usado alguna vez. De momento con un ajax envío a la función public function hookActionCartGetPackageShippingCost(&$params) Los parámetros que necesita que entre otros coge el carrito para acceder a varias cosas como los pesos o las direcciones, como quiero hacer calcular el envío, el formulario te permite poner un pais, provincia y codigo postal al darle enviar actualiza una dirección creada aposta para esto y falsea el carro cambiando el id_address_delivery y id_address_invoice por la dirección creada para esta función, este sería el ajax: <?php // Incluye el entorno de Prestashop include(dirname(__FILE__) . '/../config/config.inc.php'); include(dirname(__FILE__) . '/../init.php'); header('Content-Type: application/json'); // Obtener valores $id_country = Tools::getValue('id_country'); $id_state = Tools::getValue('id_state'); $postal = Tools::getValue('postal'); $id_cart = Tools::getValue('id_cart'); if (!$id_country || !$id_state || !$postal || !$id_cart) { echo json_encode([]); exit; } //actualizar la dirección falsa $sql = 'UPDATE `' . _DB_PREFIX_ . 'address` SET `id_country` = ' . $id_country . ', `id_state` = '. $id_state .', `postcode` = '. $postal .' WHERE `id_address` = 1'; Db::getInstance()->execute($sql); //Obtener carrito $cart = new Cart((int) $id_cart); //falsear Carrito $cart->id_address_delivery = '1'; $cart->id_address_invoice = '1'; //calcular id_zone $id_zone = $provinces = State::getIdZone((int)$id_country); /* CONSTRUIR PARAMETROS */ $params = [ 'use_tax' => true, 'id_carrier' => 169, 'default_country' => null, 'keepOrderPrices' => false, 'total' => 0, 'return' => false, 'altern' => 1, 'product_list' => null, 'cart' => $cart, 'object' => $cart, 'id_zone' => $id_zone, 'custom' => true ]; // Obtener costo de envío $result = Hook::exec('actionCartGetPackageShippingCost', $params); // Si no hay resultado, maneja el caso if ($result === null ) { $result = ['error' => 'No se pudo calcular el costo de envío']; } // Devuelve el resultado como JSON echo json_encode(['shipping_cost' => $result]); exit; y esto según la lógica debería funcionar, pero en la función a la que llama para comprobar el precio, primero lista todas las reglas y luego las recorre una a una para comprobar si el carro coincide con ella "hace un check" y si es false pasa a la siguiente, el problema es que me está haciendo false en todas, incluso en reglas que deberían saltar y no entiendo porqué, es en esta parte: if($custom){ $shipping_rule_checked = $shipping_rule->checkCustom($object); }else{ $shipping_rule_checked = $shipping_rule->check(); } self::$disable_calculation = false; if (!$shipping_rule_checked) { continue; } al principio pensaba que era porque en $shipping_rule->check() cogía el carro del $context, por eso se lo paso como $object en la función checkCustom que entra cuando viene del ajax, pero sigue sin funcionar, alguien puede ayudar? Link to comment Share on other sites More sharing options...
ventura Posted January 21 Share Posted January 21 Para implementar el controller es mejor que sigas las recomendaciones de documentación técnica https://devdocs.prestashop-project.org/8/modules/concepts/controllers/front-controllers/#ajax-request Link to comment Share on other sites More sharing options...
PepeFernandez Posted January 28 Author Share Posted January 28 he hecho algunos cambios este es el aspecto de mi ajax actual: <?php // Incluye el entorno de Prestashop include(dirname(__FILE__) . '/../config/config.inc.php'); include(dirname(__FILE__) . '/../init.php'); header('Content-Type: application/json'); // Obtener valores $id_country = Tools::getValue('id_country'); $id_state = Tools::getValue('id_state'); $postal = Tools::getValue('postal'); $id_cart = Tools::getValue('id_cart'); $delivery_by_truck = Tools::getValue('weight') >= 15 ? true : false ; if (!$id_country || !$id_state || !$postal || !$id_cart) { echo json_encode([]); exit; } //actualizar la dirección falsa $sql = 'UPDATE `' . _DB_PREFIX_ . 'address` SET `id_country` = ' . $id_country . ', `id_state` = '. $id_state .', `postcode` = '. $postal .' WHERE `id_address` = 1'; Db::getInstance()->execute($sql); //Obtener carrito $cart = new Cart((int) $id_cart); //Obtener carrier $correos = 167; $correos_internacional = 158; $camion = 168; $camion_internacional = 169; $delivery_by_truck = Tools::getValue('weight') >= 15 ? true : false ; $id_carrier = $delivery_by_truck ? $camion_internacional : $correos_internacional; if ($id_country == 6) {//Envío en españa $id_carrier = $delivery_by_truck ? $camion : $correos; } //falsear Carrito $cart->id_carrier = ''.$id_carrier.''; $cart->id_address_delivery = '1'; $cart->id_address_invoice = '1'; $cart->id_customer = '2'; $cart->delivery_option = '{"1":"'.$id_carrier.'"}'; $object = $cart; //calcular id_zone $id_zone = $provinces = State::getIdZone((int)$id_state); /* CONSTRUIR PARAMETROS */ static $cache = []; $total = 0; $return = false; $use_tax = true; $default_country = null; $keepOrderPrices = false; $product_list = null; Hook::exec('actionCartGetPackageShippingCost', [ 'object' => &$object, 'id_carrier' => &$id_carrier, 'use_tax' => &$use_tax, 'default_country' => &$default_country, 'product_list' => &$product_list, 'id_zone' => &$id_zone, 'keepOrderPrices' => &$keepOrderPrices, 'total' => &$total, 'return' => &$return, 'custom' => true ]); if ($return) { $result = ($total !== false ? (float) Tools::ps_round((float) $total, 2) : false); } else { $shipping_cost = $cart->getParentPackageShippingCost( $id_carrier, $use_tax, $default_country, $product_list, $id_zone, $keepOrderPrices ); if ($shipping_cost !== false) { $result = $shipping_cost + (float) Tools::ps_round((float) $total, 2); } } // Si no hay resultado, maneja el caso if ($result === null ) { $result = ['error' => 'No se pudo calcular el costo de envío']; } // Devuelve el resultado como JSON echo json_encode([ 'shipping_cost' => $result, ]); exit; me pasa lo siguiente si tengo la dirección guardada en la sesión, me va perfectamente, pero si lo hago hago sin una dirección en la sesión entonces el calculo aunque es muy apróximado no es exacto y no lo entiendo ya que tanto con dirección como si no, los parámetros que envío son los mismos, el carrito sería el mismo, pero lo que me devuelve la función es un resultado distinto, tanto en la función que saca el valor que añade el módulo como en la que recibe el coste de envío normal, recibo 2 cantidades distintas, envíando los mismos parámetros, lo que me hace pensar que al guardar una dirección debe de haber una variable que se me está pasando Link to comment Share on other sites More sharing options...
ventura Posted February 2 Share Posted February 2 Insisto en lo anterior, sigue las recomendaciones de la documentación de Prestashop para hacerlo desde un método ajax de controller. Esa implementación no es la mas segura, ni funcional . Link to comment Share on other sites More sharing options...
PepeFernandez Posted February 3 Author Share Posted February 3 hace 18 horas, ventura dijo: Insisto en lo anterior, sigue las recomendaciones de la documentación de Prestashop para hacerlo desde un método ajax de controller. Esa implementación no es la mas segura, ni funcional . No se de que me hablas, he encontrado el error, es por tema del impuesto, porque aplica el iva del país que tiene en sesión en el carrito, así que lo que he hecho al final es traerme el precio sin impuesto y le cargo el del país que se selecciona. Ahora funciona perfectamente Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now