whooohq / whq-woocommerce-chilexpress-shipping

Chilexpress Shipping method for WooCommerce / Agrega Chilexpress como método de envío para WooCommerce
https://wordpress.org/plugins/woo-chilexpress-shipping/
GNU General Public License v2.0
23 stars 12 forks source link

Finalizar compra posible, pese que "CHILEXPRESS (SIN SERVICIO)" #81

Closed PatrickCaneloDigital closed 6 years ago

PatrickCaneloDigital commented 6 years ago

En un sistema productivo el cliente me avisó ayer de una compra que entró con costo de envio cero y la indicación Chilexpress (Sin servicio) Sin poder hacer mayor analysis, asumo que en un momento la api de chilexpress estaba caida, porque es el primer caso en 4 meses.

El plugin al parecer no posee un mecanismo de bloqueo para este caso, en el cual no hay costo de envio por la API, es decir el cliente igual puede finalizar la compra, pese que diga costo "0" No se puede bloquear por ultimo el boton de finalizar compra mientras este elegido "Chilexpress (Sin servicio)"???

Acabo de hacer una prueba en un sistema de desarrollo mio, modificando el codigo del plugin para que me devuelva siempre "Chilexpress, sin servcio, costo 0" Y efectivamente se puede pasar al proceso de pago sin ningun inconveniente.

A la rapida (sin haber revisado el codigo del plugin al respecto, veo solo dos opciones: rechazar la verificacion de envio de datos si chilexpress esta sin servicio. No una opcion, pensaba en verificar en la pagina de pago cual metodo de envio esta elegido, pero no funciona ya que en ese momento el pedido ya esta finalizado... Si averiguo algo lo posteo tambien, es decir voy a ver también como solucionarlo elegantemente

TCattd commented 6 years ago

¿Quizás este hook sirva? http://hookr.io/actions/woocommerce_before_checkout_process/

https://docs.woocommerce.com/wc-apidocs/source-class-WC_Checkout.html#953

PatrickCaneloDigital commented 6 years ago

eso mismo pensaba, // define the woocommerce_before_checkout_process callback function action_woocommerce_before_checkout_process( $array ) { $chosen_methods = WC()->session->get( 'chosen_shipping_methods' ); $chosen_shipping = $chosen_methods[0]; if (el metodo de envio termina en '(No Disponible)'){ wc_add_notice( sprintf( 'Hi there! Looks like the Chilexpress API is at the moment not available. We can do nothing about that. Please try again later.', $values[0], $values[1] ), 'error' ); }; }
// add the action add_action( 'woocommerce_before_checkout_process', 'action_woocommerce_before_checkout_process', 10, 1 );

TCattd commented 6 years ago

Lo tengo.

Va el update en unos minutos.

TCattd commented 6 years ago

El cambio: https://github.com/whooohq/whq-woocommerce-chilexpress-shipping/commit/61417665921478d1c0f6c68ccbd20eb9ec7eff35

El hook woocommerce_before_checkout_process no sirve, porque aún no existe una orden con el costo de envío asociado a ella. Y la data que viene en el $_POST de WC, no incluye el costo de envío tampoco.

Así es que me colgué después, en esa misma rutina del método, pero en https://docs.woocommerce.com/wc-apidocs/source-class-WC_Checkout.html#983

woocommerce_checkout_order_processed tiene los datos de la orden, y con ello, el costo de envío (gracias a calculate_shipping()).

:)

PatrickCaneloDigital commented 6 years ago

super gracias... a mi si me funcionó con el "woocommerce_before_checkout_process" pero hay que cambiar el if para que no apunte a "no Disponible" sino que el id del shipping_method termine en ":0" Este codigo tambien funciona

// define the woocommerce_before_checkout_process callback 
function action_woocommerce_before_checkout_process( $array ) { 
    $chosen_methods = WC()->session->get( 'chosen_shipping_methods' ); 
    $chosen_shipping = $chosen_methods[0]; 
    if (endsWith($chosen_shipping, ':0') ){ 
        wc_add_notice( sprintf( 'Hi there! Looks like the Chilexpress API is at the moment not available. We can do nothing about that. Please try again later.', $values[0], $values[1] ), 'error' ); 
    }; 
}
// add the action 
add_action( 'woocommerce_before_checkout_process', 'action_woocommerce_before_checkout_process', 10, 1 );

             function endsWith($haystack, $needle)
            {
                $length = strlen($needle);

                return $length === 0 || 
                (substr($haystack, -$length) === $needle);
            }
TCattd commented 6 years ago

Como lo hice, simplemente verifica primero si se está usando Chilexpress como método de envío. Si se usa Chilexpress, pido el costo del shipping. Si el shipping es cero (o menor), entonces la venta no pasa. Pero en mi caso, primero crea la orden en el backend de WC.

Tu sacaste el costo desde la session del usuario en WC. No se me había ocurrido eso.

Podría evitar el crear la orden por completo así, si uso el hook que comenté en un inicio, y uso la data de la session como lo hiciste. Debería tener el costo del shipping igual, no?.

PatrickCaneloDigital commented 6 years ago

buena pregunta... En todo caso sería mas bonito no crear la orden... El costo del shipping no sé si esta en la sesion o como encontrarlo (voy a ver), pero lo que si esta es el shipping_method_id elegido y en el caso que la API de chilexpress no este disponible, ese termina con :0 (los oficiales son ':1', ':2', etc.)

voy a ver si se encuentra el costo de envio... pero en realidad la prueba de :0 (el id completo es 'chilexpress:0') es suficiente segun yo, ya que ese :0 solo queda seteado si hay un error en la API

PatrickCaneloDigital commented 6 years ago

Aqui encontre algo que incluye el shipping_method_id y la tarifa de costo de envio: Es un poco mas complejo:

foreach( WC()->session->get('shipping_for_package_0')['rates'] as $method_id => $rate ){
    if( WC()->session->get('chosen_shipping_methods')[0] == $method_id ){
        $rate_label = $rate->label; // The shipping method label name
        $rate_cost_excl_tax = floatval($rate->cost); // The cost excluding tax
        // The taxes cost
        $rate_taxes = 0;
        foreach ($rate->taxes as $rate_tax)
            $rate_taxes += floatval($rate_tax);
        // The cost including tax
        $rate_cost_incl_tax = $rate_cost_excl_tax + $rate_taxes;

        echo '<p class="shipping-total">
            <strong class="label">'.$rate_label.': </strong>
            <span class="totals">'. WC()->cart->get_cart_shipping_total() .'</span>
        </p>';
        break;
    }
}
TCattd commented 6 years ago

Lo tengo, de nuevo :)

No, el :0 al final en realidad es una ID que WC pone en los métodos de envío dependiendo del orden en el que están acá: http://prntscr.com/jcx0or http://prntscr.com/jcx16c Así es que en ese caso, es mejor buscar (dentro del array) el método de envío que contenga "chilexpress" nada más. El usuario podría tener varios métodos de envío configurados.

Luego de eso, usando WC() (gracias por el ayuda memoria), puedo obtener el total del shipping antes de crear la orden.

Moví el hook de vuelta a woocommerce_before_checkout_process con eso. Ahora no crea la orden. Y cambié el texto para agregar lo que querías, estimado.

Va actualización, de nuevo.

TCattd commented 6 years ago

El detalle https://github.com/whooohq/whq-woocommerce-chilexpress-shipping/commit/28a9e30f7e64bdde5a01a5062c27393277a79e47

Arriba la versión 1.3.12 La actualización debería aparecer en wordpress.org en breve ;)

Gracias por la ayuda, estimado!

PatrickCaneloDigital commented 6 years ago

perfecto... muchas gracias... con eso estamos. Gracias por la ayuda tambien, me hubiera costado mas integrarlo en un branch e reincluiro ;-) Saludos

PatrickCaneloDigital commented 6 years ago

un PD: La prueba que yo hacia tiene que ver con esto: El shipping_method_id del plugin se compone de 'chilexpress' mas: $service_id = $this->id . ':0'; $service_label = $this->title . ' (No Disponible)'; $service_value = 0; en el caso que no este disponible, o chilexpress:1 //ULTRA RÁPIDO:1 chilexpress:2 //OVERNIGHT:2 chilexpress:3 //DÍA HÁBIL SIGUIENTE:3 chilexpress:4 //DÍA HÁBIL SUBSIGUIENTE:4 chilexpress:5 //TERCER DÍA:5 por ende (pensaba yo, que la prueba por un shipping_method_id de "chilexpress:0" es suficiente ya que en el caso de no tener API y un costo de 0, en WC_WHQ_Chilexpress_Shipping en linea 652 se define que sea $service_id = $this->id . ':0';

PERO EN EL FONDO LA PRUEBA POR EL COSTO '0' y metodo de envio = chilexpress ES LO MISMO.