From a951be5b87bd1e5ece566eaf00ed4983a95333ba Mon Sep 17 00:00:00 2001 From: david Date: Mon, 24 Nov 2025 13:13:54 +0100 Subject: [PATCH] . --- .env | 59 ++++++++++++++++++++++++++++++++++++++++ .gitignore | 1 - app/db/normalizations.py | 29 ++++++++++++++------ app/db/sql_sentences.py | 21 +++++++++----- app/db/sync_invoices.py | 17 +++++++----- 5 files changed, 103 insertions(+), 24 deletions(-) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 0000000..f192633 --- /dev/null +++ b/.env @@ -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' diff --git a/.gitignore b/.gitignore index 7188996..c4696aa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ venv/ __pycache__ -.env input/ output/ FACTUGES.FDB diff --git a/app/db/normalizations.py b/app/db/normalizations.py index bcc6a75..4b99041 100644 --- a/app/db/normalizations.py +++ b/app/db/normalizations.py @@ -98,14 +98,20 @@ def normalize_details_invoice_fields(fd: Dict[str, Any]) -> Dict[str, Any]: - unit_value: escala 4 (cents4) - discount_percentage_value: escala 2 (10 -> 1000) - 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() - 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 - frac: Optional[Decimal] = tax_fraction_from_code( - tax_code) # p.ej. Decimal('0.21') o Decimal('0') + iva_frac: Optional[Decimal] = tax_fraction_from_code(iva_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 --- cantidad = fd.get("CANTIDAD") @@ -132,18 +138,17 @@ def normalize_details_invoice_fields(fd: Dict[str, Any]) -> Dict[str, Any]: # --- cuota (escala 2) --- # calculamos sobre el total en unidades monetarias con redondeo bancario a 2 decimales - if frac is None: - tax_amount = 0 + if iva_frac is None: + iva_amount = 0 else: 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 # item_discount_amount = ( # (factura_detalle['IMPORTE_UNIDAD'] or 0)*((factura_detalle['DESCUENTO'] or 0)/100))*100 return { - 'tax_code': tax_code, 'position': int(fd.get("POSICION") or 0), 'description': rtf_a_texto_plano(str(concepto_rtf or "")), 'quantity_value': quantity_value, @@ -151,5 +156,11 @@ def normalize_details_invoice_fields(fd: Dict[str, Any]) -> Dict[str, Any]: 'disc_pct': disc_pct, 'discount_percentage_value': discount_percentage_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, + } diff --git a/app/db/sql_sentences.py b/app/db/sql_sentences.py index 3cbe055..295f9c9 100644 --- a/app/db/sql_sentences.py +++ b/app/db/sql_sentences.py @@ -71,8 +71,15 @@ INSERT_INVOICE_ITEM = ( "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)" + + "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 = ( @@ -81,11 +88,11 @@ INSERT_INVOICE_TAX = ( "VALUES (%s,%s,%s,%s,%s,2,2,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)" ) -INSERT_INVOICE_ITEM_TAX = ( - "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)" -) +# INSERT_INVOICE_ITEM_TAX = ( +# "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)" +# ) 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, " diff --git a/app/db/sync_invoices.py b/app/db/sync_invoices.py index 3be79b0..320b279 100644 --- a/app/db/sync_invoices.py +++ b/app/db/sync_invoices.py @@ -303,12 +303,15 @@ def insert_item_and_taxes(cur, invoice_id: str, fields: Dict[str, Any]) -> None: cur.execute( SQL.INSERT_INVOICE_ITEM, (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", - item_id, fields.get('tax_code'), fields.get('total_value'), fields.get('tax_amount')) - cur.execute( - SQL.INSERT_INVOICE_ITEM_TAX, (str(uuid7()), item_id, fields.get('tax_code'), - fields.get('total_value'), fields.get('tax_amount')) - ) + # 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')) + # cur.execute( + # SQL.INSERT_INVOICE_ITEM_TAX, (str(uuid7()), item_id, fields.get('tax_code'), + # fields.get('total_value'), fields.get('tax_amount')) + # )