From 238196ff7bea1d47f3ceba2b48610b49cd441259 Mon Sep 17 00:00:00 2001 From: david Date: Thu, 11 Dec 2025 10:31:15 +0100 Subject: [PATCH] . --- .gitignore | 2 ++ app/db/normalizations.py | 17 ++++++++----- app/db/sql_sentences.py | 6 ++--- app/db/sync_invoices_factuges.py | 2 +- app/db/sync_invoices_verifactu.py | 4 +-- enviroment/.env | 26 ++++++++++---------- enviroment/.env.development | 7 +++--- enviroment/dev.env | 41 ++++++++++++++++++++++--------- scripts/build-factuges-sync.sh | 4 +-- scripts/stack.rodax.env | 32 ++++++++++++++++++++++++ setup.cfg | 2 +- 11 files changed, 100 insertions(+), 43 deletions(-) create mode 100644 scripts/stack.rodax.env diff --git a/.gitignore b/.gitignore index d5f0915..9c1ec00 100644 --- a/.gitignore +++ b/.gitignore @@ -74,4 +74,6 @@ FACTUGES.FDB # =========================== out last_execution*.txt +factuges_last.ini +verifactu_last.ini *.json diff --git a/app/db/normalizations.py b/app/db/normalizations.py index ffe4a5e..35da538 100644 --- a/app/db/normalizations.py +++ b/app/db/normalizations.py @@ -169,7 +169,8 @@ def normalize_details_invoice_fields(fd: Dict[str, Any]) -> Dict[str, Any]: # --- descuento global por linea % (escala 2) --- disc_global_raw = fd.get("DESCUENTO") disc_global_pct: Optional[Decimal] = None if disc_global_raw is None else Decimal(str(disc_global_raw)) - global_percentage_value = None if (disc_global_pct is None or disc_global_pct == 0) else cents(disc_global_pct) + global_discount_percentage_value = None if ( + disc_global_pct is None or disc_global_pct == 0) else cents(disc_global_pct) global_discount_amount_value, taxable_amount_value = apply_discount_cents4( subtotal_amount_with_dto, disc_global_pct) @@ -177,13 +178,17 @@ def normalize_details_invoice_fields(fd: Dict[str, Any]) -> Dict[str, Any]: # --- total de línea (escala 4) --- total_value = cents4(total_det) - # DEBE SER LO MISMO LO CALCULADO QUE LO QUE NOS VIENE POR BD DE FACTUGES - logger.info("total con dto linea calculado: %s - total que llega: %s", subtotal_amount_with_dto, total_value) + + if total_value > 0: + # DEBE SER LO MISMO LO CALCULADO QUE LO QUE NOS VIENE POR BD DE FACTUGES + logger.info("total con dto linea calculado: %s - total que llega: %s", subtotal_amount_with_dto, total_value) + # la base imponible sobre la que calcular impuestos es el neto menos el dto de linea y dto global base = unscale_to_decimal(taxable_amount_value, 4) - logger.info("base imponible calculada: %s - subtotal: %s - descuentodto: %s - descuentoglobal: %s", - base, subtotal_amount_value, discount_amount_value, global_discount_amount_value) + if total_value > 0: + logger.info("base imponible calculada: %s - subtotal: %s - descuentodto: %s - descuentoglobal: %s", + base, subtotal_amount_value, discount_amount_value, global_discount_amount_value) # Calcular cuota de IVA de la línea iva_code = map_iva_code(str(fd.get("DES_TIPO_IVA"))) @@ -220,7 +225,7 @@ def normalize_details_invoice_fields(fd: Dict[str, Any]) -> Dict[str, Any]: 'disc_pct': disc_pct, 'discount_percentage_value': discount_percentage_value, 'discount_amount_value': discount_amount_value, - 'global_percentage_value': global_percentage_value, + 'global_discount_percentage_value': global_discount_percentage_value, 'global_discount_amount_value': global_discount_amount_value, 'total_discount_amount_value': total_discount_amount_value, 'taxable_amount_value': taxable_amount_value, diff --git a/app/db/sql_sentences.py b/app/db/sql_sentences.py index a7c32fd..dccb413 100644 --- a/app/db/sql_sentences.py +++ b/app/db/sql_sentences.py @@ -70,14 +70,14 @@ INSERT_INVOICE_BAK = ( INSERT_INVOICE_ITEM = ( "INSERT INTO customer_invoice_items " "(item_id, invoice_id, position, description, quantity_value, unit_amount_value, subtotal_amount_value, " - "discount_percentage_value, discount_amount_value, global_percentage_value, global_discount_amount_value, total_discount_amount_value, " + "discount_percentage_value, discount_amount_value, global_discount_percentage_value, global_discount_amount_value, total_discount_amount_value, " " taxable_amount_value, total_amount_value, " "iva_code, iva_percentage_value, iva_amount_value, " "rec_code, rec_percentage_value, rec_amount_value, taxes_amount_value, " "quantity_scale, unit_amount_scale, subtotal_amount_scale, " - "discount_percentage_scale, discount_amount_scale, global_percentage_scale, global_discount_amount_scale, total_discount_amount_scale, taxable_amount_scale, total_amount_scale, " + "discount_percentage_scale, discount_amount_scale, global_discount_percentage_scale, global_discount_amount_scale, total_discount_amount_scale, taxable_amount_scale, total_amount_scale, " "iva_percentage_scale, iva_amount_scale, rec_percentage_scale, rec_amount_scale, taxes_amount_scale, retention_percentage_scale, retention_amount_scale, " "created_at, updated_at) " @@ -153,7 +153,7 @@ LIMPIAR_FACTUGES_LINK = ( # OPCION A SACAMOS EL RESUMEN DE LA TAXES DE LA CABECERA consulta_sql_customer_invoices_issue = ( "SELECT ci.id, ci.series, ci.invoice_number, ci.invoice_date, ci.description, ci.customer_tin, ci.customer_name, ci.total_amount_value, ci.total_amount_scale, ci.reference, " - "cit.taxable_amount_scale, cit.taxes_amount_scale, cit.tax_code, cit.taxable_amount_value, cit.taxes_amount_value, " + "cit.taxable_amount_scale, cit.taxes_amount_scale, cit.iva_code, cit.taxable_amount_value, cit.taxes_amount_value, " "vr.id as vrId, vr.uuid, vr.estado " "FROM customer_invoices as ci " "LEFT JOIN customer_invoice_taxes cit on (ci.id = cit.invoice_id) " diff --git a/app/db/sync_invoices_factuges.py b/app/db/sync_invoices_factuges.py index 8587554..7ec7807 100644 --- a/app/db/sync_invoices_factuges.py +++ b/app/db/sync_invoices_factuges.py @@ -432,7 +432,7 @@ def insert_item_and_taxes(cur, invoice_id: str, fields: Dict[str, Any]) -> None: fields.get("subtotal_amount_value"), fields.get("discount_percentage_value"), fields.get("discount_amount_value"), - fields.get("global_percentage_value"), + fields.get("global_discount_percentage_value"), fields.get("global_discount_amount_value"), fields.get("total_discount_amount_value"), fields.get("taxable_amount_value"), diff --git a/app/db/sync_invoices_verifactu.py b/app/db/sync_invoices_verifactu.py index 2a392b3..ff59d65 100644 --- a/app/db/sync_invoices_verifactu.py +++ b/app/db/sync_invoices_verifactu.py @@ -227,11 +227,11 @@ def preparar_linea(fila: Dict[str, Any]) -> Tuple[bool, Dict[str, Any] | list]: str(fila['taxable_amount_value']), str(fila['taxable_amount_scale'])) # Si el tipo impositivo es exento - if catalog.is_non_exempt(fila['tax_code']): + if catalog.is_non_exempt(fila['iva_code']): calificacion_operacion = "S1" # FALTA COMPROBAR SI IMPUESTO IGIC (03) o IPSI (02) impuesto = "01" - tipo_impositivo = str(catalog.get_percent_reduced(fila['tax_code'])) + tipo_impositivo = str(catalog.get_percent_reduced(fila['iva_code'])) cuota_repercutida = unscale_to_str( str(fila['taxes_amount_value']), str(fila['taxes_amount_scale'])) diff --git a/enviroment/.env b/enviroment/.env index c22722f..d155033 100644 --- a/enviroment/.env +++ b/enviroment/.env @@ -4,25 +4,25 @@ STATE_PATH = ./ #LOG_PATH = ./app.log #DESARROLLO ACANA -#FACTUGES_HOST = 192.168.0.105 +FACTUGES_HOST = 192.168.0.105 +FACTUGES_PORT = 3050 +FACTUGES_DATABASE = C:\Codigo Acana\Output\Debug\Database\FACTUGES.FDB +FACTUGES_USER = sysdba +FACTUGES_PASSWORD = masterkey +CONFIGURACION ACANA +CTE_COMPANY_ID = '019a9667-6a65-767a-a737-48234ee50a3a' +VERIFACTU_API_KEY = vf_test_ei8WYAvEq5dhSdEyQVjgCS8NZaNpEK2BljSHSUXf+Y0= + +#DESARROLLO ALONSO Y SAL +#FACTUGES_HOST = 192.168.0.144 #FACTUGES_PORT = 3050 -#FACTUGES_DATABASE = C:\Codigo Acana\Output\Debug\Database\FACTUGES.FDB +#FACTUGES_DATABASE = C:\Codigo Arribas2\Output\Debug\Database\FACTUGES.FDB #FACTUGES_USER = sysdba #FACTUGES_PASSWORD = masterkey #CONFIGURACION ACANA #CTE_COMPANY_ID = '019a9667-6a65-767a-a737-48234ee50a3a' -#VERIFACTU_API_KEY = vf_test_ei8WYAvEq5dhSdEyQVjgCS8NZaNpEK2BljSHSUXf+Y0= - -#DESARROLLO ALONSO Y SAL -FACTUGES_HOST = 192.168.0.144 -FACTUGES_PORT = 3050 -FACTUGES_DATABASE = C:\Codigo Arribas2\Output\Debug\Database\FACTUGES.FDB -FACTUGES_USER = sysdba -FACTUGES_PASSWORD = masterkey -#CONFIGURACION ACANA -CTE_COMPANY_ID = '019a9667-6a65-767a-a737-48234ee50a3a' #CTE_COMPANY_ID_PRODUCCION = '019ac4f2-9502-731a-a6db-525475e85bc7' -VERIFACTU_API_KEY = vf_test_C03HL2F0X5OXSDRunjNFoMxD4IrRfK3kCC8PfcvCENI= +#VERIFACTU_API_KEY = vf_test_C03HL2F0X5OXSDRunjNFoMxD4IrRfK3kCC8PfcvCENI= #DESARROLLO FWEB_MYSQL_HOST = localhost diff --git a/enviroment/.env.development b/enviroment/.env.development index 72e99d7..eab51a5 100644 --- a/enviroment/.env.development +++ b/enviroment/.env.development @@ -20,9 +20,9 @@ FACTUGES_PRECIO_PUNTO = 3.31 PRO_FWEB_MYSQL_HOST = 192.168.0.250 PRO_FWEB_MYSQL_PORT = 3306 -PRO_FWEB_MYSQL_DATABASE = factuges_db -PRO_FWEB_MYSQL_USER = root -PRO_FWEB_MYSQL_PASSWORD = rootpass +PRO_FWEB_MYSQL_DATABASE = rodax_db +PRO_FWEB_MYSQL_USER = rodax_usr +PRO_FWEB_MYSQL_PASSWORD = supersecret DEV_FWEB_MYSQL_HOST = 192.168.0.104 DEV_FWEB_MYSQL_PORT = 3306 @@ -30,7 +30,6 @@ DEV_FWEB_MYSQL_DATABASE = uecko_erp_sync DEV_FWEB_MYSQL_USER = rodax DEV_FWEB_MYSQL_PASSWORD = rodax - BREVO_API_KEY = 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 BREVO_EMAIL_TEMPLATE = 1 MAIL_FROM = 'no-reply@presupuestos.uecko.com' diff --git a/enviroment/dev.env b/enviroment/dev.env index 940cd58..5647c48 100644 --- a/enviroment/dev.env +++ b/enviroment/dev.env @@ -4,26 +4,38 @@ STATE_PATH = ./ #LOG_PATH = ./app.log -#DESARROLLO ACANA -#FACTUGES_HOST = 192.168.0.105 +#PRODUCCION RODAX +#FACTUGES_HOST = 192.168.0.101 #FACTUGES_PORT = 3050 -#FACTUGES_DATABASE = C:\Codigo Acana\Output\Debug\Database\FACTUGES.FDB +#FACTUGES_DATABASE = C:\FactuGES\FACTUGES.FDB #FACTUGES_USER = sysdba #FACTUGES_PASSWORD = masterkey -#CONFIGURACION ACANA -#CTE_COMPANY_ID = '019a9667-6a65-767a-a737-48234ee50a3a' -#VERIFACTU_API_KEY = vf_test_ei8WYAvEq5dhSdEyQVjgCS8NZaNpEK2BljSHSUXf+Y0= +#CTE_COMPANY_ID = '5e4dc5b3-96b9-4968-9490-14bd032fec5f' +#VERIFACTU_API_KEY = vf_prod_yfjonNPv2E4Fij+5J0hct0zCgUeFYT2dZzb23UZlM+Q= +#CTE_SERIE = 'F25' -#DESARROLLO ALONSO Y SAL -FACTUGES_HOST = 192.168.0.146 +#DESARROLLO ACANA +FACTUGES_HOST = 192.168.0.105 FACTUGES_PORT = 3050 -FACTUGES_DATABASE = C:\Codigo Arribas2\Output\Debug\Database\FACTUGES.FDB +FACTUGES_DATABASE = C:\Codigo Acana\Output\Debug\Database\FACTUGES.FDB FACTUGES_USER = sysdba FACTUGES_PASSWORD = masterkey #CONFIGURACION ACANA CTE_COMPANY_ID = '019a9667-6a65-767a-a737-48234ee50a3a' +VERIFACTU_API_KEY = vf_test_ei8WYAvEq5dhSdEyQVjgCS8NZaNpEK2BljSHSUXf+Y0= +CTE_SERIE = 'F25/' + +#DESARROLLO ALONSO Y SAL +#FACTUGES_HOST = 192.168.0.146 +#FACTUGES_PORT = 3050 +#FACTUGES_DATABASE = C:\Codigo Arribas2\Output\Debug\Database\FACTUGES.FDB +#FACTUGES_USER = sysdba +#FACTUGES_PASSWORD = masterkey +#CONFIGURACION ACANA +#CTE_COMPANY_ID = '019a9667-6a65-767a-a737-48234ee50a3a' #CTE_COMPANY_ID_PRODUCCION = '019ac4f2-9502-731a-a6db-525475e85bc7' -VERIFACTU_API_KEY = vf_test_C03HL2F0X5OXSDRunjNFoMxD4IrRfK3kCC8PfcvCENI= +#VERIFACTU_API_KEY = vf_test_C03HL2F0X5OXSDRunjNFoMxD4IrRfK3kCC8PfcvCENI= +#CTE_SERIE = 'F25/' #DESARROLLO FWEB_MYSQL_HOST = localhost @@ -32,7 +44,14 @@ FWEB_MYSQL_DATABASE = uecko_erp_sync FWEB_MYSQL_USER = rodax FWEB_MYSQL_PASSWORD = rodax -CTE_SERIE = 'F25/' +#PRODUCCION RODAX +#FWEB_MYSQL_HOST = 192.168.0.250 +#FWEB_MYSQL_PORT = 3306 +#FWEB_MYSQL_DATABASE = rodax_db +#FWEB_MYSQL_USER = rodax_usr +#FWEB_MYSQL_PASSWORD = supersecret + + CTE_STATUS_INVOICE = 'issued' CTE_IS_PROFORMA = 0 CTE_STATUS_VERIFACTU = 'Pendiente' diff --git a/scripts/build-factuges-sync.sh b/scripts/build-factuges-sync.sh index 313a4da..3a8e367 100755 --- a/scripts/build-factuges-sync.sh +++ b/scripts/build-factuges-sync.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -euo pipefail -SCRIPT_VERSION="2.0.1" +SCRIPT_VERSION="2.0.2" # ================================================ # FACTUGES SYNC - Docker Build Script (Simplificado) @@ -99,7 +99,7 @@ echo "" if [[ "$LOAD" == true ]]; then echo "📥 Subiendo imágenes al servidor..." - scp -P 49152 "${OUT_DIR}"/*.tar \ + scp -P 49152 "${OUT_DIR}"/*.* \ rodax@vps-2.rodax-software.com:/opt/factuges/${COMPANY}/sync/ echo "📥 Cargando imágenes en Docker remoto..." diff --git a/scripts/stack.rodax.env b/scripts/stack.rodax.env new file mode 100644 index 0000000..eec022e --- /dev/null +++ b/scripts/stack.rodax.env @@ -0,0 +1,32 @@ +# SYNC +ENV = development +LOCAL_TZ = Europe/Madrid +STATE_PATH = /app/state +SYNC_MODE = all + +FACTUGES_HOST = factuges-pc +FACTUGES_PORT = 3050 +FACTUGES_DATABASE = C:\FactuGES\FACTUGES.FDB +FACTUGES_USER = sysdba +FACTUGES_PASSWORD = masterkey + +FWEB_MYSQL_HOST = db # ${DB_NAME} +FWEB_MYSQL_PORT = 3306 # ${DB_PORT} +FWEB_MYSQL_DATABASE = factuges_acana # ${DB_NAME} +FWEB_MYSQL_USER = acana # ${DB_USER} +FWEB_MYSQL_PASSWORD = r@U8%GJ+2e/AWR # ${DB_PASS} + +CTE_COMPANY_ID = '5e4dc5b3-96b9-4968-9490-14bd032fec5f' +CTE_SERIE = 'F25' +CTE_STATUS_INVOICE = 'issued' +CTE_IS_PROFORMA = 0 +CTE_STATUS_VERIFACTU = 'Pendiente' +CTE_LANGUAGE_CODE = 'es' +CTE_COUNTRY_CODE = 'es' +CTE_IS_COMPANY = 1 +CTE_SYNC_RESULT_OK = 1 +CTE_SYNC_RESULT_FAIL = 2 + +VERIFACTU_API_KEY = vf_test_C03HL2F0X5OXSDRunjNFoMxD4IrRfK3kCC8PfcvCENI= +VERIFACTU_BASE_URL = https://api.verifacti.com/ +VERIFACTU_NIFS_API_KEY = vfn_osYpNdqSzAdTAHpazXG2anz4F3o0gfbSb5FFrCBZcno= diff --git a/setup.cfg b/setup.cfg index 61e8090..4527925 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = factuges-sync -version = 0.1.4 +version = 0.1.5 description = ETL job to sync data from legacy DB to MariaDB author = Rodax Software author_email = info@rodax-software.com