Skip to content
This repository has been archived by the owner on May 3, 2023. It is now read-only.

Calculo dimensiones en multiples productos . #15

Closed
llermaly opened this issue Jul 15, 2017 · 24 comments
Closed

Calculo dimensiones en multiples productos . #15

llermaly opened this issue Jul 15, 2017 · 24 comments

Comments

@llermaly
Copy link

Estimados,

Probando el plugin me encontré con que al comprar multiples productos entrega costos de envío erroneos, creo porque se están sumando las dimensiones de los productos acá :

https://github.com/whooohq/whq-woocommerce-chilexpress-shipping/blob/master/classes/WC_WHQ_Chilexpress_Shipping.php

Es decir, si por ej tengo 10 productos de 20x30x40 lo normal seria terminar con una pila de 200x30x40 como minimo, sin embargo con la formula queda un total de 200x300x400 . El peso lo omito porque ese si se suma.

Habría que elaborar un algoritmo que calcule el tamaño total tratando de conseguir "lo mas cuadrado posible" ya que si se hacen pilas sumando 1 de los lados solamente se podria caer en sobredimensionado sin que necesariamente sea así :

11. ¿Qué es un envío sobredimensionado?
Es toda encomienda que no cumpla el estándar establecido por Chilexpress, ya que posee una o más de estas características:
Tiene un embalaje irregular.
Pesa más de 50 kilos.
Sobrepasa alguna de estas tres medidas: 1,2 metros (largo) x 0,8 metros (ancho) x 0,8 metros (alto).

Encontré esta librería para hacer cajas , no sé si cumple el propósito o se puede sacar algo útil :

https://github.com/yetzt/boxing/blob/master/boxing.class.php

Y esta que es más producida :

https://github.com/dvdoug/BoxPacker

No creo que sea necesario ser tan precisos pero sí que la estimación no tire envíos de $100.000+ pesos si alguien compra 10 productos chicos.

Muchos saludos, si pillo algo más específico lo posteo acá.

@TCattd
Copy link
Collaborator

TCattd commented Jul 17, 2017

Esto sería una buena mejora al plugin.

Cuando tenga tiempo lo puedo ver.
Ahora, si alguien se adelanta y lo quiere ver antes, PR son bienvenidos y agradecidos.

@llermaly
Copy link
Author

llermaly commented Jul 17, 2017

Listo el pull request : #16

Por alguna razón pasados los 3 productos se pega un salto absurdo de precio, si alguien pudiera pegarle una mirada bacan.

saludos

@albetix
Copy link
Contributor

albetix commented Jul 22, 2017

@TCattd , hice unas modificaciones en la función que realiza el cálculo del paquete y quedó bastante mejor de lo que estaba.
La lógica fue la siguiente:

  • Modifiqué el cálculo del peso para que utilice fracciones de KG. Estaba sólo con kilos enteros y eso produce una diferencia de precio importante cuando cambia de un kilo al siguiente. En el caso de la tienda que estoy terminando, ningún producto pesa más de un kilo, por lo que en mi caso es muy relevante este cambio.
  • Para el cálculo del volumen consideré armar un bulto virtual para cada producto del carro, multiplicando la dimensión más pequeña de cada producto por la cantidad solicitada. Con esto obtenemos un bulto bastante óptimo para cantidades pequeñas (que es lo más usual).
  • Luego se arma el paquete final juntando los bultos virtuales por su lado más pequeño. Cada vez que se agrega un bulto virtual vuelve a determinar el lado más pequeño del paquete resultante antes de agregar el siguiente bulto virtual.
  • Al paquete final se le agrega un centímetro por cada lado para considerar el envoltorio del paquete (sería bueno dejar configurable este valor).

Eso sería. No es lo óptimo pero con este cambio el paquete final es bastante más pequeño que el que está calculando el plugin actualmente, y la diferencia de precio es tremenda.
A continuación va el código modificado para que lo revisen e incorporen en el plugin. La verdad es que soy bastante ignorante en GIT, y PHP no es mi fuerte.
Dejé un trozo del código anterior sólo para efectos de poder comparar el tamaño del paquete final. Ese trozo hay que eliminarlo una vez revisado el código. Lo mismo corre para las instrucciones de escritura en el log.
Me cuentas si puedo apoyar con algo más.

/**
    * calculate_shipping function.
    *
    * @access public
    * @param mixed $package
    * @return void
    */
public function calculate_shipping( $package = array() ) {
    $weight = 0;
    $length = 0;
    $width  = 0;
    $height = 0;

    $bultos = array();
    $bultos[0] = array(0, 0, 0);
    $nro_bulto = 1;
    $can_bulto = count($package['contents']);

    //Este ciclo hay que eliminarlo. Está sólo para comparar con el resultado final.
    foreach ( $package['contents'] as $item_id => $values ) {
        $_product = $values['data'];
        $weight   = round( $weight + $_product->get_weight() * $values['quantity'],3 );
        $length   = round( $length + $_product->get_length() * $values['quantity'],1 );
        $width    = round( $width + $_product->get_width() * $values['quantity'],1 );
        $height   = round( $height + $_product->get_height() * $values['quantity'],1 );
    }
    error_log(print_r("SCW-Paquete original:  Peso={$weight}  Largo={$length}  Ancho={$width} Alto={$height}", true));
    $weight = 0;
    //Eliminar hasta acá
    
    foreach ( $package['contents'] as $item_id => $values ) {
        $_product = $values['data'];
        //Calculates the final package weight
        $weight   = round( $weight + $_product->get_weight() * $values['quantity'],3 );
        //For each product in the cart generates one product package.
        $length   = round( $_product->get_length(),1 );
        $width    = round( $_product->get_width(),1 );
        $height   = round( $_product->get_height(),1 );
        $bultos[$nro_bulto] = array($length, $width, $height);
        //Orders the product dimensions in ascending order.
        sort($bultos[$nro_bulto]);
        error_log(print_r("SCW-TamPrdOr: La={$bultos[$nro_bulto][0]} An={$bultos[$nro_bulto][1]} Al={$bultos[$nro_bulto][2]}", true));
        //Multiply the smallest product dimension by the quantity to obtain the product package.
        $bultos[$nro_bulto][0] = round( $bultos[$nro_bulto][0] * $values['quantity'],1 );
        //Reorders the product package dimensions in ascendind order.
        sort($bultos[$nro_bulto]);
        error_log(print_r("SCW-TamBulOr: La={$bultos[$nro_bulto][0]} An={$bultos[$nro_bulto][1]} Al={$bultos[$nro_bulto][2]}", true));
        $nro_bulto++;
    }
    //Generates the final package.
    for ($i=1; $i <= $can_bulto; $i++) {
        $bultos[0][0] = $bultos[0][0] + $bultos[$i][0];
        $bultos[0][1] = $bultos[0][1] + $bultos[$i][1];
        $bultos[0][2] = $bultos[0][2] + $bultos[$i][2];
        //For each product package included reorders the resulting package by the smallest dimension.
        sort($bultos[0]);
        error_log(print_r("SCW-TamBul{$i}: La={$bultos[0][0]} An={$bultos[0][1]} Al={$bultos[0][2]}", true));
    }
    //Reorders the final package by the largest dimension, adds 2cm on each dimension (for the wrapping),
    //rounds up each value and trasfers the values to the final variables.
    //Maybe the value for the wrapping must be in the plugin configuration.
    rsort($bultos[0]);
    $length = (int) ceil($bultos[0][0]+2);
    $width  = (int) ceil($bultos[0][1]+2);
    $height = (int) ceil($bultos[0][2]+2);
    error_log(print_r("SCW-Paquete nuevo:  Peso={$weight}  Largo={$length}  Ancho={$width} Alto={$height}", true));

    if ( isset( $_POST['s_city'] ) && !is_null( $_POST['s_city'] ) ) {
        $city = $_POST['s_city'];
    } else {
        //And what about WC()->customer->get_shipping_city() ?
        $city = $package['destination']['city'];
    }

@llermaly
Copy link
Author

Hice algunas pruebas rápidas con productos de las mismas medidas y cumple el propósito.

Gracias @albetix ojalá se apruebe el cambio

@llermaly
Copy link
Author

llermaly commented Jul 22, 2017

@albetix
Agregué ahora 17 productos de 5x5x5 de 0.4kg y el total que obtuve fue :

Peso=6.8 Largo=87 Ancho=7 Alto=7

18 productos de 20x15x5 0.4 kg

Peso=7.2 Largo=92 Ancho=22 Alto=17,

Quizás está bien pero no me hace sentido que una dimensión se dispare siendo que se podría distribuir el total de otra manera.

Revisando más en detalle el código hay lineas que me llaman la atención, las dejo con un comentario por si aportan en algo :

$can_bulto = count($package['contents']);
Esta variable en verdad está registrando la cantidad de "tipos de producto", más que de productos en si, ya que si agrego 17 productos iguales va a ser 1, está bien eso?.

$bultos[$nro_bulto][0] = round( $bultos[$nro_bulto][0] * $values['quantity'],1 );
aqui estamos multiplicando medidas* cantidad que es lo que trajo los errores en la versión original. No será mejor iterar por la cantidad de productos e ir haciendo el tema del sort cada vez como en mi propuesta?. Te dejo el link : https://github.com/llermaly/whq-woocommerce-chilexpress-shipping/blob/8d9d8dfd4297fd856c952fb04c8561e6525321cd/classes/WC_WHQ_Chilexpress_Shipping.php

No sé por qué creo que haciendo un for de productos con un for de su cantidad dentro deberia arreglarse esto, qué opinan?.

Atte.

@albetix
Copy link
Contributor

albetix commented Jul 22, 2017

@llermaly,

En la versión actual del plugin (no la tuya), todas las dimensiones de cada producto se están multiplicando por la cantidad, por lo que el tamaño crece en forma exponencial.

$package['contents'] contiene la cantidad de productos distintos en el carro (no las unidades de cada uno de éstos), por lo que es correcto.

Efectivamente en $bultos[$nro_bulto][0] = round( $bultos[$nro_bulto][0] * $values['quantity'],1 ); se está multiplicando la medida más pequeña del producto por la cantidad de unidades solicitadas. Con esto queda un paquete bastante óptimo para pocas cantidades, pero muy largo en una sola dimensión cuando son muchas. Pero es mejor de lo que está actualmente en el plugin y creo que en general aplica bien a una gran parte de las soluciones de comercio electrónico. Obviamente es mejorable, pero el cálculo actual del plugin te asesina con las tarifas. En mi caso, con varias pruebas me salía más caro el despacho que el producto.

Lo que tu mencionas creo que se debe abordar en una segunda etapa, ya que la optimización del paquete puede tornarse bastante complicada, sobre todo si se pretende lograr llenar una caja de manera óptima. No lo veo tan fácil como un par de for.

Saludos.

@albetix
Copy link
Contributor

albetix commented Jul 22, 2017

@llermaly,

Ya había revisado tu alternativa, pero sólo considera el cálculo con dos dimensiones y no con las tres:

if(abs($ancho - $dimensiones[2]) < abs($largo - $dimensiones[0])){
    $dimensiones[0] = $largo + $dimensiones[0];
} else {
    $dimensiones[2] = $ancho + $dimensiones[2];
}

Por eso preferí buscar una solución que considerara las tres.

@llermaly
Copy link
Author

Me referia a la parte de mi alternativa que itera la cantidad de unidades por item. Tengo muy claro como funciona en plugin actualmente y que mi propuesta es inferior a la tuya al basarse en una funcion hecha que considera solo 2 lados.

En tu codigo si en vez de multiplicar la cantidad de items de un producto por el lado mas corto haces una iteracion por la cantidad de items donde en cada pasada vuelves a ordenar por el lado mas corto debería resultar y no dispararse un lado ya que estarías recalculando en cada iteración.

Corrígeme si me equivoco. Para qué esperar hasta el final para generar el paquete final si puedes meter esa iteración dentro de la otra para ir sumandole al paquete final cada item de cada producto.

por cada producto del carro
por cada item del producto (cuantity)
re-calcular paquete final
fin
devolver paquete final

P.S : Estamos de acuerdo en que es mucho mejor que multiplicar los lados x la cantidad ,pero por otro lado es importante corregirlo ya que matas a 2 tipos de vendedores dejando de lado las cantidades grandes

  1. Vendedores de productos chicos, ejemplo una librería
  2. Vendedor que tuvo el golpe de suerte y llegó alguien que quiso comprarle todo y al tirarle un envío mucho más caro que el real desistió.

@albetix
Copy link
Contributor

albetix commented Jul 22, 2017

@llermaly,

Insisto en que no es tan sencillo. Puedes hacer la prueba con papel y lápiz haciendo la iteración por cada unidad del producto, considerando 10 unidades de un producto de 10 x 10 x 8 y comprobarás que ya en la 4 unidad se empiezan a producir aberraciones. Y esto empeora si haces el mismo ejercicio con tres productos distintos y entre 5 y 7 unidades de cada uno considerando aproximadamente las mismas medidas.

Prefiero dar solución a un problema concreto que lleva varios días esperando un avance y que puede ayudar a muchos sitios. La solución para grandes cantidades requiere de más tiempo para poder llegar a un buen diseño conceptual.

@llermaly
Copy link
Author

llermaly commented Jul 23, 2017 via email

@albetix
Copy link
Contributor

albetix commented Jul 23, 2017

@llermaly,

A continuación va el desarrollo correcto con el ciclo adicional que propones:

1: 10x10x8 => 8x10x10 (reordenado de menor a mayor dimensión)
2: 16x10x10 => 10x10x16
3: 18x10x16 => 10x16x18
4: 18x16x18 => 16x18x18
5: 24x18x18 => 18x18x24
6: 26x18x24 => 18x24x26
7: 26x24x26 => 24x26x26
8: 32x26x26 => 26x26x32
9: 32x26x32 => 26x32x32
10: 32x32x32 => 32x32x32
Ajuste envoltorio => 34x34x34
Volumen final => 39.304 cm3

Opción con la lógica que propuse en el código resulta en 1 torre de 10 unidades:
Tamaño producto = 10x10x8 => 8x10x10 (reordenado de menor a mayor dimensión)
Tamaño paquete = 80x10x10 => 10x10x80
Ajuste envoltorio => 12x12x82
Volumen final => 11.088 cm3

Opción paquete manual: Dos torres de 5 unidades lado a lado:
Tamaño paquete = 10x10x40 y 10x10x40 => 20x10x40 => 10x20x40
Ajuste envoltorio => 12x22x42
Volumen final => 11.088 cm3

Conclusión: Con el ciclo que tu propones se obtiene casi 4 veces el volumen necesario.

Si quieres visualizarlo de forma más espacial, puedes hacer el mismo ejercicio con 10 piezas de dominó.

Es importante recordar que para el despacho lo relevante es el peso y el volumen del paquete.

@albetix
Copy link
Contributor

albetix commented Jul 24, 2017

@TCattd y @llermaly,

Mejoré la parte de la generación del paquete final. Estaba sumando todas dimesiones y eso estaba mal ya que para la segunda y tercera dimensión sólo debe considerar la más grande.

/**
    * calculate_shipping function.
    *
    * @access public
    * @param mixed $package
    * @return void
    */
public function calculate_shipping( $package = array() ) {
    $weight = 0;
    $length = 0;
    $width  = 0;
    $height = 0;

    $bultos = array();
    $bultos[0] = array(0, 0, 0);
    $nro_bulto = 1;
    $can_bulto = count($package['contents']);

    foreach ( $package['contents'] as $item_id => $values ) {
        $_product = $values['data'];
        $weight   = round( $weight + $_product->get_weight() * $values['quantity'],3 );
        $length   = round( $length + $_product->get_length() * $values['quantity'],1 );
        $width    = round( $width + $_product->get_width() * $values['quantity'],1 );
        $height   = round( $height + $_product->get_height() * $values['quantity'],1 );
    }
    error_log(print_r("SCW-Paquete original:  Peso={$weight}  Largo={$length}  Ancho={$width} Alto={$height}", true));

    $weight = 0;
    foreach ( $package['contents'] as $item_id => $values ) {
        $_product = $values['data'];
        //Calculates the final package weight
        $weight   = round( $weight + $_product->get_weight() * $values['quantity'],3 );
        //For each product in the cart generates one product package.
        $length   = round( $_product->get_length(),1 );
        $width    = round( $_product->get_width(),1 );
        $height   = round( $_product->get_height(),1 );
        $bultos[$nro_bulto] = array($length, $width, $height);
        //###error_log(print_r("SCW - TamPrduc: La={$bultos[$nro_bulto][0]} An={$bultos[$nro_bulto][1]} Al={$bultos[$nro_bulto][2]}", true));
        //Orders the product dimensions in ascending order.
        sort($bultos[$nro_bulto]);
        error_log(print_r("SCW-TamPrdOr: La={$bultos[$nro_bulto][0]} An={$bultos[$nro_bulto][1]} Al={$bultos[$nro_bulto][2]}", true));
        //Multiply the smallest product dimension by the quantity to obtain the product package.
        $bultos[$nro_bulto][0] = round( $bultos[$nro_bulto][0] * $values['quantity'],1 );
        //###error_log(print_r("SCW - TamBulto: La={$bultos[$nro_bulto][0]} An={$bultos[$nro_bulto][1]} Al={$bultos[$nro_bulto][2]}", true));
        //Orders the product package by the smallest dimension.
        sort($bultos[$nro_bulto]);
        error_log(print_r("SCW-TamBulOr: La={$bultos[$nro_bulto][0]} An={$bultos[$nro_bulto][1]} Al={$bultos[$nro_bulto][2]}", true));
        $nro_bulto++;
    }
    //Generates the final package.
    for ($nro_bulto=1; $nro_bulto <= $can_bulto; $nro_bulto++) {
        $bultos[0][0] = $bultos[0][0] + $bultos[$nro_bulto][0];
        if ( $bultos[$nro_bulto][1] > $bultos[0][1] ) {
            $bultos[0][1] = $bultos[$nro_bulto][1];
        }
        if ( $bultos[$nro_bulto][2] > $bultos[0][2] ) {
            $bultos[0][2] = $bultos[$nro_bulto][2];
        }
        //For each product package included reorders the resulting package by the smallest dimension.
        sort($bultos[0]);
        error_log(print_r("SCW-TamPaqIntPrd{$nro_bulto}: La={$bultos[0][0]} An={$bultos[0][1]} Al={$bultos[0][2]}", true));
    }
    //Reorders the final package by the largest dimension, adds 2cm on each dimension (for the wrapping),
    //rounds up each value and trasfers the values to the final variables.
    //Maybe the value for the wrapping must be in the plugin configuration.
    rsort($bultos[0]);
    $length = (int) ceil($bultos[0][0]+2);
    $width  = (int) ceil($bultos[0][1]+2);
    $height = (int) ceil($bultos[0][2]+2);
    error_log(print_r("SCW -Paquete nuevo:  Peso={$weight}  Largo={$length}  Ancho={$width} Alto={$height}", true));

    if ( isset( $_POST['s_city'] ) && !is_null( $_POST['s_city'] ) ) {
        $city = $_POST['s_city'];
    } else {
        //And what about WC()->customer->get_shipping_city() ?
        $city = $package['destination']['city'];
    }

@albetix
Copy link
Contributor

albetix commented Jul 24, 2017

@TCattd y @llermaly,

Si están de acuerdo con la última versión enviada a continuación va el código para llegar y reemplazar en el archivo.

/**
    * calculate_shipping function.
    *
    * @access public
    * @param mixed $package
    * @return void
    */
public function calculate_shipping( $package = array() ) {
    $weight = 0;
    $length = 0;
    $width  = 0;
    $height = 0;

    $bultos = array();
    $bultos[0] = array(0, 0, 0);
    $nro_bulto = 1;
    $can_bulto = count($package['contents']);

    foreach ( $package['contents'] as $item_id => $values ) {
        $_product = $values['data'];
        //Calculates the final package weight
        $weight   = round( $weight + $_product->get_weight() * $values['quantity'],3 );
        //For each product in the cart generates one product package.
        $length   = round( $_product->get_length(),1 );
        $width    = round( $_product->get_width(),1 );
        $height   = round( $_product->get_height(),1 );
        $bultos[$nro_bulto] = array($length, $width, $height);
        //Orders the product dimensions in ascending order.
        sort($bultos[$nro_bulto]);
        //Multiply the smallest product dimension by the quantity to obtain the product package.
        $bultos[$nro_bulto][0] = round( $bultos[$nro_bulto][0] * $values['quantity'],1 );
        //Reorders the product package by the smallest dimension.
        sort($bultos[$nro_bulto]);
        $nro_bulto++;
    }
    //Generates the final package.
    for ($nro_bulto=1; $nro_bulto <= $can_bulto; $nro_bulto++) {
        $bultos[0][0] = $bultos[0][0] + $bultos[$nro_bulto][0];
        if ( $bultos[$nro_bulto][1] > $bultos[0][1] ) {
            $bultos[0][1] = $bultos[$nro_bulto][1];
        }
        if ( $bultos[$nro_bulto][2] > $bultos[0][2] ) {
            $bultos[0][2] = $bultos[$nro_bulto][2];
        }
        //For each product package included reorders the resulting package by the smallest dimension.
        sort($bultos[0]);
    }
    //Reorders the final package by the largest dimension, adds 2cm on each dimension (for the wrapping),
    //rounds up each value and trasfers the values to the final variables.
    //Maybe the value for the wrapping must be in the plugin configuration.
    rsort($bultos[0]);
    $length = (int) ceil($bultos[0][0]+2);
    $width  = (int) ceil($bultos[0][1]+2);
    $height = (int) ceil($bultos[0][2]+2);

    if ( isset( $_POST['s_city'] ) && !is_null( $_POST['s_city'] ) ) {
        $city = $_POST['s_city'];
    } else {
        //And what about WC()->customer->get_shipping_city() ?
        $city = $package['destination']['city'];
    }

@albetix
Copy link
Contributor

albetix commented Jul 24, 2017

@TCattd y @llermaly,

A continuación va una versión más avanzada que estuve trabajando. Las mejoras que tiene respecto a la última enviada son las siguientes:

  • Calcula el volumen de cada paquete virtual por producto en el carro (bulto).
  • Ordena los bultos en forma descendente según su volumen para mejorar el armado del paquete final.
  • Si son más de 3 bultos, genera un nuevo bulto por cada dos bultos, considerando los de mayor volumen primero, utilizando el ordenamiento mencionado anteriormente. Con esto mejora la eficiencia en el armado del paquete final.

Lo estuve probando con cuatro y cinco productos. Funciona bastante bien. Este código va con todos los error_log para que puedan ver y comparar los resultados:

/**
    * calculate_shipping function.
    *
    * @access public
    * @param mixed $package
    * @return void
    */
public function calculate_shipping( $package = array() ) {
    $weight = 0;
    $length = 0;
    $width  = 0;
    $height = 0;

    $bultos = array();
    $bultos[0] = array(0, 0, 0, 0);
    $nro_bulto = 1;
    $can_bulto = count($package['contents']);

    //Este ciclo hay que eliminarlo. Está sólo para comparar con el resultado final.
    foreach ( $package['contents'] as $item_id => $values ) {
        $_product = $values['data'];
        $weight   = round( $weight + $_product->get_weight() * $values['quantity'],3 );
        $length   = round( $length + $_product->get_length() * $values['quantity'],1 );
        $width    = round( $width + $_product->get_width() * $values['quantity'],1 );
        $height   = round( $height + $_product->get_height() * $values['quantity'],1 );
    }
    $volume = $length * $width * $height;
    error_log(print_r("SCW-PaqOri: Kg={$weight} Vl={$volume} La={$length} An={$width} Al={$height}", true));
    $weight = 0;
    //Eliminar hasta acá

    foreach ( $package['contents'] as $item_id => $values ) {
        $_product = $values['data'];
        //Calculates the final package weight
        $weight   = round( $weight + $_product->get_weight() * $values['quantity'],3 );
        //For each product in the cart generates one product package.
        $length   = round( $_product->get_length(),1 );
        $width    = round( $_product->get_width(),1 );
        $height   = round( $_product->get_height(),1 );
        $bultos[$nro_bulto] = array(0, $length, $width, $height);
        //Orders the product dimensions in ascending order.
        sort($bultos[$nro_bulto]);
        error_log(print_r("SCW-TamPrdOr{$nro_bulto}: Al={$bultos[$nro_bulto][1]} An={$bultos[$nro_bulto][2]} La={$bultos[$nro_bulto][3]}", true));
        //Multiply the smallest product dimension by the quantity to obtain the product package.
        $bultos[$nro_bulto][1] = round( $bultos[$nro_bulto][1] * $values['quantity'],1 );
        //Reorders the product package dimensions in ascendind order.
        sort($bultos[$nro_bulto]);
        error_log(print_r("SCW-TamBulOr{$nro_bulto}: Al={$bultos[$nro_bulto][1]} An={$bultos[$nro_bulto][2]} La={$bultos[$nro_bulto][3]}", true));
        $nro_bulto++;
    }
    //Calculates the volume of each product package.
    for ($nro_bulto=1; $nro_bulto <= $can_bulto; $nro_bulto++) {
        $bultos[$nro_bulto][0] = $bultos[$nro_bulto][1] * $bultos[$nro_bulto][2] * $bultos[$nro_bulto][3];
    }
    //Orders the product packages by volume descending.
    $aux_array = array(0, 0, 0, 0);
    for ($i=1; $i < $can_bulto; $i++) {
        for ($nro_bulto=1; $nro_bulto < $can_bulto; $nro_bulto++) {
            if ( $bultos[$nro_bulto][0] < $bultos[$nro_bulto+1][0] ) {
                $aux_array = $bultos[$nro_bulto];
                $bultos[$nro_bulto] = $bultos[$nro_bulto+1];
                $bultos[$nro_bulto+1] = $aux_array;
            }
        }
    }
    for ($i=1; $i <= $can_bulto; $i++) {
        error_log(print_r("SCW-TBOVol{$i}: Vl={$bultos[$i][0]} Al={$bultos[$i][1]} An={$bultos[$i][2]} La={$bultos[$i][3]}", true));
    }

    //If the product packages are more than 3 then makes a new package
    //for every two product packages to improve the final package.
    if ( $can_bulto > 3 ) {
        //if the prodct packages are not even then generates a new empty package
        if (($can_bulto % 2) == 1) {
            $can_bulto++;
            $bultos[$can_bulto] = array(0, 0, 0, 0);
        }
        //Joins every two product packages in a new single product package
        $nro_bulto = 1;
        for ($i=1; $i < $can_bulto; $i+=2) {
            $bultos[$nro_bulto][1] = $bultos[$i][1] + $bultos[$i+1][1];
            if ( $bultos[$i][2] > $bultos[$i+1][2] ) {
                $bultos[$nro_bulto][2] = $bultos[$i][2];
            } else {
                $bultos[$nro_bulto][2] = $bultos[$i+1][2];
            }
            if ( $bultos[$i][3] > $bultos[$i+1][3] ) {
                $bultos[$nro_bulto][3] = $bultos[$i][3];
            } else {
                $bultos[$nro_bulto][3] = $bultos[$i+1][3];
            }
            $bultos[$nro_bulto][0] = 0;
            //Reorders the new product package dimensions in ascendind order.
            sort($bultos[$nro_bulto]);
            $nro_bulto++;
        }
        $can_bulto = $can_bulto / 2;
        for ($i=1; $i <= $can_bulto; $i++) {
            error_log(print_r("SCW-TBONew{$i}: Al={$bultos[$i][1]} An={$bultos[$i][2]} La={$bultos[$i][3]}", true));
        }
    }

    //Generates the final package.
    for ($nro_bulto=1; $nro_bulto <= $can_bulto; $nro_bulto++) {
        $bultos[0][1] = $bultos[0][1] + $bultos[$nro_bulto][1];
        if ( $bultos[$nro_bulto][2] > $bultos[0][2] ) {
            $bultos[0][2] = $bultos[$nro_bulto][2];
        }
        if ( $bultos[$nro_bulto][3] > $bultos[0][3] ) {
            $bultos[0][3] = $bultos[$nro_bulto][3];
        }
        //For each product package included reorders the resulting package by the smallest dimension.
        sort($bultos[0]);
        error_log(print_r("SCW-TamPaqIntPrd{$nro_bulto}: Al={$bultos[0][1]} An={$bultos[0][2]} La={$bultos[0][3]}", true));
    }
    //Reorders the final package by the largest dimension, adds 2cm on each dimension (for the wrapping),
    //rounds up each value and trasfers the values to the final variables.
    //Maybe the value for the wrapping must be in the plugin configuration.
    rsort($bultos[0]);
    $length = (int) ceil($bultos[0][0]+2);
    $width  = (int) ceil($bultos[0][1]+2);
    $height = (int) ceil($bultos[0][2]+2);
    $bultos[0][4] = $length * $width * $height;
    error_log(print_r("SCW-PaqNue: Kg={$weight} Vl={$bultos[0][4]} La={$length} An={$width} Al={$height}", true));

    if ( isset( $_POST['s_city'] ) && !is_null( $_POST['s_city'] ) ) {
        $city = $_POST['s_city'];
    } else {
        //And what about WC()->customer->get_shipping_city() ?
        $city = $package['destination']['city'];
    }

Si lo aprueban, le saco los error_log y lo que no debe ir, para dejarlo listo para ser publicado.

@TCattd
Copy link
Collaborator

TCattd commented Jul 24, 2017

Primero que todo, totalmente agradecido por la ayuda con esto, de verdad :)

Dudas @albetix

  • Acá http://prntscr.com/fzmev4 menor que, y menor o igual que, no deberían ser lo mismo en ambos casos?

  • Sobre esos mismos "for" para loops, si hay que caminar por todos los elementos del array, ¿algún motivo por el cual no usaste foreach? (es más rápido que el for, no necesita contar). Lo mismo comenté acá Se depura metodo que suma las dimensiones de multiples articulos en el carro #16 (comment)
    Aunque es marginal ese cambio, de todos modos el "foreach" es más limpio de leer que el viejo "for".
    Sería bueno que se reemplazaran por simples foreach si no van a usar el conteo dentro (del incremento $i inicial del "for"). Tal como lo hiciste acá al principio: http://prntscr.com/fzmhen

  • La idea de adicionar CM extra a añadir al tamaño del paquete, no es mala idea, y es mejor si lo metemos como configuración del plugin como comentaste ahí. Lo puedo agregar como opción yo al meter el método nuevo, no hay problema con eso.

Si puedes, comparte el método completo por favor (calculate_shipping) para publicarlo (con los cambios solicitados acá, por favor).
Yo le agrego lo de los CM extra como opción, y limpio los nombres (según esto).

No saques los error_log. No los saques, por favor. Tengo otra idea mejor al respecto para que convivan ahí y no molesten a los usuarios finales (no los necesitan), pero si nos ayuden a nosotros a debugear a futuro ;)

Y agradecido desde ya, lógicamente. Totalmente :)

Si quieres intentar hacer un PR tu mismo, te recomiendo https://desktop.github.com/ es muy sencillo de usar (facilita harto el trabajo con git en general).
Aunque si lo vas a intentar, pon ojo con las normas de contribución por favor, que si voy a hacer cumplir de aquí en adelante.

@llermaly
Copy link
Author

@albetix , se agradece la explicación, ya me queda más claro el tema de ir armando los montones, efectivamente aumentar el lado más corto sin más considera que siempre tenemos un cuadrado perfecto cuando no es así. Gracias.

Respecto al sobredimensionado comentar que el cotizador de Chilexpress no lo considera, solo tira un aviso, por lo que da igual que un lado quede de 2 metros y los demás de centímetros, estaba dando por sentado que sí le agregaba este monto al total final.

@albetix
Copy link
Contributor

albetix commented Jul 24, 2017

@TCattd,

Sobre tus consultas:

  1. Están bien. Si te fijas procesan desde el índice 1 (no consideran el primer elemento - índice 0).

  2. Utilicé for porque no procesan el array completo.

Sobre el código, cambié los nombres de las variables y ajusté el código a las normas. Instalé Desktop GitHub pero no me deja hacer el pull request. Arroja el siguiente mensaje:

Authentication failed. You may not have permission to access the repository. Open options and verify that you're signed in with an account that has permission to access this repository.

@TCattd
Copy link
Collaborator

TCattd commented Jul 24, 2017

Gracias por aclarar las dudas, @albetix :)

Para poder hacer un PR en GitHub, primero tienes que hacer un fork en tu propia cuenta de GitHub. El fork acá arriba: http://prntscr.com/fzoxm0
Después de hacer los cambios al plugin, en una rama/branch nueva en tu copia del repositorio en GitHub, puedes enviar el PR a través de GitHub mismo. El proceso completo está acá: https://akrabat.com/the-beginners-guide-to-contributing-to-a-github-project/ (aunque las partes con la linea de comandos las puedes ignorar, si vas a usar Github for Desktop).

Si no quieres darte ese trabajo aún, puedes compartir el método acá completo, no hay problema tampoco (por ahora).

¡Gracias desde ya!

@albetix
Copy link
Contributor

albetix commented Jul 24, 2017

@TCattd,

Listo el Pull Request.

@TCattd
Copy link
Collaborator

TCattd commented Jul 24, 2017

Lanzada la versión 1.1.7

Agradecimientos totales a ambos por la ayuda en esto.

En especial a @albetix que se pasó :)

@TCattd TCattd closed this as completed Jul 24, 2017
@albetix
Copy link
Contributor

albetix commented Jul 24, 2017

@TCattd,

De nada. Feliz de aportar!

@albetix
Copy link
Contributor

albetix commented Jul 24, 2017

@TCattd,

Consulta, ¿cómo puedo mantener el fork de este plugin actualizado en GitHub Desktop?. No encontré ninguna opción que permita hacerlo.
Gracias!

@TCattd
Copy link
Collaborator

TCattd commented Jul 24, 2017

@albetix puedes hacerlo directamente desde la interfaz web de GitHub https://stackoverflow.com/a/23853061/920648

O puedes aplicar linea de comandos en tu copia local del repo fork: https://stackoverflow.com/a/7244456/920648

Ignoro si GitHub Desktop tiene algo por el estilo implementado aún o no.

@TCattd
Copy link
Collaborator

TCattd commented Jul 24, 2017

Ver http://prntscr.com/fztb3t

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants