2025-09-04 16:54:32 +00:00
import logging
from uuid import uuid4
from config import load_config
from decimal import Decimal
def sync_invoices ( conn_factuges , conn_mysql , last_execution_date ) :
config = load_config ( )
2025-09-10 17:38:41 +00:00
# Recorrer todas las facturas eliminadas para liberarlas en factuges
# VERIFACTU = 0 and ID_VERIFACTU = NULL
consulta_sql_customer_invoices_deleted = (
f " SELECT ci.id "
f " FROM customer_invoices as ci "
2025-09-04 16:54:32 +00:00
f " WHERE "
2025-09-10 17:38:41 +00:00
f " (ci.deleted_at is not null) "
2025-09-04 16:54:32 +00:00
)
consulta_sql_FACTURAS_CLIENTE = (
f " SELECT fac.VERIFACTU, fac.ID_VERIFACTU, fac.ID || ' ' AS ID, fac.ID_EMPRESA || ' ' AS ID_EMPRESA, fac.REFERENCIA, fac.FECHA_FACTURA, fac.ID_CLIENTE || ' ' as ID_CLIENTE, fac.NIF_CIF, fac.NOMBRE, "
f " fac.CALLE, fac.POBLACION, fac.PROVINCIA, fac.CODIGO_POSTAL, fac.FECHA_ALTA, "
2025-09-10 17:38:41 +00:00
f " fac.IMPORTE_NETO, fac.DESCUENTO, fac.IMPORTE_DESCUENTO, fac.BASE_IMPONIBLE, fac.IVA, fac.IMPORTE_IVA, fac.IMPORTE_TOTAL, "
f " fac.ID_FORMA_PAGO, fp.DESCRIPCION as DES_FORMA_PAGO, fac.ID_TIPO_IVA, ti.REFERENCIA as DES_TIPO_IVA, fac.RECARGO_EQUIVALENCIA, fac.RE, fac.IMPORTE_RE, "
f " fac.ID_CLIENTE, fac.NIF_CIF, fac.NOMBRE, fac.CALLE, fac.POBLACION, fac.PROVINCIA, fac.CODIGO_POSTAL, "
2025-09-18 10:41:06 +00:00
f " cc.TELEFONO_1, cc.TELEFONO_2, cc.MOVIL_1, cc.MOVIL_2, cc.EMAIL_1, cc.EMAIL_2, cc.PAGINA_WEB, "
2025-09-10 17:38:41 +00:00
f " facdet.ID || ' ' as ID_DET, facdet.ID_FACTURA, facdet.POSICION, facdet.TIPO_DETALLE, facdet.ID_ARTICULO, facdet.CONCEPTO, facdet.CANTIDAD, "
2025-09-18 10:41:06 +00:00
f " facdet.IMPORTE_UNIDAD, facdet.DESCUENTO as DESCUENTO_DET, facdet.IMPORTE_TOTAL as IMPORTE_TOTAL_DET, facdet.VISIBLE, facdet.FECHA_ALTA as FECHA_ALTA_DET, facdet.FECHA_MODIFICACION as FECHA_MODIFICACION_DET "
2025-09-04 16:54:32 +00:00
f " FROM FACTURAS_CLIENTE AS fac "
2025-09-18 10:41:06 +00:00
f " LEFT JOIN CONTACTOS AS cc ON fac.ID_CLIENTE = cc.ID "
2025-09-04 16:54:32 +00:00
f " LEFT JOIN FORMAS_PAGO AS fp ON fac.ID_FORMA_PAGO = fp.ID "
2025-09-10 17:38:41 +00:00
f " LEFT JOIN TIPOS_IVA AS ti ON fac.ID_TIPO_IVA = ti.ID "
f " LEFT JOIN FACTURAS_CLIENTE_DETALLES as facdet ON fac.ID = facdet.ID_FACTURA "
2025-09-04 16:54:32 +00:00
f " WHERE "
f " (fac.VERIFACTU > 0) "
f " AND (fac.ID_VERIFACTU is null) "
2025-09-10 17:38:41 +00:00
f " ORDER BY (fac.ID) "
2025-09-04 16:54:32 +00:00
)
2025-09-10 17:38:41 +00:00
# Crear un cursor para ejecutar consultas SQL
cursor_mysql = None
try :
cursor_mysql = conn_mysql . cursor ( )
# Ejecutar la consulta de FACTURAS_CLIENTE
cursor_mysql . execute ( consulta_sql_customer_invoices_deleted )
filas = cursor_mysql . fetchall ( )
cursor_mysql . close ( )
# Crear un conjunto con los IDs [0] de los customer_inovices que debo liberar en FactuGES
ids_verifactu_deleted = { str ( fila [ 0 ] ) for fila in filas }
logging . info ( f " Customer invoices rows to be deleted: {
len ( ids_verifactu_deleted ) } " )
# Verificar si hay filas en el resultado
if ids_verifactu_deleted :
eliminar_datos ( conn_factuges , ids_verifactu_deleted , config )
else :
logging . info ( f " There are no rows to deleted " )
except Exception as e :
if cursor_mysql is not None :
cursor_mysql . close ( )
logging . error ( f " (ERROR) Failed to fetch from database: {
config [ ' UECKO_MYSQL_DATABASE ' ] } - using user : { config [ ' UECKO_MYSQL_USER ' ] } " )
logging . error ( e )
raise e
2025-09-04 16:54:32 +00:00
# Crear un cursor para ejecutar consultas SQL
cursor_FactuGES = None
try :
cursor_FactuGES = conn_factuges . cursor ( )
# Ejecutar la consulta de FACTURAS_CLIENTE
cursor_FactuGES . execute ( consulta_sql_FACTURAS_CLIENTE )
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 (
2025-09-10 17:38:41 +00:00
f " FACTURAS_CLIENTE_DETALLE rows to be processed: { len ( tuplas_seleccionadas ) } " )
2025-09-04 16:54:32 +00:00
# Verificar si hay filas en el resultado
if tuplas_seleccionadas :
insertar_datos ( conn_mysql , tuplas_seleccionadas , conn_factuges , config )
else :
logging . info (
2025-09-10 17:38:41 +00:00
" There are no new FACTURAS rows since the last run. " )
# Verificamos que en customer_invoice de mysql no se ha eliminado ninguna factura,
# si se ha eliminado alguna factura, procedemos quitar la asociación en factuges para que se pueda modificar
# en un futuro se modificará solo en el programa nuevo y tendrá que sincronizarse con factuges los importes totales de la factura
# ya pasamos de los detalles ya que no se van a ver las facturas en FactuGES, pero la relación que tengan las facturas con otros módulos
# deben verse, ejemplo contratos-facturas
# try:
# cursor_FactuGES.execute(consulta_sql_FACTURAS_CLIENTE)
# filas = cursor_FactuGES.fetchall()
# cursor_FactuGES.close()
2025-09-04 16:54:32 +00:00
# Crear un conjunto con los IDs [0] de los artículos en FactuGES para una búsqueda rápida
2025-09-10 17:38:41 +00:00
# ids_factuges = {str(fila[0]) for fila in filas}
# logging.info(f"customer_invoice rows to be processed: {
# len(ids_factuges)}")
2025-09-04 16:54:32 +00:00
# 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']}.")
2025-09-10 17:38:41 +00:00
# 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
2025-09-04 16:54:32 +00:00
2025-09-10 17:38:41 +00:00
def eliminar_datos ( conn_factuges , ids_verifactu_deleted , config ) :
2025-09-04 16:54:32 +00:00
# Recorrer todos los articulos del catálogo web para ver si estan en filas, si no están se eliminan
2025-09-10 17:38:41 +00:00
update_facturas_cliente_query = (
f " UPDATE FACTURAS_CLIENTE "
f " SET ID_VERIFACTU = NULL, "
f " VERIFACTU = 0 "
f " WHERE (ID_VERIFACTU = ?) "
2025-09-04 16:54:32 +00:00
)
2025-09-10 17:38:41 +00:00
cursor_FactuGES = None
2025-09-04 16:54:32 +00:00
try :
2025-09-10 17:38:41 +00:00
cursor_FactuGES = conn_factuges . cursor ( )
if ids_verifactu_deleted :
logging . info ( f " Liberate factures: { ids_verifactu_deleted } " )
cursor_FactuGES . executemany ( update_facturas_cliente_query , [ (
id_verifactu , ) for id_verifactu in ids_verifactu_deleted ] )
2025-09-04 16:54:32 +00:00
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
2025-09-10 17:38:41 +00:00
if cursor_FactuGES is not None :
cursor_FactuGES . close ( )
2025-09-04 16:54:32 +00:00
def insertar_datos ( conn_mysql , filas , conn_factuges , config ) :
2025-09-10 17:38:41 +00:00
cte_company_id = ' 5e4dc5b3-96b9-4968-9490-14bd032fec5f '
2025-09-04 16:54:32 +00:00
insert_customer_query = (
2025-09-18 10:41:06 +00:00
" INSERT INTO customers (id, name, tin, street, city, province, postal_code, country, phone_primary, phone_secondary, mobile_primary, mobile_secondary, "
" email_primary, email_secondary, website, factuges_id, company_id, is_company, language_code, currency_code, status, created_at, updated_at ) "
" VALUES ( %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , 1, ' es ' , ' EUR ' , ' active ' , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) "
2025-09-04 16:54:32 +00:00
)
2025-09-22 17:32:39 +00:00
insert_payment_methods_query = (
" INSERT INTO payment_methods (id, description, factuges_id, created_at, updated_at ) "
" VALUES ( %s , %s , %s , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) "
)
2025-09-10 17:38:41 +00:00
insert_customer_invoices_query = (
" INSERT INTO customer_invoices (id, company_id, status, series, invoice_number, invoice_date, operation_date, "
" subtotal_amount_value, discount_amount_value, discount_percentage_value, taxable_amount_value, taxes_amount_value, total_amount_value, "
" customer_id, customer_tin, customer_name, customer_street, customer_city, customer_province, customer_postal_code, customer_country, "
2025-09-22 17:32:39 +00:00
" payment_method_id, payment_method_description, "
2025-09-10 17:38:41 +00:00
" subtotal_amount_scale, discount_amount_scale, discount_percentage_scale, taxable_amount_scale, taxes_amount_scale, total_amount_scale, "
" language_code, currency_code, created_at, updated_at) "
2025-09-22 17:32:39 +00:00
" VALUES ( %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , %s , 2, 2, 2, 2, 2, 2, ' es ' , ' EUR ' , CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) "
2025-09-10 17:38:41 +00:00
)
2025-09-04 16:54:32 +00:00
2025-09-10 17:38:41 +00:00
insert_customer_invoices_taxes_query = (
" INSERT INTO customer_invoice_taxes (tax_id, invoice_id, tax_code, taxable_amount_value, taxes_amount_value, taxable_amount_scale, taxes_amount_scale, "
" created_at, updated_at) "
" VALUES ( %s , %s , %s , %s , %s , 2, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) "
2025-09-04 16:54:32 +00:00
)
2025-09-10 17:38:41 +00:00
insert_customer_invoice_items_query = (
" INSERT INTO customer_invoice_items (item_id, invoice_id, position, description, quantity_value, unit_amount_value, discount_percentage_value, discount_amount_value, total_amount_value, "
" quantity_scale, unit_amount_scale, discount_amount_scale, total_amount_scale, discount_percentage_scale, created_at, updated_at) "
" VALUES ( %s , %s , %s , %s , %s , %s , %s , %s , %s , 2, 4, 2, 4, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) "
2025-09-04 16:54:32 +00:00
)
2025-09-10 17:38:41 +00:00
insert_customer_invoice_item_taxes_query = (
" INSERT INTO customer_invoice_item_taxes (tax_id, item_id, tax_code, taxable_amount_value, taxes_amount_value, taxable_amount_scale, taxes_amount_scale, "
" created_at, updated_at) "
" VALUES ( %s , %s , %s , %s , %s , 4, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) "
2025-09-04 16:54:32 +00:00
)
2025-09-10 17:38:41 +00:00
update_FACTURAS_CLIENTE_query = (
" UPDATE FACTURAS_CLIENTE set ID_VERIFACTU = ? WHERE ID = ? " )
2025-09-04 16:54:32 +00:00
select_customer_query = (
2025-09-10 17:38:41 +00:00
" SELECT customers.id "
" FROM customers "
" WHERE customers.factuges_id = %s "
2025-09-04 16:54:32 +00:00
)
2025-09-22 17:32:39 +00:00
select_payment_method_query = (
" SELECT payment_methods.id "
" FROM payment_methods "
" WHERE payment_methods.factuges_id = %s "
)
2025-09-04 16:54:32 +00:00
cursorMySQL = None
cursor_FactuGES = None
2025-09-10 17:38:41 +00:00
factuges_id_anterior = None
id_customer_invoice = None
num_fac_procesed = 0
2025-09-04 16:54:32 +00:00
try :
cursorMySQL = conn_mysql . cursor ( )
cursor_FactuGES = conn_factuges . cursor ( )
# Insertar datos en la tabla 'customer_invoices'
2025-09-10 17:38:41 +00:00
for factura_detalle in filas :
factuges_id = int ( factura_detalle [ ' ID_FACTURA ' ] )
2025-09-04 16:54:32 +00:00
invoice_status = str ( ' draft ' )
invoice_series = str ( ' A ' )
2025-09-10 17:38:41 +00:00
invoice_number = str ( factura_detalle [ ' REFERENCIA ' ] )
invoice_date = str ( factura_detalle [ ' FECHA_FACTURA ' ] )
operation_date = str ( factura_detalle [ ' FECHA_FACTURA ' ] )
2025-09-04 16:54:32 +00:00
# siempre tendrán 2 decimales
2025-09-10 17:38:41 +00:00
subtotal_amount_value = ( factura_detalle [ ' IMPORTE_NETO ' ] or 0 ) * 100
discount_amount_value = (
factura_detalle [ ' IMPORTE_DESCUENTO ' ] or 0 ) * 100
discount_percentage_value = (
2025-09-18 10:41:06 +00:00
factura_detalle [ ' DESCUENTO ' ] or 0 ) * 100 if ( factura_detalle [ ' DESCUENTO ' ] ) is not None else 0
2025-09-10 17:38:41 +00:00
taxable_amount_value = ( factura_detalle [ ' BASE_IMPONIBLE ' ] or 0 ) * 100
2025-09-18 10:41:06 +00:00
# Preparamos el tipo de IVA, en FactuGES es único
2025-09-10 17:38:41 +00:00
tax_code = str ( factura_detalle [ ' DES_TIPO_IVA ' ] )
2025-09-18 10:41:06 +00:00
if tax_code == ' IVA21 ' :
tax_code = ' iva_21 '
elif tax_code == ' IVA18 ' :
tax_code = ' iva_18 '
elif tax_code == ' IVA16 ' :
tax_code = ' iva_16 '
elif tax_code == ' IVA10 ' :
tax_code = ' iva_10 '
else :
tax_code = ' '
# La cuota de impuestos es el IVA + RE
tax_amount_value = (
( factura_detalle [ ' IMPORTE_IVA ' ] or 0 ) + ( factura_detalle [ ' IMPORTE_RE ' ] or 0 ) ) * 100
2025-09-10 17:38:41 +00:00
total_amount_value = ( factura_detalle [ ' IMPORTE_TOTAL ' ] or 0 ) * 100
2025-09-22 17:32:39 +00:00
payment_method_id = str ( uuid4 ( ) )
factuges_payment_method_id = str ( factura_detalle [ ' ID_FORMA_PAGO ' ] )
2025-09-10 17:38:41 +00:00
payment_method_description = str ( factura_detalle [ ' DES_FORMA_PAGO ' ] )
2025-09-04 16:54:32 +00:00
customer_id = str ( uuid4 ( ) )
2025-09-10 17:38:41 +00:00
factuges_customer_id = str ( factura_detalle [ ' ID_CLIENTE ' ] )
customer_tin = str ( factura_detalle [ ' NIF_CIF ' ] )
customer_name = str ( factura_detalle [ ' NOMBRE ' ] )
customer_street = str ( factura_detalle [ ' CALLE ' ] )
customer_city = str ( factura_detalle [ ' POBLACION ' ] )
customer_province = str ( factura_detalle [ ' PROVINCIA ' ] )
customer_postal_code = str ( factura_detalle [ ' CODIGO_POSTAL ' ] )
2025-09-18 10:41:06 +00:00
customer_phone_primary = factura_detalle [ ' TELEFONO_1 ' ]
customer_phone_secondary = factura_detalle [ ' TELEFONO_2 ' ]
customer_mobile_primary = factura_detalle [ ' MOVIL_1 ' ]
customer_mobile_secondary = factura_detalle [ ' MOVIL_2 ' ]
customer_email_primary = factura_detalle [ ' EMAIL_1 ' ]
customer_email_secondary = factura_detalle [ ' EMAIL_2 ' ]
customer_webside = str ( factura_detalle [ ' PAGINA_WEB ' ] )
2025-09-04 16:54:32 +00:00
customer_country = ' es '
2025-09-10 17:38:41 +00:00
item_position = int ( factura_detalle [ ' POSICION ' ] )
item_description = str ( factura_detalle [ ' CONCEPTO ' ] )
2025-09-18 10:41:06 +00:00
item_quantity_value = None if factura_detalle [ ' CANTIDAD ' ] is None else (
factura_detalle [ ' CANTIDAD ' ] or 0 ) * 100
item_unit_amount_value = None if factura_detalle [ ' IMPORTE_UNIDAD ' ] is None else (
2025-09-10 17:38:41 +00:00
factura_detalle [ ' IMPORTE_UNIDAD ' ] or 0 ) * 10000
2025-09-22 17:32:39 +00:00
Descuento = factura_detalle [ ' DESCUENTO ' ]
item_discount_percentage_value = None if Descuento is None else None if Descuento == 0 else (
factura_detalle [ ' DESCUENTO ' ] ) * 100
2025-09-10 17:38:41 +00:00
item_discount_amount = None
2025-09-22 17:32:39 +00:00
# Se calcula en el objeto de negocio de nuevo, comprobar si coincide
2025-09-10 17:38:41 +00:00
# item_discount_amount = (
# (factura_detalle['IMPORTE_UNIDAD'] or 0)*((factura_detalle['DESCUENTO'] or 0)/100))*100
2025-09-18 10:41:06 +00:00
item_total_amount = None if factura_detalle [ ' IMPORTE_TOTAL_DET ' ] is None else (
factura_detalle [ ' IMPORTE_TOTAL_DET ' ] or 0 ) * 100
2025-09-10 17:38:41 +00:00
2025-09-04 16:54:32 +00:00
# campos pendiente de revisar en un futuro
2025-09-10 17:38:41 +00:00
# xxxxxxx = str(factura_detalle['ID_EMPRESA'])
# xxxxxxx = str(factura_detalle['ID_FORMA_PAGO']) según este id se debe de guardar en la factura los vencimiento asociados a la forma de pago
# xxxxxxx = str(factura_detalle['OBSERVACIONES'])
2025-09-04 16:54:32 +00:00
2025-09-10 17:38:41 +00:00
if factuges_id_anterior is None or factuges_id_anterior != factuges_id :
2025-09-22 17:32:39 +00:00
# Comprobamos si existe el cliente del primer item de la factura
2025-09-10 17:38:41 +00:00
cursorMySQL . execute ( select_customer_query ,
( factuges_customer_id , ) )
row = cursorMySQL . fetchone ( )
is_new = ( row is None ) or ( row [ 0 ] is None )
if is_new :
logging . info (
f " Inserting customer { factuges_customer_id } { customer_tin } { customer_name } " )
cursorMySQL . execute ( insert_customer_query , ( customer_id , customer_name , customer_tin , customer_street , customer_city , customer_province ,
2025-09-18 10:41:06 +00:00
customer_postal_code , customer_country , customer_phone_primary , customer_phone_secondary , customer_mobile_primary ,
customer_mobile_secondary , customer_email_primary , customer_email_secondary , customer_webside , factuges_customer_id , cte_company_id ) )
2025-09-10 17:38:41 +00:00
else :
# Si ya exite ponemos el id del customer correspondiente
customer_id = str ( row [ 0 ] )
logging . info (
f " Updating customer { factuges_customer_id } { customer_id } " )
# cursorMySQL.execute(update_customer_query, .....)
2025-09-22 17:32:39 +00:00
# Comprobamos si existe la forma de pago del primer item de la factura
cursorMySQL . execute ( select_payment_method_query ,
( factuges_payment_method_id , ) )
row = cursorMySQL . fetchone ( )
is_new = ( row is None ) or ( row [ 0 ] is None )
if is_new :
logging . info (
f " Inserting cuspayment method { factuges_payment_method_id } { payment_method_id } { payment_method_description } " )
cursorMySQL . execute ( insert_payment_methods_query , (
payment_method_id , payment_method_description , factuges_payment_method_id ) )
else :
# Si ya exite ponemos el id del customer correspondiente
payment_method_id = str ( row [ 0 ] )
logging . info (
f " Updating customer { factuges_payment_method_id } { payment_method_id } " )
# cursorMySQL.execute(update_customer_query, .....)
2025-09-10 17:38:41 +00:00
# Insertamos cabecera de la factura
# Generar un ID único para la tabla customer_invoices
id_customer_invoice = str ( uuid4 ( ) )
2025-09-04 16:54:32 +00:00
logging . info (
2025-09-10 17:38:41 +00:00
f " Inserting customer_invoice { id_customer_invoice } { invoice_number } { invoice_date } " )
cursorMySQL . execute ( insert_customer_invoices_query , ( id_customer_invoice , cte_company_id , invoice_status , invoice_series , invoice_number , invoice_date , operation_date ,
subtotal_amount_value , discount_amount_value , discount_percentage_value , taxable_amount_value , tax_amount_value , total_amount_value ,
2025-09-22 17:32:39 +00:00
customer_id , customer_tin , customer_name , customer_street , customer_city , customer_province , customer_postal_code , customer_country ,
payment_method_id , payment_method_description ) )
2025-09-10 17:38:41 +00:00
2025-09-18 10:41:06 +00:00
# Insertamos el IVA y RE si viene
if ( factura_detalle [ ' IVA ' ] > 0 ) :
taxable_amount_value = (
factura_detalle [ ' BASE_IMPONIBLE ' ] ) * 100
tax_amount_value = ( factura_detalle [ ' IMPORTE_IVA ' ] ) * 100
cursorMySQL . execute ( insert_customer_invoices_taxes_query , ( str ( uuid4 ( ) ) ,
id_customer_invoice , tax_code , taxable_amount_value , tax_amount_value ) )
2025-09-10 17:38:41 +00:00
if ( factura_detalle [ ' RECARGO_EQUIVALENCIA ' ] > 0 ) :
2025-09-18 10:41:06 +00:00
tax_code = ' re_5_2 '
taxable_amount_value = (
factura_detalle [ ' BASE_IMPONIBLE ' ] ) * 100
2025-09-10 17:38:41 +00:00
tax_amount_value = ( factura_detalle [ ' IMPORTE_RE ' ] ) * 100
cursorMySQL . execute ( insert_customer_invoices_taxes_query , ( str ( uuid4 ( ) ) ,
id_customer_invoice , tax_code , taxable_amount_value , tax_amount_value ) )
# Guardamos en Factuges el id de la customer_invoice
2025-09-04 16:54:32 +00:00
logging . info (
2025-09-10 17:38:41 +00:00
f " Updating FACTURAS_CLIENTE { id_customer_invoice } { factuges_id } " )
cursor_FactuGES . execute (
update_FACTURAS_CLIENTE_query , ( id_customer_invoice , factuges_id ) )
num_fac_procesed + = 1
# Insertamos detalles y taxes correspondientes siempre
# Generar un ID único para la tabla customer_invoice_items
item_id = str ( uuid4 ( ) )
2025-09-04 16:54:32 +00:00
logging . info (
2025-09-10 17:38:41 +00:00
f " Inserting customer_invoice_items { id_customer_invoice } { item_position } { item_quantity_value } " )
cursorMySQL . execute ( insert_customer_invoice_items_query , ( item_id , id_customer_invoice , item_position , item_description ,
item_quantity_value , item_unit_amount_value , item_discount_percentage_value , item_discount_amount , item_total_amount ) )
if tax_code == ' IVA21 ' :
tax_amount_value = (
( factura_detalle [ ' IMPORTE_TOTAL ' ] or 0 ) * Decimal ( 0.21 ) ) * 100
elif tax_code == ' IVA18 ' :
tax_amount_value = (
( factura_detalle [ ' IMPORTE_TOTAL ' ] or 0 ) * Decimal ( 0.18 ) ) * 100
elif tax_code == ' IVA16 ' :
tax_amount_value = (
( factura_detalle [ ' IMPORTE_TOTAL ' ] or 0 ) * Decimal ( 0.16 ) ) * 100
elif tax_code == ' IVA10 ' :
tax_amount_value = (
( factura_detalle [ ' IMPORTE_TOTAL ' ] or 0 ) * Decimal ( 0.10 ) ) * 100
else :
tax_amount_value = item_total_amount
2025-09-04 16:54:32 +00:00
logging . info (
2025-09-10 17:38:41 +00:00
f " Inserting customer_invoice_item_taxes { item_id } { item_position } { tax_code } { tax_amount_value } " )
cursorMySQL . execute ( insert_customer_invoice_item_taxes_query , ( str ( uuid4 ( ) ) , item_id , tax_code ,
item_total_amount , tax_amount_value ) )
# Asignamos el id factura anterior para no volver a inserta cabecera
factuges_id_anterior = factuges_id
logging . info (
f " FACTURAS_CLIENTE rows to be processed: { str ( num_fac_procesed ) } " )
2025-09-04 16:54:32 +00:00
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
2025-09-10 17:38:41 +00:00
2025-09-04 16:54:32 +00:00
finally :
# Cerrar la conexión
if cursorMySQL is not None :
cursorMySQL . close ( )
if cursor_FactuGES is not None :
cursor_FactuGES . close ( )