This commit is contained in:
David Arranz 2025-12-11 10:31:15 +01:00
parent 6b63474cbc
commit 238196ff7b
11 changed files with 100 additions and 43 deletions

2
.gitignore vendored
View File

@ -74,4 +74,6 @@ FACTUGES.FDB
# ===========================
out
last_execution*.txt
factuges_last.ini
verifactu_last.ini
*.json

View File

@ -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,

View File

@ -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) "

View File

@ -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"),

View File

@ -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']))

View File

@ -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

View File

@ -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'

View File

@ -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'

View File

@ -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..."

32
scripts/stack.rodax.env Normal file
View File

@ -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=

View File

@ -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