This commit is contained in:
David Arranz 2025-11-24 13:13:54 +01:00
parent bb91c34ba7
commit a951be5b87
5 changed files with 103 additions and 24 deletions

59
.env Normal file
View File

@ -0,0 +1,59 @@
ENVIRONMENT = development
LOCAL_TZ = Europe/Madrid
#LOG_PATH = ./app.log
#DESARROLLO ACANA
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
# PRODUCCION RODAX FACTUGES FIREBIRD
#FACTUGES_HOST = 192.168.0.101
#FACTUGES_PORT = 3050
#FACTUGES_DATABASE = C:\FactuGES\FACTUGES.FDB
#FACTUGES_USER = sysdba
#FACTUGES_PASSWORD = masterkey
# PRODUCCION RODAX MYSQL
#UECKO_MYSQL_HOST = 192.168.0.250
#UECKO_MYSQL_PORT = 3306
#UECKO_MYSQL_DATABASE = rodax_db
#UECKO_MYSQL_USER = rodax_usr
#UECKO_MYSQL_PASSWORD = supersecret
#DESARROLLO
UECKO_MYSQL_HOST = localhost
UECKO_MYSQL_PORT = 3306
UECKO_MYSQL_DATABASE = uecko_erp_sync
UECKO_MYSQL_USER = rodax
UECKO_MYSQL_PASSWORD = rodax
#CONFIGURACION ACANA
CTE_COMPANY_ID = '019a9667-6a65-767a-a737-48234ee50a3a'
CTE_SERIE = 'F25/'
CTE_STATUS_INVOICE = 'issued'
CTE_IS_PROFORMA = 0
CTE_STATUS_VERIFACTU = 'pendiente'
CTE_LANGUAGE_CODE = 'es' #En uecko vendrá de su ficha
CTE_COUNTRY_CODE = 'es' #En uecko vendrá de su ficha
CTE_IS_COMPANY = 1
#CONFIGURACION RODAX
#CTE_COMPANY_ID = '5e4dc5b3-96b9-4968-9490-14bd032fec5f'
#CTE_SERIE = 'F25/'
#CTE_STATUS_INVOICE = 'approved'
#CTE_IS_PROFORMA = 1
#CTE_STATUS_VERIFACTU = 'Pendiente'
VERIFACTU_BASE_URL = https://api.verifacti.com/
VERIFACTU_API_KEY = vf_test_ei8WYAvEq5dhSdEyQVjgCS8NZaNpEK2BljSHSUXf+Y0=
VERIFACTU_NIFS_API_KEY = vfn_osYpNdqSzAdTAHpazXG2anz4F3o0gfbSb5FFrCBZcno=
#BREVO_API_KEY = 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
#BREVO_EMAIL_TEMPLATE = 1
#MAIL_FROM = 'no-reply@presupuestos.uecko.com'
#MAIL_TO = 'soporte@rodax-software.com'

1
.gitignore vendored
View File

@ -1,6 +1,5 @@
venv/ venv/
__pycache__ __pycache__
.env
input/ input/
output/ output/
FACTUGES.FDB FACTUGES.FDB

View File

@ -98,14 +98,20 @@ def normalize_details_invoice_fields(fd: Dict[str, Any]) -> Dict[str, Any]:
- unit_value: escala 4 (cents4) - unit_value: escala 4 (cents4)
- discount_percentage_value: escala 2 (10 -> 1000) - discount_percentage_value: escala 2 (10 -> 1000)
- total_value: escala 4 (cents4) - total_value: escala 4 (cents4)
- tax_amount: escala 2 (cents), calculado con redondeo a 2 decimales - iva_amount: escala 2 (cents), calculado con redondeo a 2 decimales
-
""" """
config = load_config() config = load_config()
tax_code = map_tax_code(str(fd.get("DES_TIPO_IVA"))) iva_code = map_tax_code(str(fd.get("DES_TIPO_IVA")))
# Calcular cuota de IVA de la línea # Calcular cuota de IVA de la línea
frac: Optional[Decimal] = tax_fraction_from_code( iva_frac: Optional[Decimal] = tax_fraction_from_code(iva_code) # p.ej. Decimal('0.21') o Decimal('0')
tax_code) # p.ej. Decimal('0.21') o Decimal('0') iva_percentage_value = None if (
iva_frac is None or iva_frac == 0) else cents4(iva_frac)
rec_code = None
rec_percentage_value = None
rec_amount = None
# --- Campos base del origen --- # --- Campos base del origen ---
cantidad = fd.get("CANTIDAD") cantidad = fd.get("CANTIDAD")
@ -132,18 +138,17 @@ def normalize_details_invoice_fields(fd: Dict[str, Any]) -> Dict[str, Any]:
# --- cuota (escala 2) --- # --- cuota (escala 2) ---
# calculamos sobre el total en unidades monetarias con redondeo bancario a 2 decimales # calculamos sobre el total en unidades monetarias con redondeo bancario a 2 decimales
if frac is None: if iva_frac is None:
tax_amount = 0 iva_amount = 0
else: else:
base = Decimal(str(total_det or 0)) base = Decimal(str(total_det or 0))
tax_amount = cents(money_round(base * frac, 2)) iva_amount = cents(money_round(base * iva_frac, 2))
# Se calcula en el objeto de negocio de nuevo, comprobar si coincide # Se calcula en el objeto de negocio de nuevo, comprobar si coincide
# item_discount_amount = ( # item_discount_amount = (
# (factura_detalle['IMPORTE_UNIDAD'] or 0)*((factura_detalle['DESCUENTO'] or 0)/100))*100 # (factura_detalle['IMPORTE_UNIDAD'] or 0)*((factura_detalle['DESCUENTO'] or 0)/100))*100
return { return {
'tax_code': tax_code,
'position': int(fd.get("POSICION") or 0), 'position': int(fd.get("POSICION") or 0),
'description': rtf_a_texto_plano(str(concepto_rtf or "")), 'description': rtf_a_texto_plano(str(concepto_rtf or "")),
'quantity_value': quantity_value, 'quantity_value': quantity_value,
@ -151,5 +156,11 @@ def normalize_details_invoice_fields(fd: Dict[str, Any]) -> Dict[str, Any]:
'disc_pct': disc_pct, 'disc_pct': disc_pct,
'discount_percentage_value': discount_percentage_value, 'discount_percentage_value': discount_percentage_value,
'total_value': total_value, 'total_value': total_value,
'tax_amount': tax_amount 'iva_code': iva_code,
'iva_percentage_value': iva_percentage_value,
'iva_amount': iva_amount,
'rec_code': rec_code,
'rec_percentage_value': rec_percentage_value,
'rec_amount': rec_amount,
} }

View File

@ -71,8 +71,15 @@ INSERT_INVOICE_ITEM = (
"INSERT INTO customer_invoice_items " "INSERT INTO customer_invoice_items "
"(item_id, invoice_id, position, description, quantity_value, unit_amount_value, " "(item_id, invoice_id, position, description, quantity_value, unit_amount_value, "
"discount_percentage_value, discount_amount_value, total_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)" "iva_code, iva_percentage_value, iva_amount_value, "
"rec_code, rec_percentage_value, rec_amount_value, "
"quantity_scale, unit_amount_scale, discount_amount_scale, total_amount_scale, discount_percentage_scale,"
"iva_percentage_scale, iva_amount_scale, rec_percentage_scale, rec_amount_scale, retention_percentage_scale, retention_amount_scale,"
"created_at, updated_at) "
"VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,2,4,2,4,2,2,4,2,4,2,4,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)"
) )
INSERT_INVOICE_TAX = ( INSERT_INVOICE_TAX = (
@ -81,11 +88,11 @@ INSERT_INVOICE_TAX = (
"VALUES (%s,%s,%s,%s,%s,2,2,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)" "VALUES (%s,%s,%s,%s,%s,2,2,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)"
) )
INSERT_INVOICE_ITEM_TAX = ( # INSERT_INVOICE_ITEM_TAX = (
"INSERT INTO customer_invoice_item_taxes " # "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) " # "(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)" # "VALUES (%s,%s,%s,%s,%s,4,2,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)"
) # )
UPDATE_CUSTOMER = ( UPDATE_CUSTOMER = (
"UPDATE customers SET name=%s, tin=%s, street=%s, city=%s, province=%s, postal_code=%s, country=%s, language_code=%s, is_company=%s, " "UPDATE customers SET name=%s, tin=%s, street=%s, city=%s, province=%s, postal_code=%s, country=%s, language_code=%s, is_company=%s, "

View File

@ -303,12 +303,15 @@ def insert_item_and_taxes(cur, invoice_id: str, fields: Dict[str, Any]) -> None:
cur.execute( cur.execute(
SQL.INSERT_INVOICE_ITEM, SQL.INSERT_INVOICE_ITEM,
(item_id, invoice_id, fields.get('position'), fields.get('description'), fields.get('quantity_value'), (item_id, invoice_id, fields.get('position'), fields.get('description'), fields.get('quantity_value'),
fields.get('unit_value'), fields.get('discount_percentage_value'), None, fields.get('total_value')) fields.get('unit_value'), fields.get('discount_percentage_value'), None, fields.get('total_value'),
fields.get('iva_code'), fields.get('iva_percentage_value'), fields.get('tax_amount'),
fields.get('rec_code'), fields.get('rec_percentage_value'), fields.get('rec_amount'),
)
) )
logging.info("Inserting item tax %s code=%s base=%s tax=%s", # logging.info("Inserting item tax %s code=%s base=%s tax=%s",
item_id, fields.get('tax_code'), fields.get('total_value'), fields.get('tax_amount')) # item_id, fields.get('tax_code'), fields.get('total_value'), fields.get('tax_amount'))
cur.execute( # cur.execute(
SQL.INSERT_INVOICE_ITEM_TAX, (str(uuid7()), item_id, fields.get('tax_code'), # SQL.INSERT_INVOICE_ITEM_TAX, (str(uuid7()), item_id, fields.get('tax_code'),
fields.get('total_value'), fields.get('tax_amount')) # fields.get('total_value'), fields.get('tax_amount'))
) # )