2025-09-04 16:54:32 +00:00
import logging
2025-10-29 16:08:14 +00:00
import textwrap
2025-11-05 17:43:40 +00:00
from . import sql_sentences as SQL
from uuid6 import uuid7
2025-09-04 16:54:32 +00:00
from config import load_config
2025-10-03 18:22:15 +00:00
from decimal import Decimal , ROUND_HALF_UP
2025-11-05 17:43:40 +00:00
from utils import limpiar_cadena , normalizar_telefono_con_plus , corregir_y_validar_email , normalizar_url_para_insert
2025-09-04 16:54:32 +00:00
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-11-05 17:43:40 +00:00
# LIMPIAMOS LAS FACTURAS DE FACTUGES QUE HAYAN SIDO ELIMINADAS DEL PROGRAMA NUEVO DE FACTURACION, PARA QUE PUEDAN SER MODIFICADAS
2025-09-10 17:38:41 +00:00
# Crear un cursor para ejecutar consultas SQL
cursor_mysql = None
try :
cursor_mysql = conn_mysql . cursor ( )
2025-11-05 17:43:40 +00:00
# Ejecutar la consulta de FACTURAS_CLIENTE
2025-09-10 17:38:41 +00:00
cursor_mysql . execute ( consulta_sql_customer_invoices_deleted )
filas = cursor_mysql . fetchall ( )
cursor_mysql . close ( )
2025-11-05 17:43:40 +00:00
# Crear un conjunto con los IDs [0] de los customer_inovices que debo liberar en FactuGES, porque han sido eliminadas en programa de facturación nuevo
2025-09-10 17:38:41 +00:00
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-11-05 17:43:40 +00:00
# BUSCAMOS FACTURAS ENVIADAS A VERIFACTU EN FACTUGES, PARA SUBIRLAS AL NUEVO PROGRAMA DE FACTURACIÓN
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. " )
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-11-05 17:43:40 +00:00
# Eliminamos todos los IDs de verifacti que han sido eliminados así liberaremos la factura borrador y podermos modificarla de nuevo, para volverla a subir una vez hechos los cambios.
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 } " )
2025-11-05 17:43:40 +00:00
cursor_FactuGES . executemany ( SQL . LIMPIAR_FACTUGES_LINK , [ (
2025-09-10 17:38:41 +00:00
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-11-05 17:43:40 +00:00
# Insertaremos cada factura existente en las filas a la nueva estructura de tablas del programa nuevo de facturacion.
2025-09-04 16:54:32 +00:00
2025-11-05 17:43:40 +00:00
# Compañia RODAX
cte_company_id = ' 5e4dc5b3-96b9-4968-9490-14bd032fec5f '
2025-09-22 17:32:39 +00:00
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 ( )
2025-11-05 17:43:40 +00:00
contador_serie = 0
2025-09-04 16:54:32 +00:00
# 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 ' )
2025-11-05 17:43:40 +00:00
invoice_series = str ( ' F25/ ' )
2025-10-29 16:08:14 +00:00
reference = str ( factura_detalle [ ' REFERENCIA ' ] )
2025-09-10 17:38:41 +00:00
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-11-05 17:43:40 +00:00
if ( tax_code == ' IVA21 ' ) or ( tax_code == ' IVA 21 ' ) :
2025-09-18 10:41:06 +00:00
tax_code = ' iva_21 '
2025-11-05 17:43:40 +00:00
elif tax_code == ' IVA18 ' or ( tax_code == ' IVA 18 ' ) :
2025-09-18 10:41:06 +00:00
tax_code = ' iva_18 '
2025-11-05 17:43:40 +00:00
elif tax_code == ' IVA16 ' or ( tax_code == ' IVA 16 ' ) :
2025-09-18 10:41:06 +00:00
tax_code = ' iva_16 '
2025-11-05 17:43:40 +00:00
elif tax_code == ' IVA10 ' or ( tax_code == ' IVA 10 ' ) :
2025-09-18 10:41:06 +00:00
tax_code = ' iva_10 '
2025-11-05 17:43:40 +00:00
elif tax_code == ' IVA4 ' or ( tax_code == ' IVA 4 ' ) :
tax_code = ' iva_4 '
2025-10-29 16:08:14 +00:00
elif tax_code == ' EXENTO ' :
tax_code = ' iva_exenta '
2025-09-18 10:41:06 +00:00
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
2025-11-05 17:43:40 +00:00
payment_method_id = str ( uuid7 ( ) )
2025-09-22 17:32:39 +00:00
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-11-05 17:43:40 +00:00
customer_id = str ( uuid7 ( ) )
2025-09-10 17:38:41 +00:00
factuges_customer_id = str ( factura_detalle [ ' ID_CLIENTE ' ] )
2025-10-29 16:08:14 +00:00
customer_tin = limpiar_cadena ( str ( factura_detalle [ ' NIF_CIF ' ] ) )
2025-09-10 17:38:41 +00:00
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-10-29 16:08:14 +00:00
description = textwrap . shorten (
f " { reference or ' ' } - { customer_name or ' ' } " , width = 50 , placeholder = " … " )
2025-09-04 16:54:32 +00:00
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-10-03 18:22:15 +00:00
item_total_amount = ( factura_detalle [ ' IMPORTE_TOTAL_DET ' ] or 0 ) * 100
# 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-11-05 17:43:40 +00:00
cursorMySQL . execute ( SQL . SELECT_CUSTOMER_BY_FACTUGES ,
2025-09-10 17:38:41 +00:00
( factuges_customer_id , ) )
row = cursorMySQL . fetchone ( )
is_new = ( row is None ) or ( row [ 0 ] is None )
2025-11-05 17:43:40 +00:00
#Validamos los campos que pueden dar conflicto
customer_phone_primary_tratado = normalizar_telefono_con_plus ( customer_phone_primary )
customer_phone_secondary_tratado = normalizar_telefono_con_plus ( customer_phone_secondary )
customer_mobile_primary_tratado = normalizar_telefono_con_plus ( customer_mobile_primary )
customer_mobile_secondary_tratado = normalizar_telefono_con_plus ( customer_mobile_secondary )
customer_webside_tratado = normalizar_url_para_insert ( customer_webside )
customer_email_primary_ok , customer_email_primary_tratado = corregir_y_validar_email ( customer_email_primary )
customer_email_secondary_ok , customer_email_secondary_tratado = corregir_y_validar_email ( customer_email_secondary )
logging . info ( f " La ficha de cliente { customer_tin } se modifican los siguientes campos: " )
if ( customer_phone_primary_tratado != customer_phone_primary ) :
logging . info ( f " phone_primary ( { customer_phone_primary } ) se cambia por ( { customer_phone_primary_tratado } ) " )
if ( customer_phone_secondary_tratado != customer_phone_secondary ) :
logging . info ( f " phone_secondary ( { customer_phone_secondary } ) se cambia por ( { customer_phone_secondary_tratado } ) " )
if ( customer_mobile_primary_tratado != customer_mobile_primary ) :
logging . info ( f " mobile_primary ( { customer_mobile_primary } ) se cambia por ( { customer_mobile_primary_tratado } ) " )
if ( customer_mobile_secondary_tratado != customer_mobile_secondary ) :
logging . info ( f " mobile_secondary ( { customer_mobile_secondary } ) se cambia por ( { customer_mobile_secondary_tratado } ) " )
if ( customer_webside_tratado != customer_webside ) :
logging . info ( f " customer_webside ( { customer_webside } ) se cambia por ( { customer_webside_tratado } ) " )
if customer_email_primary_ok :
if ( customer_email_primary_tratado != customer_email_primary ) :
logging . info ( f " email_primary ( { customer_email_primary } ) se cambia por ( { customer_email_primary_tratado } ) " )
else :
logging . info ( f " Omitimos email_primary invalido( { customer_email_primary } ) " )
if customer_email_secondary_ok :
if ( customer_email_secondary_tratado != customer_email_secondary ) :
logging . info ( f " email_secondary ( { customer_email_secondary } ) se cambia por ( { customer_email_secondary_tratado } ) " )
else :
logging . info ( f " Omitimos email_secondary invalido( { customer_email_secondary } ) " )
2025-09-10 17:38:41 +00:00
if is_new :
logging . info (
f " Inserting customer { factuges_customer_id } { customer_tin } { customer_name } " )
2025-11-05 17:43:40 +00:00
cursorMySQL . execute ( SQL . INSERT_CUSTOMER , ( customer_id , customer_name , customer_tin , customer_street , customer_city , customer_province ,
customer_postal_code , customer_country , customer_phone_primary_tratado , customer_phone_secondary_tratado , customer_mobile_primary_tratado ,
customer_mobile_secondary_tratado , customer_email_primary_tratado , customer_email_secondary_tratado , customer_webside_tratado , 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 } " )
2025-11-05 17:43:40 +00:00
cursorMySQL . execute ( SQL . UPDATE_CUSTOMER , ( customer_name , customer_tin , customer_street , customer_city , customer_province , customer_postal_code , customer_country ,
customer_phone_primary_tratado , customer_phone_secondary_tratado , customer_mobile_primary_tratado , customer_mobile_secondary_tratado ,
customer_email_primary_tratado , customer_email_secondary_tratado , customer_webside_tratado , customer_id ) )
2025-09-10 17:38:41 +00:00
2025-11-05 17:43:40 +00:00
2025-09-22 17:32:39 +00:00
# Comprobamos si existe la forma de pago del primer item de la factura
2025-11-05 17:43:40 +00:00
cursorMySQL . execute ( SQL . SELECT_PAYMENT_METHOD_BY_FACTUGES ,
2025-09-22 17:32:39 +00:00
( 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 } " )
2025-11-05 17:43:40 +00:00
cursorMySQL . execute ( SQL . INSERT_PAYMENT_METHOD , (
2025-09-22 17:32:39 +00:00
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
2025-11-05 17:43:40 +00:00
id_customer_invoice = str ( uuid7 ( ) )
contador_serie = contador_serie + 1
2025-09-04 16:54:32 +00:00
logging . info (
2025-10-29 16:08:14 +00:00
f " Inserting customer_invoice { id_customer_invoice } { reference } { invoice_date } " )
2025-11-05 17:43:40 +00:00
cursorMySQL . execute ( SQL . INSERT_INVOICE , ( id_customer_invoice , cte_company_id , contador_serie , invoice_status , invoice_series , reference , invoice_date , operation_date , description ,
2025-09-10 17:38:41 +00:00
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-11-05 17:43:40 +00:00
2025-09-10 17:38:41 +00:00
2025-09-18 10:41:06 +00:00
# Insertamos el IVA y RE si viene
2025-10-29 16:08:14 +00:00
if ( factura_detalle [ ' IVA ' ] > = 0 ) :
2025-09-18 10:41:06 +00:00
taxable_amount_value = (
factura_detalle [ ' BASE_IMPONIBLE ' ] ) * 100
tax_amount_value = ( factura_detalle [ ' IMPORTE_IVA ' ] ) * 100
2025-11-05 17:43:40 +00:00
cursorMySQL . execute ( SQL . INSERT_INVOICE_TAX , ( str ( uuid7 ( ) ) ,
2025-09-18 10:41:06 +00:00
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
2025-11-05 17:43:40 +00:00
cursorMySQL . execute ( SQL . INSERT_INVOICE_TAX , ( str ( uuid7 ( ) ) ,
2025-09-10 17:38:41 +00:00
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 (
2025-11-05 17:43:40 +00:00
SQL . UPDATE_FACTUGES_LINK , ( id_customer_invoice , factuges_id ) )
2025-09-10 17:38:41 +00:00
num_fac_procesed + = 1
# Insertamos detalles y taxes correspondientes siempre
# Generar un ID único para la tabla customer_invoice_items
2025-11-05 17:43:40 +00:00
item_id = str ( uuid7 ( ) )
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 } " )
2025-11-05 17:43:40 +00:00
cursorMySQL . execute ( SQL . INSERT_INVOICE_ITEM , ( item_id , id_customer_invoice , item_position , item_description ,
2025-09-10 17:38:41 +00:00
item_quantity_value , item_unit_amount_value , item_discount_percentage_value , item_discount_amount , item_total_amount ) )
2025-10-03 18:22:15 +00:00
if tax_code == ' iva_21 ' :
2025-09-10 17:38:41 +00:00
tax_amount_value = (
2025-10-03 18:22:15 +00:00
( Decimal ( str ( factura_detalle [ ' IMPORTE_TOTAL_DET ' ] or 0 ) ) * Decimal ( ' 0.21 ' ) ) . quantize ( Decimal ( ' 0.01 ' ) , rounding = ROUND_HALF_UP ) ) * 100
elif tax_code == ' iva_18 ' :
2025-09-10 17:38:41 +00:00
tax_amount_value = (
2025-10-03 18:22:15 +00:00
( Decimal ( str ( factura_detalle [ ' IMPORTE_TOTAL_DET ' ] or 0 ) ) * Decimal ( ' 0.18 ' ) ) . quantize ( Decimal ( ' 0.01 ' ) , rounding = ROUND_HALF_UP ) ) * 100
elif tax_code == ' iva_16 ' :
2025-09-10 17:38:41 +00:00
tax_amount_value = (
2025-10-03 18:22:15 +00:00
( Decimal ( str ( factura_detalle [ ' IMPORTE_TOTAL_DET ' ] or 0 ) ) * Decimal ( ' 0.16 ' ) ) . quantize ( Decimal ( ' 0.01 ' ) , rounding = ROUND_HALF_UP ) ) * 100
elif tax_code == ' iva_10 ' :
2025-09-10 17:38:41 +00:00
tax_amount_value = (
2025-10-03 18:22:15 +00:00
( Decimal ( str ( factura_detalle [ ' IMPORTE_TOTAL_DET ' ] or 0 ) ) * Decimal ( ' 0.10 ' ) ) . quantize ( Decimal ( ' 0.01 ' ) , rounding = ROUND_HALF_UP ) ) * 100
2025-10-29 16:08:14 +00:00
elif tax_code == ' iva_exenta ' :
tax_amount_value = (
( Decimal ( str ( factura_detalle [ ' IMPORTE_TOTAL_DET ' ] or 0 ) ) * Decimal ( ' 0 ' ) ) . quantize ( Decimal ( ' 0.01 ' ) , rounding = ROUND_HALF_UP ) ) * 100
2025-09-10 17:38:41 +00:00
else :
2025-10-03 18:22:15 +00:00
tax_amount_value = (
factura_detalle [ ' IMPORTE_TOTAL_DET ' ] or 0 ) * 100
2025-09-04 16:54:32 +00:00
logging . info (
2025-10-03 18:22:15 +00:00
f " Inserting customer_invoice_item_taxes { item_id } { item_position } { tax_code } { item_total_amount } { tax_amount_value } " )
2025-11-05 17:43:40 +00:00
cursorMySQL . execute ( SQL . INSERT_INVOICE_ITEM_TAX , ( str ( uuid7 ( ) ) , item_id , tax_code ,
2025-09-10 17:38:41 +00:00
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 ( )