Subida a producción
This commit is contained in:
parent
973391ec68
commit
51bd9fe7af
@ -56,7 +56,7 @@ Esto crea el comando factuges-sync disponible en tu entorno virtual.
|
||||
El código carga automáticamente:
|
||||
|
||||
* environment/dev.env cuando ENV=dev
|
||||
* Variables del contenedor en producción (ENV=prod)
|
||||
* Variables del contenedor en producción (ENV=production)
|
||||
|
||||
Por tanto, **en desarrollo**:
|
||||
|
||||
@ -122,5 +122,5 @@ Build:
|
||||
Cron job:
|
||||
|
||||
```bash
|
||||
*/5 * * * * docker run --rm -e ENV=prod -e SYNC_MODE=factuges myimage:latest
|
||||
*/5 * * * * docker run --rm -e ENV=production -e SYNC_MODE=factuges myimage:latest
|
||||
```
|
||||
|
||||
@ -1 +1 @@
|
||||
2025-11-30 09:07:15
|
||||
2025-11-30 18:28:15
|
||||
@ -1 +0,0 @@
|
||||
__version__ = "1.0.0"
|
||||
@ -1 +0,0 @@
|
||||
__version__ = "1.0.0"
|
||||
@ -28,7 +28,7 @@ def main():
|
||||
print("Error: debes indicar modo: 'factuges' o 'verifactu'")
|
||||
sys.exit(1)
|
||||
|
||||
if os.getenv("ENV") == "dev":
|
||||
if os.getenv("ENV") == "developement":
|
||||
print("Running in development mode (no docker)")
|
||||
|
||||
module = (
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
from .settings import load_config
|
||||
from .setup_logging import setup_logging
|
||||
from .setup_brevo import setup_brevo
|
||||
from .settings import load_config, log_config
|
||||
from .version import get_package_version
|
||||
from .setup_logger import create_logger, logger
|
||||
from .setup_brevo import setup_brevo
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import logging
|
||||
import os
|
||||
from os.path import join, dirname
|
||||
from typing import Any, Dict, Optional
|
||||
from .setup_logger import logger
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
@ -23,16 +23,16 @@ def load_config() -> Dict[str, Any]:
|
||||
Carga la configuración desde variables de entorno.
|
||||
|
||||
- En dev: carga dev.env y luego valida.
|
||||
- En prod: NO carga ningún .env, solo usa entorno del sistema/contendor.
|
||||
- En production: NO carga ningún .env, solo usa entorno del sistema/contendor.
|
||||
- Si falta alguna variable requerida -> RuntimeError.
|
||||
"""
|
||||
|
||||
env = os.getenv("ENV", "dev")
|
||||
env = os.getenv("ENV", "development")
|
||||
|
||||
if env == "dev":
|
||||
if env == "development":
|
||||
dotenv_path = join(dirname(__file__), "../../enviroment/dev.env")
|
||||
load_dotenv(dotenv_path)
|
||||
elif env == "prod":
|
||||
elif env == "production":
|
||||
# En producción NO se carga archivo .env
|
||||
# Las variables vienen del contenedor (docker run -e VAR=...)
|
||||
pass
|
||||
@ -42,7 +42,6 @@ def load_config() -> Dict[str, Any]:
|
||||
config: Dict[str, Any] = {
|
||||
# Opcionales (con valor por defecto)
|
||||
"ENV": env,
|
||||
"ENVIRONMENT": os.getenv("ENVIRONMENT", env),
|
||||
"LOCAL_TZ": os.getenv("LOCAL_TZ", "Europe/Madrid"),
|
||||
"LAST_RUN_PATH": _required("LAST_RUN_PATH"),
|
||||
|
||||
@ -54,11 +53,11 @@ def load_config() -> Dict[str, Any]:
|
||||
"FACTUGES_PASSWORD": _required("FACTUGES_PASSWORD"),
|
||||
|
||||
# UECKO MySQL (requeridas salvo puerto)
|
||||
"UECKO_MYSQL_HOST": _required("UECKO_MYSQL_HOST"),
|
||||
"UECKO_MYSQL_PORT": os.getenv("UECKO_MYSQL_PORT", "3306"),
|
||||
"UECKO_MYSQL_DATABASE": _required("UECKO_MYSQL_DATABASE"),
|
||||
"UECKO_MYSQL_USER": _required("UECKO_MYSQL_USER"),
|
||||
"UECKO_MYSQL_PASSWORD": _required("UECKO_MYSQL_PASSWORD"),
|
||||
"FWEB_MYSQL_HOST": _required("FWEB_MYSQL_HOST"),
|
||||
"FWEB_MYSQL_PORT": os.getenv("FWEB_MYSQL_PORT", "3306"),
|
||||
"FWEB_MYSQL_DATABASE": _required("FWEB_MYSQL_DATABASE"),
|
||||
"FWEB_MYSQL_USER": _required("FWEB_MYSQL_USER"),
|
||||
"FWEB_MYSQL_PASSWORD": _required("FWEB_MYSQL_PASSWORD"),
|
||||
|
||||
# Constantes/CTE (requeridas)
|
||||
"CTE_COMPANY_ID": _required("CTE_COMPANY_ID"),
|
||||
@ -79,3 +78,14 @@ def load_config() -> Dict[str, Any]:
|
||||
}
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def log_config(config: dict) -> None:
|
||||
"""Loguea la configuración con una clave por línea."""
|
||||
lines = ["Loaded configuration:"]
|
||||
for key in sorted(config.keys()):
|
||||
value = config[key]
|
||||
if any(t in key.lower() for t in ("pass", "password", "api_key", "token", "secret")):
|
||||
value = "***"
|
||||
lines.append(f" {key} = {value!r}")
|
||||
logger.info("\n".join(lines))
|
||||
|
||||
55
app/config/setup_logger.py
Normal file
55
app/config/setup_logger.py
Normal file
@ -0,0 +1,55 @@
|
||||
import logging
|
||||
import sys
|
||||
import os
|
||||
from logging.handlers import RotatingFileHandler
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def create_logger(
|
||||
name: str = "factuges-sync",
|
||||
*,
|
||||
level: int = logging.INFO,
|
||||
log_path: str | None = None,
|
||||
) -> logging.Logger:
|
||||
"""
|
||||
Crea un logger:
|
||||
- SIEMPRE stdout (Docker-friendly)
|
||||
- SOLO EN PRODUCCIÓN añade RotatingFileHandler si log_path no es None
|
||||
"""
|
||||
|
||||
logger = logging.getLogger(name)
|
||||
logger.setLevel(level)
|
||||
|
||||
# No duplicar handlers si ya existe el logger
|
||||
if logger.handlers:
|
||||
return logger
|
||||
|
||||
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 1) Consola → SIEMPRE (para docker logs)
|
||||
# ------------------------------------------------------------------
|
||||
h_console = logging.StreamHandler(sys.stdout)
|
||||
h_console.setFormatter(formatter)
|
||||
logger.addHandler(h_console)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 2) Fichero → SOLO en prod + si se define log_path
|
||||
# ------------------------------------------------------------------
|
||||
environment = os.getenv("ENV", "development")
|
||||
if environment == "production" and log_path:
|
||||
Path(log_path).parent.mkdir(parents=True, exist_ok=True)
|
||||
h_file = RotatingFileHandler(
|
||||
log_path,
|
||||
maxBytes=5 * 1024 * 1024,
|
||||
backupCount=15,
|
||||
encoding="utf8",
|
||||
)
|
||||
h_file.setFormatter(formatter)
|
||||
logger.addHandler(h_file)
|
||||
|
||||
return logger
|
||||
|
||||
|
||||
# logger "global" ya creado
|
||||
logger = create_logger()
|
||||
@ -1,18 +0,0 @@
|
||||
import logging
|
||||
import sys
|
||||
from logging.handlers import RotatingFileHandler
|
||||
|
||||
def setup_logging():
|
||||
logging.basicConfig(stream=sys.stdout, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
|
||||
def setup_rotating_logging(log_path):
|
||||
# Rotación de logs con un tamaño máximo de 5 MB y mantiene 15 archivos de backup
|
||||
handler = RotatingFileHandler(log_path, maxBytes=5*1024*1024, backupCount=15, encoding="utf8")
|
||||
|
||||
# Configuración básica de logging
|
||||
logging.basicConfig(
|
||||
handlers=[handler],
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
8
app/config/version.py
Normal file
8
app/config/version.py
Normal file
@ -0,0 +1,8 @@
|
||||
from importlib.metadata import version, PackageNotFoundError
|
||||
|
||||
|
||||
def get_package_version() -> str:
|
||||
try:
|
||||
return version("factuges-sync") # nombre del paquete en [metadata].name
|
||||
except PackageNotFoundError:
|
||||
return "unknown"
|
||||
@ -1,6 +1,6 @@
|
||||
import fdb
|
||||
import mysql.connector
|
||||
import logging
|
||||
from app.config import logger
|
||||
|
||||
|
||||
def get_factuges_connection(config):
|
||||
@ -13,32 +13,32 @@ def get_factuges_connection(config):
|
||||
password=config['FACTUGES_PASSWORD'],
|
||||
charset='UTF8'
|
||||
)
|
||||
logging.info(
|
||||
logger.info(
|
||||
f"Conexión a la base de datos FactuGES establecida: {config['FACTUGES_HOST']} with database:{config['FACTUGES_DATABASE']} - using user:{config['FACTUGES_USER']}")
|
||||
return conn
|
||||
except Exception as e:
|
||||
logging.error("Error al conectar a la base de datos FactuGES.")
|
||||
logging.error(
|
||||
logger.error("Error al conectar a la base de datos FactuGES.")
|
||||
logger.error(
|
||||
f"(ERROR) Failed to establish connection to: {config['FACTUGES_HOST']} with database:{config['FACTUGES_DATABASE']} - using user:{config['FACTUGES_USER']}")
|
||||
logging.error(str(e))
|
||||
logger.error(str(e))
|
||||
raise e
|
||||
|
||||
|
||||
def get_mysql_connection(config):
|
||||
try:
|
||||
conn = mysql.connector.connect(
|
||||
host=config['UECKO_MYSQL_HOST'],
|
||||
port=config['UECKO_MYSQL_PORT'],
|
||||
database=config['UECKO_MYSQL_DATABASE'],
|
||||
user=config['UECKO_MYSQL_USER'],
|
||||
password=config['UECKO_MYSQL_PASSWORD']
|
||||
host=config['FWEB_MYSQL_HOST'],
|
||||
port=config['FWEB_MYSQL_PORT'],
|
||||
database=config['FWEB_MYSQL_DATABASE'],
|
||||
user=config['FWEB_MYSQL_USER'],
|
||||
password=config['FWEB_MYSQL_PASSWORD']
|
||||
)
|
||||
logging.info(
|
||||
f"Conexión a la base de datos MySQL establecida a: {config['UECKO_MYSQL_HOST']} with database:{config['UECKO_MYSQL_DATABASE']} - using user:{config['UECKO_MYSQL_USER']}")
|
||||
logger.info(
|
||||
f"Conexión a la base de datos MySQL establecida a: {config['FWEB_MYSQL_HOST']} with database:{config['FWEB_MYSQL_DATABASE']} - using user:{config['FWEB_MYSQL_USER']}")
|
||||
return conn
|
||||
except Exception as e:
|
||||
logging.error("Error al conectar a la base de datos MySQL.")
|
||||
logging.error(
|
||||
f"(ERROR) Failed to establish connection to: {config['UECKO_MYSQL_HOST']} with database:{config['UECKO_MYSQL_DATABASE']} - using user:{config['UECKO_MYSQL_USER']}")
|
||||
logging.error(str(e))
|
||||
logger.error("Error al conectar a la base de datos MySQL.")
|
||||
logger.error(
|
||||
f"(ERROR) Failed to establish connection to: {config['FWEB_MYSQL_HOST']} with database:{config['FWEB_MYSQL_DATABASE']} - using user:{config['FWEB_MYSQL_USER']}")
|
||||
logger.error(str(e))
|
||||
raise e
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import logging
|
||||
from app.config import logger
|
||||
from datetime import date
|
||||
from app.config import load_config
|
||||
import textwrap
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import logging
|
||||
from app.config import logger
|
||||
from typing import Dict, Any
|
||||
from uuid6 import uuid7
|
||||
from app.config import load_config
|
||||
@ -21,20 +21,20 @@ def sync_invoices_factuges(conn_factuges, conn_mysql, last_execution_date):
|
||||
|
||||
# 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
|
||||
ids_verifactu_deleted = {str(fila[0]) for fila in filas}
|
||||
# logging.info(f"Customer invoices rows to be deleted: {len(ids_verifactu_deleted)}")
|
||||
# logger.info(f"Customer invoices rows to be deleted: {len(ids_verifactu_deleted)}")
|
||||
# Verificar si hay filas en el resultado
|
||||
if ids_verifactu_deleted:
|
||||
sync_delete_invoices(conn_factuges, ids_verifactu_deleted, config)
|
||||
else:
|
||||
logging.info(
|
||||
logger.info(
|
||||
f"There are NOT customer invoices deleted since the last run")
|
||||
|
||||
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)
|
||||
logger.error(f"(ERROR) Failed to fetch from database:{
|
||||
config['FWEB_MYSQL_DATABASE']} - using user:{config['FWEB_MYSQL_USER']}")
|
||||
logger.error(e)
|
||||
raise e
|
||||
|
||||
# BUSCAMOS FACTURAS ENVIADAS A VERIFACTU EN FACTUGES, PARA SUBIRLAS AL NUEVO PROGRAMA DE FACTURACIÓN
|
||||
@ -48,9 +48,9 @@ def sync_invoices_factuges(conn_factuges, conn_mysql, last_execution_date):
|
||||
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)
|
||||
logger.error(f"(ERROR) Failed to fetch from database:{
|
||||
config['FACTUGES_DATABASE']} - using user:{config['FACTUGES_USER']}")
|
||||
logger.error(e)
|
||||
raise e
|
||||
|
||||
# Obtener los nombres de las columnas
|
||||
@ -67,7 +67,7 @@ def sync_invoices_factuges(conn_factuges, conn_mysql, last_execution_date):
|
||||
sync_invoices_from_FACTUGES(
|
||||
conn_mysql, tuplas_seleccionadas, conn_factuges, config)
|
||||
else:
|
||||
logging.info(
|
||||
logger.info(
|
||||
"There are NOT new FACTURAS rows since the last run.")
|
||||
|
||||
|
||||
@ -78,15 +78,15 @@ def sync_delete_invoices(conn_factuges, ids_verifactu_deleted, config):
|
||||
try:
|
||||
cursor_FactuGES = conn_factuges.cursor()
|
||||
if ids_verifactu_deleted:
|
||||
logging.info(f"Liberate factuGES: {ids_verifactu_deleted}")
|
||||
logger.info(f"Liberate factuGES: {ids_verifactu_deleted}")
|
||||
cursor_FactuGES.executemany(SQL.LIMPIAR_FACTUGES_LINK, [(
|
||||
id_verifactu,) for id_verifactu in ids_verifactu_deleted])
|
||||
else:
|
||||
logging.info("No articles to delete.")
|
||||
logger.info("No articles to delete.")
|
||||
|
||||
except Exception as e:
|
||||
# Escribir el error en el archivo de errores
|
||||
logging.error(str(e))
|
||||
logger.error(str(e))
|
||||
raise e # Re-lanzar la excepción para detener el procesamiento
|
||||
finally:
|
||||
# Cerrar la conexión
|
||||
@ -96,7 +96,7 @@ def sync_delete_invoices(conn_factuges, ids_verifactu_deleted, config):
|
||||
|
||||
def sync_invoices_from_FACTUGES(conn_mysql, filas, conn_factuges, config):
|
||||
# Insertaremos cada factura existente en las filas a la nueva estructura de tablas del programa nuevo de facturacion.
|
||||
# logging.info(f"FACTURAS_CLIENTE_DETALLE rows to be processed: {len(filas)}")
|
||||
# logger.info(f"FACTURAS_CLIENTE_DETALLE rows to be processed: {len(filas)}")
|
||||
|
||||
cursorMySQL = None
|
||||
cursor_FactuGES = None
|
||||
@ -163,10 +163,10 @@ def sync_invoices_from_FACTUGES(conn_mysql, filas, conn_factuges, config):
|
||||
sync_notes = (f">>> Factura {header_invoice_fields['reference']} no cumple requisitos para ser mandada a Verifactu: "
|
||||
f">>>>>> El NIF/NOMBRE ({customer_fields['tin']}/{customer_fields['name']}) no está registrado en la AEAT. "
|
||||
f"El NIF/CIF debe estar registrado en la AEAT y el nombre debe ser suficientemente parecido al nombre registrado en la AEAT")
|
||||
logging.info(sync_notes)
|
||||
logger.info(sync_notes)
|
||||
|
||||
# Guardamos en Factuges el id de la customer_invoice
|
||||
logging.info(
|
||||
logger.info(
|
||||
f"Updating FACTURAS_CLIENTE {sync_result} {invoice_id} {factuges_id} {sync_notes}")
|
||||
cursor_FactuGES.execute(SQL.UPDATE_FACTUGES_LINK, (sync_result, invoice_id, sync_notes, factuges_id))
|
||||
num_fac_procesed += 1
|
||||
@ -178,12 +178,12 @@ def sync_invoices_from_FACTUGES(conn_mysql, filas, conn_factuges, config):
|
||||
# Asignamos el id factura anterior para no volver a inserta cabecera
|
||||
factuges_id_anterior = factuges_id
|
||||
|
||||
logging.info(
|
||||
logger.info(
|
||||
f"FACTURAS_CLIENTE rows to be processed: {str(num_fac_procesed)}")
|
||||
|
||||
except Exception as e:
|
||||
# Escribir el error en el archivo de errores
|
||||
logging.error(str(e))
|
||||
logger.error(str(e))
|
||||
raise e # Re-lanzar la excepción para detener el procesamiento
|
||||
|
||||
finally:
|
||||
@ -202,8 +202,8 @@ def get_or_create_customer(cur, company_id: str, factuges_customer_id: str, fiel
|
||||
row = cur.fetchone()
|
||||
if not row or not row[0]:
|
||||
customer_id = str(uuid7())
|
||||
logging.info("Inserting customer %s %s %s",
|
||||
factuges_customer_id, fields["tin"], fields["name"])
|
||||
logger.info("Inserting customer %s %s %s",
|
||||
factuges_customer_id, fields["tin"], fields["name"])
|
||||
cur.execute(
|
||||
SQL.INSERT_CUSTOMER,
|
||||
(
|
||||
@ -215,7 +215,7 @@ def get_or_create_customer(cur, company_id: str, factuges_customer_id: str, fiel
|
||||
)
|
||||
return customer_id
|
||||
customer_id = str(row[0])
|
||||
logging.info("Updating customer %s %s", factuges_customer_id, customer_id)
|
||||
logger.info("Updating customer %s %s", factuges_customer_id, customer_id)
|
||||
cur.execute(
|
||||
SQL.UPDATE_CUSTOMER,
|
||||
(
|
||||
@ -236,13 +236,13 @@ def get_or_create_payment_method(cur, factuges_payment_id: str, description: str
|
||||
row = cur.fetchone()
|
||||
if not row or not row[0]:
|
||||
pm_id = str(uuid7())
|
||||
logging.info("Inserting payment method %s %s %s",
|
||||
factuges_payment_id, pm_id, description)
|
||||
logger.info("Inserting payment method %s %s %s",
|
||||
factuges_payment_id, pm_id, description)
|
||||
cur.execute(SQL.INSERT_PAYMENT_METHOD,
|
||||
(pm_id, description, factuges_payment_id))
|
||||
return pm_id
|
||||
pm_id = str(row[0])
|
||||
logging.info("Payment method exists %s -> %s", factuges_payment_id, pm_id)
|
||||
logger.info("Payment method exists %s -> %s", factuges_payment_id, pm_id)
|
||||
return pm_id
|
||||
|
||||
|
||||
@ -253,8 +253,8 @@ def insert_invoice_header(cur: str, cf: Dict[str, Any], hif: Dict[str, Any], cus
|
||||
"""
|
||||
invoice_id = str(uuid7())
|
||||
|
||||
logging.info("Inserting invoice %s %s %s %s %s",
|
||||
invoice_id, hif.get('reference'), hif.get('invoice_date'), hif.get('operation_date'), config['CTE_STATUS_INVOICE'])
|
||||
logger.info("Inserting invoice %s %s %s %s %s",
|
||||
invoice_id, hif.get('reference'), hif.get('invoice_date'), hif.get('operation_date'), config['CTE_STATUS_INVOICE'])
|
||||
cur.execute(
|
||||
SQL.INSERT_INVOICE,
|
||||
(
|
||||
@ -279,8 +279,8 @@ def insert_verifactu_record(cur: str, hif: Dict[str, Any], invoice_id: str, conf
|
||||
"""
|
||||
id = str(uuid7())
|
||||
|
||||
logging.info("Inserting verifactu record %s %s %s",
|
||||
id, hif.get('reference'), hif.get('invoice_date'))
|
||||
logger.info("Inserting verifactu record %s %s %s",
|
||||
id, hif.get('reference'), hif.get('invoice_date'))
|
||||
cur.execute(
|
||||
SQL.INSERT_VERIFACTU_RECORD,
|
||||
(
|
||||
@ -311,7 +311,7 @@ def insert_item_and_taxes(cur, invoice_id: str, fields: Dict[str, Any]) -> None:
|
||||
"""
|
||||
item_id = str(uuid7())
|
||||
|
||||
# logging.info("Inserting item %s pos=%s qty=%s", item_id, fields.get('position'), fields.get('quantity_value'))
|
||||
# logger.info("Inserting item %s pos=%s qty=%s", item_id, fields.get('position'), fields.get('quantity_value'))
|
||||
cur.execute(
|
||||
SQL.INSERT_INVOICE_ITEM,
|
||||
(item_id, invoice_id, fields.get('position'), fields.get('description'), fields.get('quantity_value'),
|
||||
@ -321,7 +321,7 @@ def insert_item_and_taxes(cur, invoice_id: str, fields: Dict[str, Any]) -> None:
|
||||
)
|
||||
)
|
||||
|
||||
# logging.info("Inserting item tax %s code=%s base=%s tax=%s",
|
||||
# logger.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'),
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import logging
|
||||
from app.config import logger
|
||||
from typing import Dict, Any, Tuple, Optional, List, Iterable
|
||||
from app.config import load_config
|
||||
from decimal import Decimal
|
||||
@ -26,22 +26,22 @@ def sync_invoices_verifactu(conn_mysql, last_execution_date):
|
||||
tuplas_seleccionadas.append(tupla)
|
||||
|
||||
# invoices_to_verifactu = {str(fila[0]) for fila in filas}
|
||||
logging.info(
|
||||
logger.info(
|
||||
f"Customer invoices rows to be send Verifactu: {len(tuplas_seleccionadas)}")
|
||||
|
||||
# Verificar si hay filas en el resultado
|
||||
if tuplas_seleccionadas:
|
||||
enviar_datos(tuplas_seleccionadas, cursor_mysql, config)
|
||||
logging.info(f"Ok send Verifactu")
|
||||
logger.info(f"Ok send Verifactu")
|
||||
else:
|
||||
logging.info(f"There are no rows to send")
|
||||
logger.info(f"There are no rows to send")
|
||||
|
||||
except Exception as error:
|
||||
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(error)
|
||||
logger.error(
|
||||
f"(ERROR) Failed to fetch from database:{config['FWEB_MYSQL_DATABASE']} - using user:{config['FWEB_MYSQL_USER']}")
|
||||
logger.error(error)
|
||||
raise error
|
||||
|
||||
|
||||
@ -61,9 +61,9 @@ def enviar_datos(invoices_to_verifactu, cursor_mysql, config):
|
||||
# preparamos nueva factura
|
||||
ok, respuesta = preparar_factura(fila)
|
||||
if not ok:
|
||||
logging.info(
|
||||
logger.info(
|
||||
f"ERROR >>>>>> Factura {fila['reference']} no cumple requisitos para ser mandada a Verifactu:")
|
||||
logging.info(
|
||||
logger.info(
|
||||
f">>>>>> Faltan campos requeridos: {respuesta}")
|
||||
factura = None
|
||||
continue
|
||||
@ -71,9 +71,9 @@ def enviar_datos(invoices_to_verifactu, cursor_mysql, config):
|
||||
|
||||
ok, linea = preparar_linea(fila)
|
||||
if not ok:
|
||||
logging.info(
|
||||
logger.info(
|
||||
f"ERROR >>>>>> Factura {factura.get('reference')} no cumple requisitos para ser mandada a Verifactu:")
|
||||
logging.info(f">>>>>> Faltan campos requeridos: {linea}")
|
||||
logger.info(f">>>>>> Faltan campos requeridos: {linea}")
|
||||
factura = None
|
||||
else:
|
||||
factura["lineas"].append(linea)
|
||||
@ -82,7 +82,7 @@ def enviar_datos(invoices_to_verifactu, cursor_mysql, config):
|
||||
|
||||
except Exception as e:
|
||||
# Escribir el error en el archivo de errores
|
||||
logging.error(str(e))
|
||||
logger.error(str(e))
|
||||
raise e # Re-lanzar la excepción para detener el procesamiento
|
||||
|
||||
|
||||
@ -95,29 +95,29 @@ def procesar_factura_verifactu(
|
||||
if factura != None:
|
||||
# Creamos registro de factura en verifactu
|
||||
if factura.get('uuid') == '':
|
||||
# logging.info(f"Send to create Verifactu: {factura}")
|
||||
# logger.info(f"Send to create Verifactu: {factura}")
|
||||
respuesta = crear_factura(factura, config)
|
||||
if respuesta.get("status") == 200 and respuesta.get("ok"):
|
||||
data = respuesta.get("data")
|
||||
qr_verifactu = f"data:image/png;base64,{data.get('qr', '')}"
|
||||
cursor_mysql.execute(SQL.update_verifactu_records_with_invoiceId, (data.get("estado"), data.get(
|
||||
"uuid"), data.get("url"), qr_verifactu, factura.get("id")))
|
||||
logging.info(
|
||||
logger.info(
|
||||
f">>> Factura {factura.get("reference")} registrada en Verifactu")
|
||||
return True
|
||||
else:
|
||||
logging.info(
|
||||
logger.info(
|
||||
f">>> Factura {factura.get("reference")} enviada a Verifactu con error {respuesta}")
|
||||
return False
|
||||
# Actualizamos registro de factura en verifactu
|
||||
else:
|
||||
# logging.info(f"Send to update Verifactu: {factura}")
|
||||
# logger.info(f"Send to update Verifactu: {factura}")
|
||||
respuesta = estado_factura(factura.get('uuid'), config)
|
||||
if respuesta.get("status") == 200 and respuesta.get("ok"):
|
||||
data = respuesta.get("data")
|
||||
cursor_mysql.execute(SQL.update_verifactu_records_with_uuid, (data.get(
|
||||
'estado'), data.get('operacion'), factura.get('uuid')))
|
||||
logging.info(
|
||||
logger.info(
|
||||
f">>> Factura {factura.get("reference")} actualizado registro de Verifactu")
|
||||
return True
|
||||
else:
|
||||
|
||||
@ -1,28 +1,32 @@
|
||||
import sys
|
||||
import logging
|
||||
|
||||
from app.__version_sync_factuges__ import __version__
|
||||
from app.config import get_package_version
|
||||
from datetime import datetime
|
||||
from dateutil import tz
|
||||
from app.config import setup_logging, load_config
|
||||
from app.config import create_logger, load_config, log_config
|
||||
from app.db import get_mysql_connection, get_factuges_connection, sync_invoices_factuges
|
||||
from app.utils import obtener_fecha_ultima_ejecucion, actualizar_fecha_ultima_ejecucion, log_system_metrics, send_orders_mail
|
||||
from app.utils import obtener_fecha_ultima_ejecucion, actualizar_fecha_ultima_ejecucion
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
# Cargar la configuración
|
||||
config = load_config()
|
||||
|
||||
version = get_package_version()
|
||||
local_tz = tz.gettz(config['LOCAL_TZ'])
|
||||
|
||||
# Logging
|
||||
setup_logging()
|
||||
logger = create_logger(
|
||||
name="factuges-sync",
|
||||
log_path="/app/logs/sync_factuges.log", # Solo lo genera en producción
|
||||
)
|
||||
|
||||
logging.info("== START SYNC FACTUGES ==")
|
||||
logging.info(f"Version: {__version__}")
|
||||
logging.info(f"Environment: {config['ENVIRONMENT']}")
|
||||
log_system_metrics()
|
||||
logger.info("============================================================")
|
||||
logger.info(" FACTUGES Sync FactuGES - START ")
|
||||
logger.info(" Version: %s", version)
|
||||
logger.info(" UTC Now: %s", datetime.utcnow().isoformat())
|
||||
logger.info(" Environment: {config['ENV']}")
|
||||
|
||||
log_config(config)
|
||||
|
||||
conn_factuges = None
|
||||
conn_mysql = None
|
||||
@ -32,17 +36,17 @@ def main():
|
||||
last_execution_date_local_tz = last_execution_date_utc.astimezone(
|
||||
tz=local_tz).strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
logging.info("Last execution (UTC): %s",
|
||||
last_execution_date_utc.strftime("%Y-%m-%d %H:%M:%S %Z"))
|
||||
logging.info("Last execution (Local time): %s",
|
||||
last_execution_date_local_tz)
|
||||
logger.info("Last execution (UTC): %s",
|
||||
last_execution_date_utc.strftime("%Y-%m-%d %H:%M:%S %Z"))
|
||||
logger.info("Last execution (Local time): %s",
|
||||
last_execution_date_local_tz)
|
||||
|
||||
# Abrimos conexiones con una única transacción para que todo esté controlado
|
||||
conn_factuges = get_factuges_connection(config)
|
||||
conn_mysql = get_mysql_connection(config)
|
||||
|
||||
# Sincronizamos
|
||||
logging.info(
|
||||
logger.info(
|
||||
f">>>>>>>>>>> INI Sync invoices FactuGES escritorio to FactuGES web")
|
||||
sync_invoices_factuges(conn_factuges, conn_mysql, last_execution_date_local_tz)
|
||||
|
||||
@ -51,21 +55,23 @@ def main():
|
||||
conn_factuges.commit()
|
||||
conn_factuges.close()
|
||||
conn_mysql.close()
|
||||
logging.info(f">>>>>>>>>>> FIN Sync invoices FactuGES escritorio to FactuGES web")
|
||||
logger.info(f">>>>>>>>>>> FIN Sync invoices FactuGES escritorio to FactuGES web")
|
||||
|
||||
actualizar_fecha_ultima_ejecucion(config['LAST_RUN_PATH'])
|
||||
|
||||
# Enviar email
|
||||
# send_orders_mail(inserted_orders)
|
||||
|
||||
logging.info("== END (0) ==")
|
||||
logger.info("== END (0) ==")
|
||||
logger.info("============================================================")
|
||||
sys.exit(0)
|
||||
|
||||
except Exception as e:
|
||||
logging.error("Se ha producido un error en la última ejecución.")
|
||||
logging.error(e)
|
||||
logging.error("Traceback:", exc_info=True)
|
||||
logging.info("== END (1) ==")
|
||||
logger.error("Se ha producido un error en la última ejecución.")
|
||||
logger.error(e)
|
||||
logger.error("Traceback:", exc_info=True)
|
||||
logger.info("== END (1) ==")
|
||||
logger.info("============================================================")
|
||||
|
||||
if conn_mysql is not None:
|
||||
conn_mysql.rollback()
|
||||
|
||||
@ -1,28 +1,33 @@
|
||||
import sys
|
||||
import logging
|
||||
|
||||
from app.__version_sync_factuges__ import __version__
|
||||
from app.config import get_package_version
|
||||
from datetime import datetime
|
||||
from dateutil import tz
|
||||
from config import setup_logging, load_config
|
||||
from db import get_mysql_connection, get_factuges_connection, sync_invoices_verifactu
|
||||
from utils import obtener_fecha_ultima_ejecucion, actualizar_fecha_ultima_ejecucion, log_system_metrics, send_orders_mail
|
||||
from app.config import create_logger, load_config, log_config
|
||||
from app.db import get_mysql_connection, get_factuges_connection, sync_invoices_verifactu
|
||||
from app.utils import obtener_fecha_ultima_ejecucion, actualizar_fecha_ultima_ejecucion
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
# Cargar la configuración
|
||||
config = load_config()
|
||||
|
||||
version = get_package_version()
|
||||
local_tz = tz.gettz(config['LOCAL_TZ'])
|
||||
|
||||
# Logging
|
||||
setup_logging()
|
||||
logger = create_logger(
|
||||
name="factuges-sync",
|
||||
log_path="/app/logs/sync_verifactu.log", # Solo lo genera en producción
|
||||
)
|
||||
|
||||
logging.info("== START SYNC VERIFACTU ==")
|
||||
logging.info(f"Version: {__version__}")
|
||||
logging.info(f"Environment: {config['ENVIRONMENT']}")
|
||||
log_system_metrics()
|
||||
logger.info("============================================================")
|
||||
logger.info(" FACTUGES Sync Verifactu - START ")
|
||||
logger.info(" Version: %s", version)
|
||||
logger.info(" UTC Now: %s", datetime.utcnow().isoformat())
|
||||
logger.info(" Environment: {config['ENV']}")
|
||||
|
||||
log_config(config)
|
||||
|
||||
conn_factuges = None
|
||||
conn_mysql = None
|
||||
@ -32,35 +37,37 @@ def main():
|
||||
last_execution_date_local_tz = last_execution_date_utc.astimezone(
|
||||
tz=local_tz).strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
logging.info("Last execution (UTC): %s",
|
||||
last_execution_date_utc.strftime("%Y-%m-%d %H:%M:%S %Z"))
|
||||
logging.info("Last execution (Local time): %s",
|
||||
last_execution_date_local_tz)
|
||||
logger.info("Last execution (UTC): %s",
|
||||
last_execution_date_utc.strftime("%Y-%m-%d %H:%M:%S %Z"))
|
||||
logger.info("Last execution (Local time): %s",
|
||||
last_execution_date_local_tz)
|
||||
|
||||
# Abrimos conexión con una única transacción para que todo esté controlado
|
||||
conn_mysql = get_mysql_connection(config)
|
||||
|
||||
# Sync Verifactu
|
||||
logging.info(
|
||||
logger.info(
|
||||
f">>>>>>>>>> INI Sync facturas emitidas to Verifactu")
|
||||
sync_invoices_verifactu(conn_mysql, last_execution_date_local_tz)
|
||||
conn_mysql.commit()
|
||||
conn_mysql.close()
|
||||
logging.info(f">>>>>>>>>> FIN Sync facturas emitidas to Verifactu")
|
||||
logger.info(f">>>>>>>>>> FIN Sync facturas emitidas to Verifactu")
|
||||
|
||||
actualizar_fecha_ultima_ejecucion()
|
||||
|
||||
# Enviar email
|
||||
# send_orders_mail(inserted_orders)
|
||||
|
||||
logging.info("== END (0) ==")
|
||||
logger.info("== END (0) ==")
|
||||
logger.info("============================================================")
|
||||
sys.exit(0)
|
||||
|
||||
except Exception as e:
|
||||
logging.error("Se ha producido un error en la última ejecución.")
|
||||
logging.error(e)
|
||||
logging.error("Traceback:", exc_info=True)
|
||||
logging.info("== END (1) ==")
|
||||
logger.error("Se ha producido un error en la última ejecución.")
|
||||
logger.error(e)
|
||||
logger.error("Traceback:", exc_info=True)
|
||||
logger.info("== END (1) ==")
|
||||
logger.info("============================================================")
|
||||
|
||||
if conn_mysql is not None:
|
||||
conn_mysql.rollback()
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
from .last_execution_helper import actualizar_fecha_ultima_ejecucion, obtener_fecha_ultima_ejecucion
|
||||
from .log_system_metrics import log_system_metrics
|
||||
from .password import hashPassword
|
||||
from .send_orders_mail import send_orders_mail
|
||||
from .text_converter import text_converter, limpiar_cadena
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
import psutil
|
||||
import logging
|
||||
|
||||
def log_system_metrics():
|
||||
cpu_usage = psutil.cpu_percent(interval=1)
|
||||
memory_usage = psutil.virtual_memory().percent
|
||||
|
||||
logging.info(f'CPU Usage: {cpu_usage}%')
|
||||
logging.info(f'Memory Usage: {memory_usage}%')
|
||||
@ -1,4 +1,4 @@
|
||||
import logging
|
||||
from app.config import logger
|
||||
import brevo_python
|
||||
|
||||
from brevo_python.rest import ApiException
|
||||
@ -25,6 +25,6 @@ def send_orders_mail(inserted_orders):
|
||||
},
|
||||
)
|
||||
api_response = api_instance.send_transac_email(send_smtp_email)
|
||||
logging.info(msg=api_response)
|
||||
logger.info(msg=api_response)
|
||||
except ApiException as e:
|
||||
logging.error(msg=e)
|
||||
logger.error(msg=e)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import requests
|
||||
import logging
|
||||
from app.config import logger
|
||||
from typing import Optional, Dict, Any, Tuple
|
||||
|
||||
|
||||
@ -51,10 +51,10 @@ def estado_factura(uuid_str: str,
|
||||
return {"ok": False, "status": resp.status_code, "error": f"HTTP {resp.status_code}", "raw": resp.text}
|
||||
|
||||
except requests.RequestException as e:
|
||||
logging.error("Error de conexión con la API Verifacti: %s", e)
|
||||
logger.error("Error de conexión con la API Verifacti: %s", e)
|
||||
return False, None, str(e)
|
||||
except ValueError as e:
|
||||
logging.error("Respuesta no es JSON válido: %s", e)
|
||||
logger.error("Respuesta no es JSON válido: %s", e)
|
||||
return False, None, "Respuesta no es JSON válido"
|
||||
|
||||
|
||||
@ -83,7 +83,7 @@ def crear_factura(payload,
|
||||
if resp.status_code == 200:
|
||||
try:
|
||||
data = resp.json()
|
||||
# logging.info(data)
|
||||
# logger.info(data)
|
||||
except ValueError:
|
||||
return {"ok": False, "status": 200, "error": "Respuesta 200 sin JSON válido", "raw": resp.text}
|
||||
return {"ok": True, "status": 200, "data": data}
|
||||
@ -106,10 +106,10 @@ def crear_factura(payload,
|
||||
return {"ok": False, "status": resp.status_code, "error": f"HTTP {resp.status_code}", "raw": resp.text}
|
||||
|
||||
except requests.RequestException as e:
|
||||
logging.error("Error de conexión con la API Verifacti: %s", e)
|
||||
logger.error("Error de conexión con la API Verifacti: %s", e)
|
||||
return False, None, str(e)
|
||||
except ValueError as e:
|
||||
logging.error("Respuesta no es JSON válido: %s", e)
|
||||
logger.error("Respuesta no es JSON válido: %s", e)
|
||||
return False, None, "Respuesta no es JSON válido"
|
||||
|
||||
|
||||
@ -140,18 +140,18 @@ def validar_nif(
|
||||
resp = requests.post(
|
||||
url, json=payload, headers=headers, timeout=timeout)
|
||||
if resp.status_code != 200:
|
||||
logging.info(f"ERRRRRROOOOOOORRRRR LLAMADA REST API")
|
||||
logger.info(f"ERRRRRROOOOOOORRRRR LLAMADA REST API")
|
||||
# return False, None, f"HTTP {resp.status_code}: {resp.text}"
|
||||
|
||||
data = resp.json()
|
||||
resultado = data.get("resultado", "NO IDENTIFICADO")
|
||||
logging.info(f"Resultado Verifacti: {resultado}")
|
||||
logger.info(f"Resultado Verifacti: {resultado}")
|
||||
|
||||
return resultado == "IDENTIFICADO"
|
||||
|
||||
except requests.RequestException as e:
|
||||
logging.error("Error de conexión con la API Verifacti: %s", e)
|
||||
logger.error("Error de conexión con la API Verifacti: %s", e)
|
||||
return False, None, str(e)
|
||||
except ValueError as e:
|
||||
logging.error("Respuesta no es JSON válido: %s", e)
|
||||
logger.error("Respuesta no es JSON válido: %s", e)
|
||||
return False, None, "Respuesta no es JSON válido"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import logging
|
||||
from app.config import logger
|
||||
import json
|
||||
from decimal import Decimal
|
||||
from typing import Any, Dict, Iterable, Optional, Tuple
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import logging
|
||||
import re
|
||||
from app.config import logger
|
||||
|
||||
|
||||
def text_converter(texto, charset_destino='ISO8859_1', longitud_maxima=None):
|
||||
@ -24,18 +24,18 @@ def text_converter(texto, charset_destino='ISO8859_1', longitud_maxima=None):
|
||||
|
||||
# Si se especifica una longitud máxima, truncar el texto
|
||||
if longitud_maxima and len(texto_convertido) > longitud_maxima:
|
||||
logging.warning(
|
||||
logger.warning(
|
||||
f"El texto ha sido truncado de {len(texto_convertido)} a {longitud_maxima} caracteres.")
|
||||
texto_convertido = texto_convertido[:longitud_maxima]
|
||||
|
||||
return texto_convertido
|
||||
|
||||
except UnicodeEncodeError as e:
|
||||
logging.error(
|
||||
logger.error(
|
||||
f"Error al convertir texto a {charset_destino}: {str(e)}")
|
||||
return ""
|
||||
except Exception as e:
|
||||
logging.error(f"Error inesperado al convertir texto: {str(e)}")
|
||||
logger.error(f"Error inesperado al convertir texto: {str(e)}")
|
||||
return ""
|
||||
|
||||
|
||||
|
||||
@ -1,17 +1,41 @@
|
||||
services:
|
||||
uecko_sync:
|
||||
container_name: uecko_sync_app:v1.0.8
|
||||
env_file: ".env.production"
|
||||
build: .
|
||||
#volumes:
|
||||
#- logs:/var/log/uecko_sync_app
|
||||
networks:
|
||||
- presupuestador-uecko_private
|
||||
restart: unless-stopped
|
||||
factuges_sync:
|
||||
image: "factuges-sync-factuges:acana-latest"
|
||||
container_name: "factuges-sync-factuges-acana"
|
||||
restart: "no"
|
||||
environment:
|
||||
ENV: "prod"
|
||||
LOCAL_TZ: "Europe/Madrid"
|
||||
LAST_RUN_PATH: "${LAST_RUN_PATH}"
|
||||
|
||||
#volumes:
|
||||
# logs:
|
||||
FACTUGES_HOST: "${FACTUGES_HOST}"
|
||||
FACTUGES_PORT: "${FACTUGES_PORT}"
|
||||
FACTUGES_DATABASE: "${FACTUGES_DATABASE}"
|
||||
FACTUGES_USER: "${FACTUGES_USER}"
|
||||
FACTUGES_PASSWORD: "${FACTUGES_PASSWORD}"
|
||||
|
||||
networks:
|
||||
presupuestador-uecko_private:
|
||||
external: true
|
||||
FWEB_MYSQL_HOST: "db"
|
||||
FWEB_MYSQL_PORT: "${DB_PORT}"
|
||||
FWEB_MYSQL_DATABASE: "${DB_NAME}"
|
||||
FWEB_MYSQL_USER: "${DB_USER}"
|
||||
FWEB_MYSQL_PASSWORD: "${DB_PASS}"
|
||||
|
||||
CTE_COMPANY_ID: "${CTE_COMPANY_ID}"
|
||||
CTE_SERIE: "${CTE_SERIE}"
|
||||
CTE_STATUS_INVOICE: "${CTE_STATUS_INVOICE}"
|
||||
CTE_IS_PROFORMA: "${CTE_IS_PROFORMA}"
|
||||
CTE_STATUS_VERIFACTU: "${CTE_STATUS_VERIFACTU}"
|
||||
CTE_LANGUAGE_CODE: "${CTE_LANGUAGE_CODE}"
|
||||
CTE_COUNTRY_CODE: "${CTE_COUNTRY_CODE}"
|
||||
CTE_IS_COMPANY: "${CTE_IS_COMPANY}"
|
||||
CTE_SYNC_RESULT_OK: "${CTE_SYNC_RESULT_OK}"
|
||||
CTE_SYNC_RESULT_FAIL: "${CTE_SYNC_RESULT_FAIL}"
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- internal
|
||||
- edge
|
||||
volumes:
|
||||
- ./volumes/db_sync/logs:/app/logs
|
||||
- ./volumes/db_sync/last_run_factuges.ini:/app/last_run_factuges.ini:rw
|
||||
@ -1,4 +1,4 @@
|
||||
ENVIRONMENT = development
|
||||
ENV = development
|
||||
LOCAL_TZ = Europe/Madrid
|
||||
LAST_RUN_PATH = ./app.last_run.txt
|
||||
#LOG_PATH = ./app.log
|
||||
@ -25,11 +25,11 @@ CTE_COMPANY_ID = '019a9667-6a65-767a-a737-48234ee50a3a'
|
||||
VERIFACTU_API_KEY = vf_test_C03HL2F0X5OXSDRunjNFoMxD4IrRfK3kCC8PfcvCENI=
|
||||
|
||||
#DESARROLLO
|
||||
UECKO_MYSQL_HOST = localhost
|
||||
UECKO_MYSQL_PORT = 3306
|
||||
UECKO_MYSQL_DATABASE = uecko_erp_sync
|
||||
UECKO_MYSQL_USER = rodax
|
||||
UECKO_MYSQL_PASSWORD = rodax
|
||||
FWEB_MYSQL_HOST = localhost
|
||||
FWEB_MYSQL_PORT = 3306
|
||||
FWEB_MYSQL_DATABASE = uecko_erp_sync
|
||||
FWEB_MYSQL_USER = rodax
|
||||
FWEB_MYSQL_PASSWORD = rodax
|
||||
|
||||
CTE_SERIE = 'F25/'
|
||||
CTE_STATUS_INVOICE = 'issued'
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
ENVIRONMENT = development
|
||||
ENV = development
|
||||
LOCAL_TZ = Europe/Madrid
|
||||
#LOG_PATH = ./app.log
|
||||
|
||||
@ -18,17 +18,17 @@ FACTUGES_CONTRATO_TIPO_DETALLE = "Concepto"
|
||||
FACTUGES_NOMBRE_TARIFA = TARIFA 2024
|
||||
FACTUGES_PRECIO_PUNTO = 3.31
|
||||
|
||||
PRO_UECKO_MYSQL_HOST = 192.168.0.250
|
||||
PRO_UECKO_MYSQL_PORT = 3306
|
||||
PRO_UECKO_MYSQL_DATABASE = factuges_db
|
||||
PRO_UECKO_MYSQL_USER = root
|
||||
PRO_UECKO_MYSQL_PASSWORD = rootpass
|
||||
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
|
||||
|
||||
DEV_UECKO_MYSQL_HOST = 192.168.0.104
|
||||
DEV_UECKO_MYSQL_PORT = 3306
|
||||
DEV_UECKO_MYSQL_DATABASE = uecko_erp_sync
|
||||
DEV_UECKO_MYSQL_USER = rodax
|
||||
DEV_UECKO_MYSQL_PASSWORD = rodax
|
||||
DEV_FWEB_MYSQL_HOST = 192.168.0.104
|
||||
DEV_FWEB_MYSQL_PORT = 3306
|
||||
DEV_FWEB_MYSQL_DATABASE = uecko_erp_sync
|
||||
DEV_FWEB_MYSQL_USER = rodax
|
||||
DEV_FWEB_MYSQL_PASSWORD = rodax
|
||||
|
||||
|
||||
BREVO_API_KEY = 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
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
ENVIRONMENT = development
|
||||
ENV = development
|
||||
LOCAL_TZ = Europe/Madrid
|
||||
LAST_RUN_PATH = ./app.last_run.txt
|
||||
#LOG_PATH = ./app.log
|
||||
@ -11,11 +11,11 @@ FACTUGES_USER = sysdba
|
||||
FACTUGES_PASSWORD = masterkey
|
||||
|
||||
#DESARROLLO
|
||||
UECKO_MYSQL_HOST = localhost
|
||||
UECKO_MYSQL_PORT = 3306
|
||||
UECKO_MYSQL_DATABASE = uecko_erp_sync
|
||||
UECKO_MYSQL_USER = rodax
|
||||
UECKO_MYSQL_PASSWORD = rodax
|
||||
FWEB_MYSQL_HOST = localhost
|
||||
FWEB_MYSQL_PORT = 3306
|
||||
FWEB_MYSQL_DATABASE = uecko_erp_sync
|
||||
FWEB_MYSQL_USER = rodax
|
||||
FWEB_MYSQL_PASSWORD = rodax
|
||||
|
||||
#CONFIGURACION ACANA
|
||||
CTE_COMPANY_ID = '019a9667-6a65-767a-a737-48234ee50a3a'
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
ENVIRONMENT = development
|
||||
ENV = development
|
||||
LOCAL_TZ = Europe/Madrid
|
||||
LAST_RUN_PATH = ./app.last_run.txt
|
||||
#LOG_PATH = ./app.log
|
||||
|
||||
#DESARROLLO
|
||||
UECKO_MYSQL_HOST = localhost
|
||||
UECKO_MYSQL_PORT = 3306
|
||||
UECKO_MYSQL_DATABASE = uecko_erp_sync
|
||||
UECKO_MYSQL_USER = rodax
|
||||
UECKO_MYSQL_PASSWORD = rodax
|
||||
FWEB_MYSQL_HOST = localhost
|
||||
FWEB_MYSQL_PORT = 3306
|
||||
FWEB_MYSQL_DATABASE = uecko_erp_sync
|
||||
FWEB_MYSQL_USER = rodax
|
||||
FWEB_MYSQL_PASSWORD = rodax
|
||||
|
||||
VERIFACTU_BASE_URL = https://api.verifacti.com/
|
||||
VERIFACTU_API_KEY = vf_test_ei8WYAvEq5dhSdEyQVjgCS8NZaNpEK2BljSHSUXf+Y0=
|
||||
|
||||
30
enviroment/acana.env
Normal file
30
enviroment/acana.env
Normal file
@ -0,0 +1,30 @@
|
||||
ENV = development
|
||||
LOCAL_TZ = Europe/Madrid
|
||||
LAST_RUN_PATH = /usr/share/factuges-app/last_run.txt
|
||||
|
||||
FACTUGES_HOST = acana.mywire.org
|
||||
FACTUGES_PORT = 63050
|
||||
FACTUGES_DATABASE = D:\Rodax\BD\FACTUGES.FDB
|
||||
FACTUGES_USER = sysdba
|
||||
FACTUGES_PASSWORD = masterkey
|
||||
CTE_COMPANY_ID = '019a9667-6a65-767a-a737-48234ee50a3a'
|
||||
VERIFACTU_API_KEY = vf_test_ei8WYAvEq5dhSdEyQVjgCS8NZaNpEK2BljSHSUXf+Y0=
|
||||
|
||||
FWEB_MYSQL_HOST = db
|
||||
FWEB_MYSQL_PORT = 3306
|
||||
FWEB_MYSQL_DATABASE = factuges_acana
|
||||
FWEB_MYSQL_USER = acana
|
||||
FWEB_MYSQL_PASSWORD = r@U8%GJ+2e/AWR
|
||||
|
||||
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
|
||||
CTE_SYNC_RESULT_OK = 1
|
||||
CTE_SYNC_RESULT_FAIL = 2
|
||||
|
||||
VERIFACTU_BASE_URL = https://api.verifacti.com/
|
||||
VERIFACTU_NIFS_API_KEY = vfn_osYpNdqSzAdTAHpazXG2anz4F3o0gfbSb5FFrCBZcno=
|
||||
@ -1,4 +1,4 @@
|
||||
ENVIRONMENT = development
|
||||
ENV = development
|
||||
LOCAL_TZ = Europe/Madrid
|
||||
LAST_RUN_PATH = ./app.last_run.txt
|
||||
#LOG_PATH = ./app.log
|
||||
@ -25,11 +25,11 @@ CTE_COMPANY_ID = '019a9667-6a65-767a-a737-48234ee50a3a'
|
||||
VERIFACTU_API_KEY = vf_test_C03HL2F0X5OXSDRunjNFoMxD4IrRfK3kCC8PfcvCENI=
|
||||
|
||||
#DESARROLLO
|
||||
UECKO_MYSQL_HOST = localhost
|
||||
UECKO_MYSQL_PORT = 3306
|
||||
UECKO_MYSQL_DATABASE = uecko_erp_sync
|
||||
UECKO_MYSQL_USER = rodax
|
||||
UECKO_MYSQL_PASSWORD = rodax
|
||||
FWEB_MYSQL_HOST = localhost
|
||||
FWEB_MYSQL_PORT = 3306
|
||||
FWEB_MYSQL_DATABASE = uecko_erp_sync
|
||||
FWEB_MYSQL_USER = rodax
|
||||
FWEB_MYSQL_PASSWORD = rodax
|
||||
|
||||
CTE_SERIE = 'F25/'
|
||||
CTE_STATUS_INVOICE = 'issued'
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
DB_HOST=prod-db
|
||||
DB_USER=prod_user
|
||||
DB_PASS=supersecret
|
||||
RUN_INTERVAL_MINUTES=5
|
||||
@ -2,12 +2,12 @@
|
||||
|
||||
# Sincronización FactuGES → cada 5 minutos
|
||||
*/5 * * * * docker run --rm \
|
||||
-e ENV=prod \
|
||||
-e ENV=production \
|
||||
factuges-sync-factuges:acme-latest \
|
||||
>> /var/log/factuges-sync/factuges.log 2>&1
|
||||
|
||||
# Sincronización Verifactu → cada 7 minutos
|
||||
*/7 * * * * docker run --rm \
|
||||
-e ENV=prod \
|
||||
-e ENV=production \
|
||||
factuges-sync-verifactu:acme-latest \
|
||||
>> /var/log/factuges-sync/verifactu.log 2>&1
|
||||
|
||||
@ -23,13 +23,13 @@ cat > "$CRON_FILE" <<EOF
|
||||
|
||||
# Sincronización FactuGES → cada 5 minutos
|
||||
*/5 * * * * docker run --rm \
|
||||
-e ENV=prod \
|
||||
-e ENV=production \
|
||||
factuges-sync-factuges:${COMPANY}-latest \
|
||||
>> /var/log/factuges-sync/factuges.log 2>&1
|
||||
|
||||
# Sincronización Verifactu → cada 7 minutos
|
||||
*/7 * * * * docker run --rm \
|
||||
-e ENV=prod \
|
||||
-e ENV=production \
|
||||
factuges-sync-verifactu:${COMPANY}-latest \
|
||||
>> /var/log/factuges-sync/verifactu.log 2>&1
|
||||
EOF
|
||||
|
||||
Loading…
Reference in New Issue
Block a user