Esta tienda en particular, para el cálculo de los gastos de envío, tiene unas 600 líneas diferentes, diferenciando por pesos y zonas geográficas. Hasta ahí algo normal. En su día alguien picaría a mano todas las líneas, pero ahora me piden que actualice la tarifa. Algo tan fácil como aplicarle un % de subida a la tarifa podría hacerse con una instrucción SQL, algo así como: (ajustando el nombre del campo y la tabla)
UPDATE precio = precio * 1.05 FROM TARIFAS
Pues no, resulta que en este software, los datos de las tarifas no están guardados como
SELECT shipment_params FROM xxxx_virtuemart_shipmentmethods;
Resumiendo, los parámetros (campos!!!!) están guardados como una cadena de texto formateada, de manera que ya no es tan sencillo hacer un "UPDATE".
Solución: habrá que usar un poquito de programación.
En primer lugar, creamos una función que nos da la funcionalidad de "SPLIT", es decir, dada una cadena de caracteres y un separador, devuelve la sección número "i".
Por ejemplo, SPLIT('primero;segundo;tercero', ';', 2) tendrá como resultado: 'segundo'
DROP FUNCTION IF EXISTS SPLIT_STRING;
DELIMITER $
CREATE FUNCTION
SPLIT_STRING ( s VARCHAR(1024) , del CHAR(1) , i INT)
RETURNS VARCHAR(1024)
DETERMINISTIC -- always returns same results for same input parameters
BEGIN
DECLARE n INT ;
-- get max number of items
SET n = LENGTH(s) - LENGTH(REPLACE(s, del, '')) + 1;
IF i > n THEN
RETURN NULL ;
ELSE
RETURN SUBSTRING_INDEX(SUBSTRING_INDEX(s, del, i) , del , -1 ) ;
END IF;
END
$
DELIMITER ;
DROP Function IF EXISTS my_precios;
DELIMITER $$
CREATE FUNCTION my_precios(entrada TEXT)
RETURNS TEXT
LANGUAGE SQL
BEGIN
DECLARE i INT ;
DECLARE trozo TEXT ;
DECLARE encontrado BOOLEAN ;
DECLARE coste_str TEXT;
DECLARE coste DOUBLE;
DECLARE nuevo_coste DOUBLE;
DECLARE nuevo_coste_str TEXT;
DECLARE nuevo_trozo TEXT;
SET i = 1;
SET encontrado = false;
REPEAT
SET trozo = SPLIT_STRING(entrada,'|',i);
IF not trozo IS NULL THEN
if trozo like '%cost%' THEN
SET coste_str = SPLIT_STRING(trozo,'"',2);
IF not coste_str IS NULL THEN
SET coste = CAST(coste_str AS DECIMAL(10,2));
SET encontrado = true;
END IF ;
END IF;
SET i = i + 1;
END IF;
UNTIL (trozo IS NULL) OR encontrado END REPEAT;
if encontrado then
set nuevo_coste = coste * 1.05;
set nuevo_coste_str = CAST(ROUND(nuevo_coste,2) as CHAR(5));
set nuevo_trozo = CONCAT('cost="', nuevo_coste_str, '"');
return REPLACE(entrada, trozo, nuevo_trozo);
else
return entrada;
end if ;
END;
$$
DELIMITER ;
Con estas funciones creadas, ya podemos hacer un simple UPDATE de lo que queremos:
UPDATE `xxxx_virtuemart_shipmentmethods`
set shipment_params= my_precios(shipment_params)
Aclaración 1: Lo de poner el porcentaje como parámetro sería una mejora
Aclaración 2: Estoy seguro que debe haber alguna expresión regular que hace la sustitución sin tanta complicación, pero no tenía tiempo de ponerme a investigar por ese lado.
0 comentarios:
Publicar un comentario