220 lines
8.7 KiB
Python
220 lines
8.7 KiB
Python
import logging
|
|
from uuid import uuid4
|
|
from config import load_config
|
|
|
|
|
|
def sync_catalog(conn_factuges, conn_mysql, last_execution_date):
|
|
config = load_config()
|
|
|
|
logging.info(f"Tarifa: {config['FACTUGES_NOMBRE_TARIFA']}")
|
|
logging.info(f"Precio punto: {config['FACTUGES_PRECIO_PUNTO']}")
|
|
|
|
# Construir la consulta SQL con la condición de fecha de modificación
|
|
consulta_sql_art_modificados = (
|
|
f"SELECT art.id || '' AS id, art.tarifa as tarifa, COALESCE(art.referencia,'') AS referencia, "
|
|
f"TRIM(COALESCE(art.familia, '') || ' ' || COALESCE(art.referencia_prov, '') || ' ' || COALESCE(art.descripcion, '')) as descripcion_es, "
|
|
f"TRIM(COALESCE(art_idioma_en.descripcion, '')) AS descripcion_en, "
|
|
f"TRUNC(art.precio_coste * 100) || '' AS puntos, "
|
|
f"TRUNC(ROUND(art.precio_coste * {
|
|
config['FACTUGES_PRECIO_PUNTO']}, 2) * 100) || '' AS pvp "
|
|
f"FROM articulos AS art "
|
|
f"LEFT JOIN ARTICULOS_IDIOMAS AS art_idioma_en ON art.id = art_idioma_en.id_articulo AND art_idioma_en.id_idioma = 2 "
|
|
f"WHERE "
|
|
f"(art.eliminado = 0) AND "
|
|
f"(art.tarifa = '{config['FACTUGES_NOMBRE_TARIFA']}') "
|
|
f"AND (art.FECHA_MODIFICACION > '{last_execution_date}')"
|
|
)
|
|
|
|
consulta_sql_all_tarifa = (
|
|
f"SELECT art.id || '' AS id, art.tarifa as tarifa "
|
|
f"FROM articulos AS art "
|
|
f"WHERE "
|
|
f"(art.eliminado = 0) AND "
|
|
f"(art.tarifa = '{config['FACTUGES_NOMBRE_TARIFA']}') "
|
|
)
|
|
|
|
# Crear un cursor para ejecutar consultas SQL
|
|
cursor_FactuGES = None
|
|
try:
|
|
cursor_FactuGES = conn_factuges.cursor()
|
|
# Ejecutar la consulta de articulos modificados
|
|
cursor_FactuGES.execute(consulta_sql_art_modificados)
|
|
filas = cursor_FactuGES.fetchall()
|
|
except Exception as e:
|
|
if cursor_FactuGES is not None:
|
|
cursor_FactuGES.close()
|
|
logging.error(f"(ERROR) Failed to fetch from database:{
|
|
config['FACTUGES_DATABASE']} - using user:{config['FACTUGES_USER']}")
|
|
logging.error(e)
|
|
raise e
|
|
|
|
# Obtener los nombres de las columnas
|
|
columnas = [desc[0] for desc in cursor_FactuGES.description]
|
|
cursor_FactuGES.close()
|
|
|
|
# Convertir las filas en diccionarios con nombres de columnas como claves
|
|
tuplas_seleccionadas = []
|
|
for fila in filas:
|
|
tupla = dict(zip(columnas, fila))
|
|
tuplas_seleccionadas.append(tupla)
|
|
|
|
logging.info(f"Catalog rows to be processed: {len(tuplas_seleccionadas)}")
|
|
|
|
# Verificar si hay filas en el resultado
|
|
if tuplas_seleccionadas:
|
|
insertar_datos(conn_mysql, tuplas_seleccionadas, config)
|
|
else:
|
|
logging.info(
|
|
"There are no new or modified catalog rows since the last run.")
|
|
|
|
# Verificamos que en el catálogo de mysql solo hay los artículos del catálogo de FactuGES
|
|
# es decir, que si un artículo lo asignan a otra tarifa debe desaparecer del catálogo mysql
|
|
try:
|
|
cursor_FactuGES.execute(consulta_sql_all_tarifa)
|
|
filas = cursor_FactuGES.fetchall()
|
|
cursor_FactuGES.close()
|
|
|
|
# Crear un conjunto con los IDs [0] de los artículos en FactuGES para una búsqueda rápida
|
|
ids_factuges = {str(fila[0]) for fila in filas}
|
|
logging.info(f"{config['FACTUGES_NOMBRE_TARIFA']} rows to be processed: {
|
|
len(ids_factuges)}")
|
|
|
|
# Verificar si hay filas en el resultado
|
|
if ids_factuges:
|
|
eliminar_datos(conn_mysql, ids_factuges, config)
|
|
else:
|
|
logging.info(f"There are no rows in the {
|
|
config['FACTUGES_NOMBRE_TARIFA']}.")
|
|
except Exception as e:
|
|
if cursor_FactuGES is not None:
|
|
cursor_FactuGES.close()
|
|
logging.error(f"(ERROR) Failed to fetch from database:{
|
|
config['FACTUGES_DATABASE']} - using user:{config['FACTUGES_USER']}")
|
|
logging.error(e)
|
|
raise e
|
|
|
|
|
|
def eliminar_datos(conn_mysql, ids_factuges, config):
|
|
# Recorrer todos los articulos del catálogo web para ver si estan en filas, si no están se eliminan
|
|
|
|
select_all_catalog_query = (
|
|
"SELECT catalog.id, catalog.id_article FROM catalog"
|
|
)
|
|
|
|
delete_catalog_query = (
|
|
"DELETE FROM catalog WHERE catalog.id_article = %s"
|
|
)
|
|
|
|
cursorMySQL = None
|
|
try:
|
|
cursorMySQL = conn_mysql.cursor()
|
|
cursorMySQL.execute(select_all_catalog_query)
|
|
catalog_rows = cursorMySQL.fetchall()
|
|
logging.info(
|
|
f">>>>Comprobar que todos los artículos del catálogo existen en FactuGES")
|
|
|
|
ids_a_eliminar = [
|
|
catalog_row[1] # id_article
|
|
for catalog_row in catalog_rows
|
|
if str(catalog_row[1]) not in ids_factuges
|
|
]
|
|
|
|
if ids_a_eliminar:
|
|
logging.info(f"Deleting articles: {ids_a_eliminar}")
|
|
cursorMySQL.executemany(delete_catalog_query, [(
|
|
id_article,) for id_article in ids_a_eliminar])
|
|
else:
|
|
logging.info("No articles to delete.")
|
|
|
|
except Exception as e:
|
|
# Escribir el error en el archivo de errores
|
|
logging.error(str(e))
|
|
raise e # Re-lanzar la excepción para detener el procesamiento
|
|
finally:
|
|
# Cerrar la conexión
|
|
if cursorMySQL is not None:
|
|
cursorMySQL.close()
|
|
|
|
|
|
def insertar_datos(conn_mysql, filas, config):
|
|
|
|
insert_catalog_query = (
|
|
"INSERT INTO catalog (id, catalog_name, id_article, points, retail_price, created_at, updated_at) "
|
|
"VALUES (%s, %s, %s, %s, %s, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)"
|
|
)
|
|
|
|
insert_translation_query = (
|
|
"INSERT INTO catalog_translations (id, lang_code, catalog_id, description) "
|
|
"VALUES (%s, %s, %s, %s)"
|
|
)
|
|
|
|
update_catalog_query = (
|
|
"UPDATE catalog set "
|
|
"points = %s, "
|
|
"retail_price = %s, "
|
|
"updated_at = Now() "
|
|
"WHERE id_article=%s"
|
|
)
|
|
|
|
update_translation_query = (
|
|
"UPDATE catalog_translations SET "
|
|
"description = %s "
|
|
"WHERE lang_code = %s AND "
|
|
"catalog_id IN (SELECT catalog.id FROM catalog WHERE catalog.id_article = %s)"
|
|
)
|
|
|
|
select_catalog_query = (
|
|
"SELECT count(catalog.id) FROM catalog WHERE catalog.id_article = %s"
|
|
)
|
|
|
|
cursorMySQL = None
|
|
try:
|
|
cursorMySQL = conn_mysql.cursor()
|
|
# Insertar datos en la tabla 'catalog'
|
|
for articulo in filas:
|
|
# Generar un ID único para la tabla catalog
|
|
id_catalog = str(uuid4())
|
|
id_article = int(articulo['ID'])
|
|
points = int(articulo['PUNTOS'])
|
|
retail_price = int(articulo['PVP'])
|
|
tarifa = config['FACTUGES_NOMBRE_TARIFA']
|
|
|
|
cursorMySQL.execute(select_catalog_query, (id_article, ))
|
|
row_count = cursorMySQL.fetchone()
|
|
is_new = row_count[0] < 1
|
|
|
|
if is_new:
|
|
logging.info(f"Inserting article {id_article} {tarifa}")
|
|
cursorMySQL.execute(
|
|
insert_catalog_query, (id_catalog, tarifa, id_article, points, retail_price))
|
|
else:
|
|
logging.info(f"Updating article {id_article} {tarifa}")
|
|
cursorMySQL.execute(update_catalog_query,
|
|
(points, retail_price, id_article))
|
|
|
|
# Insertar traducciones en la tabla 'catalog_translations'
|
|
for lang_code, desc_key in [('es', 'DESCRIPCION_ES'), ('en', 'DESCRIPCION_EN')]:
|
|
descripcion_traducida = articulo.get(desc_key, '')
|
|
if descripcion_traducida:
|
|
if (is_new):
|
|
logging.info(f"Inserting translation {
|
|
lang_code} {descripcion_traducida}")
|
|
# Generar un ID único para cada traducción
|
|
id_translation = str(uuid4())
|
|
cursorMySQL.execute(
|
|
insert_translation_query, (id_translation, lang_code, id_catalog, descripcion_traducida))
|
|
else:
|
|
logging.info(f"Updating translation {
|
|
lang_code} {descripcion_traducida}")
|
|
cursorMySQL.execute(
|
|
update_translation_query, (descripcion_traducida, lang_code, id_article))
|
|
|
|
except Exception as e:
|
|
# Escribir el error en el archivo de errores
|
|
logging.error(str(e))
|
|
raise e # Re-lanzar la excepción para detener el procesamiento
|
|
finally:
|
|
# Cerrar la conexión
|
|
if cursorMySQL is not None:
|
|
cursorMySQL.close()
|