2025-05-17 11:36:26 -04:00

402 lines
22 KiB
Go

package main
import (
"context"
"daemonService/internal/handlers"
"daemonService/internal/models"
svc "daemonService/internal/models"
"daemonService/internal/models/obtencionCodigos"
"daemonService/internal/repositories"
"daemonService/internal/services/obtencionCodigo"
"daemonService/internal/services/procesar"
"daemonService/internal/services/sincronizacionDatos"
"flag"
"fmt"
"github.com/robfig/cron/v3"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"daemonService/internal/api"
"daemonService/internal/config"
"daemonService/internal/database"
"daemonService/internal/notifications"
"daemonService/internal/services"
)
func main() {
configFile := flag.String("config", "configs/config.yaml", "Ruta al archivo de configuración")
runOnce := flag.Bool("run-once", false, "Ejecutar servicios una vez y salir")
serviceName := flag.String("service", "", "Nombre del servicio específico a ejecutar")
flag.Parse()
// Cargar configuración
cfg, err := config.LoadConfig(*configFile)
if err != nil {
log.Fatalf("Error al cargar configuración: %v", err)
}
// Inicializar la base de datos
db, err := database.InitDB(*cfg)
if err != nil {
log.Fatalf("Error al inicializar la base de datos: %v", err)
}
defer db.Close()
// Crear sistema de notificaciones
notifier := notifications.CreateNotificationSender(cfg.Notifications.Enabled, cfg.Notifications.Method, cfg.Notifications.Config)
if notifier != nil {
log.Printf("Sistema de notificaciones iniciado: %s", cfg.Notifications.Method)
}
// Crear servicios a partir de la configuración
var servicesList []models.SoapService
var servicesList2 []obtencionCodigos.CuisService
for _, svcCfg := range cfg.Services {
if !svcCfg.Enabled {
continue
}
// Crear el logger para el servicio
serviceLogger := log.New(log.Writer(), fmt.Sprintf("[%s] ", svcCfg.Name), log.LstdFlags)
baseSvc := svc.ServiceModel{
Name: svcCfg.Name,
Enabled: svcCfg.Enabled,
Concurrency: svcCfg.Concurrency,
DB: db,
SOAPEndpoint: cfg.SOAP.FACTURA_SINCRONIZACION.Endpoint,
SOAPTimeout: time.Duration(cfg.SOAP.FACTURA_SINCRONIZACION.Timeout) * time.Second,
SOAPRetries: cfg.SOAP.FACTURA_SINCRONIZACION.Retries,
NotificationSender: notifier,
KeyToken: "",
ValueToken: "",
TagNames: "",
QueryInsert: "",
MsgCustomResponse: "",
}
cuisServiceModel := obtencionCodigos.CuisServiceModel{
Name: svcCfg.Name,
Enabled: svcCfg.Enabled,
Concurrency: svcCfg.Concurrency,
DB: db,
SOAPEndpoint: cfg.SOAP.FACTURA_CODIGO.Endpoint,
SOAPTimeout: time.Duration(cfg.SOAP.FACTURA_CODIGO.Timeout) * time.Second,
SOAPRetries: cfg.SOAP.FACTURA_CODIGO.Retries,
NotificationSender: notifier,
TokenKey: "",
TokenValue: "",
TagNames: "",
TagNamesCufd: "",
QueryInsert: "",
MsgCustomResponse: "",
}
//registrar-empresa solo para registrar empresa
cuisServiceModel.TagNames = "cuis"
cuisServiceModel.TagNamesCufd = "cufd"
cuisServiceModel.QueryInsert = "INSERT INTO registroEmpresa (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
cuisServiceModel.MsgCustomResponse = "Registrar Empresa"
procesarRegistro := procesar.NewProcesarRegistro(cuisServiceModel)
empresaRepository := repositories.NewEmpresaRepository(cuisServiceModel)
cuisService := services.NewCuisService(cuisServiceModel, serviceLogger)
cuisRepository := repositories.NewCuisRepository(baseSvc, cuisService)
cronHandler := handlers.NewCronHandler(cuisService, empresaRepository, cuisRepository, procesarRegistro)
apiHandler := handlers.NewApiHandler(cuisService, cuisRepository, procesarRegistro)
// Llamar a NewObtencionCodigoService correctamente
obtencionCodigoSvc := obtencionCodigo.NewObtencionCodigoService(
cuisServiceModel,
cuisService,
cronHandler,
apiHandler,
)
switch svcCfg.Name {
case "registrar-empresa":
servicesList2 = append(servicesList2, obtencionCodigoSvc)
break
case "actividades": //todo revisar que pasa
baseSvc.TagNames = "sincronizarActividades"
baseSvc.QueryInsert = "INSERT INTO sincronizar_actividades (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Listado de Actividades"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
case "sincronizar_fecha_hora": //todo revisar que pasa
baseSvc.TagNames = "sincronizarFechaHora"
baseSvc.QueryInsert = "INSERT INTO sincronizar_fecha_hora (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Sincronizar la hora"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
case "sincronizar_mensaje_servicio": //todo revisar que pasa
baseSvc.TagNames = "sincronizarListaMensajesServicios"
baseSvc.QueryInsert = "INSERT INTO sincronizar_mensaje_servicio (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Sincronizar mensaje servicio"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
case "leyendas_factura":
baseSvc.TagNames = "sincronizarListaLeyendasFactura"
baseSvc.QueryInsert = "INSERT INTO sincronizar_leyendas_factura (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Listado Leyendas de Facturas"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
case "producto-servicio":
baseSvc.TagNames = "sincronizarListaProductosServicios"
baseSvc.QueryInsert = "INSERT INTO sincronizar_productos_servicios (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Listado Producto Servicio"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
case "tipo_motivo_anulacion":
baseSvc.TagNames = "sincronizarParametricaMotivoAnulacion"
baseSvc.QueryInsert = "INSERT INTO sincronizar_tipo_motivo_anulacion (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Listado motivo anulacion"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
case "tipo_documento_identidad":
baseSvc.TagNames = "sincronizarParametricaTipoDocumentoIdentidad"
baseSvc.QueryInsert = "INSERT INTO sincronizar_tipo_documento_identidad (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Listado tipos de documento de identidad"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
case "tipo_documento_sector":
baseSvc.TagNames = "sincronizarParametricaTipoDocumentoSector"
baseSvc.QueryInsert = "INSERT INTO sincronizar_tipo_documento_sector (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Listado tipos de documento sector"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
case "tipo_emision": //todo falta este
baseSvc.TagNames = "sincronizarParametricaTipoEmision"
baseSvc.QueryInsert = "INSERT INTO sincronizar_tipo_emision (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Listado tipos de emision"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
case "tipo_actividades_documento_sector": //todo falta este
baseSvc.TagNames = "sincronizarListaActividadesDocumentoSector"
baseSvc.QueryInsert = "INSERT INTO sincronizar_tipo_actividades_documento_sector (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Listado tipos de emision"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
case "tipo_metodo_pago":
baseSvc.TagNames = "sincronizarParametricaTipoMetodoPago"
baseSvc.QueryInsert = "INSERT INTO sincronizar_tipo_metodo_pago (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Listado tipos metodo de pago"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
case "tipo_moneda":
baseSvc.TagNames = "sincronizarParametricaTipoMoneda"
baseSvc.QueryInsert = "INSERT INTO sincronizar_tipo_moneda (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Listado tipos de moneda"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
case "tipo_punto_venta":
baseSvc.TagNames = "sincronizarParametricaTipoPuntoVenta"
baseSvc.QueryInsert = "INSERT INTO sincronizar_tipo_punto_venta (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Listado tipos de punto de venta"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
case "tipo_factura": //todo este falta
baseSvc.TagNames = "sincronizarParametricaTiposFactura"
baseSvc.QueryInsert = "INSERT INTO sincronizar_tipo_factura (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Listado tipos de factura"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
case "tipo_unidad_medida":
baseSvc.TagNames = "sincronizarParametricaUnidadMedida"
baseSvc.QueryInsert = "INSERT INTO sincronizar_tipo_unidad_medida (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Listado tipos de unidad de medida"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
case "tipo_evento_significativos":
baseSvc.TagNames = "sincronizarParametricaEventosSignificativos"
baseSvc.QueryInsert = "INSERT INTO sincronizar_evento_significativo (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Listado eventos significativos"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
case "sincronizar_tipo_habitacion":
baseSvc.TagNames = "sincronizarParametricaTipoHabitacion"
baseSvc.QueryInsert = "INSERT INTO sincronizar_Tipo_Habitacion (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Listado eventos significativos"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
case "sincronizar_pais_origen":
baseSvc.TagNames = "sincronizarParametricaPaisOrigen"
baseSvc.QueryInsert = "INSERT INTO sincronizar_Pais_Origen (codigo, reqSoap, respSoap, reqJson, respJson, cuis_id, fecha_creacion) VALUES ($1, $2, $3, $4, $5, $6, NOW() AT TIME ZONE 'America/La_Paz') ON CONFLICT (codigo, cuis_id) DO UPDATE SET reqSoap = EXCLUDED.reqSoap, respSoap = EXCLUDED.respSoap, reqJson = EXCLUDED.reqJson, respJson = EXCLUDED.respJson, cuis_id = EXCLUDED.cuis_id, fecha_actualizacion = NOW() AT TIME ZONE 'America/La_Paz';"
baseSvc.MsgCustomResponse = "Listado eventos significativos"
servicesList = append(servicesList, &sincronizacionDatos.SincronizacionDatosService{
ServiceModel: baseSvc,
})
break
default:
log.Printf("Servicio desconocido: %s", svcCfg.Name)
}
}
// Si se especifica un servicio específico, filtrar la lista.
if *serviceName != "" {
var filtered []models.SoapService
for _, s := range servicesList {
if s.GetName() == *serviceName {
filtered = append(filtered, s)
break
}
}
if len(filtered) == 0 {
log.Fatalf("No se encontró el servicio: %s", *serviceName)
}
servicesList = filtered
log.Printf("Ejecutando solo el servicio: %s", *serviceName)
}
// Crear contexto con cancelación para manejar señales de terminación.
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// Canal para capturar señales del sistema.
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
// Iniciar servidor HTTP si se configura puerto para API.
var httpServer *http.Server
if cfg.API.Port > 0 {
httpServer = api.StartAPIServer(cfg.API.Port, servicesList, servicesList2, false)
}
// Goroutine para manejar señales.
go func() {
sig := <-sigChan
log.Printf("Recibida señal: %v. Cerrando...", sig)
if notifier != nil {
notifier.SendNotification("Servicio detenido", fmt.Sprintf("El servicio fue detenido por la señal: %v", sig))
}
cancel()
if httpServer != nil {
log.Println("Cerrando servidor HTTP...")
shutdownCtx, cancelServer := context.WithTimeout(context.Background(), 10*time.Second)
defer cancelServer()
if err := httpServer.Shutdown(shutdownCtx); err != nil {
log.Printf("Error al cerrar servidor HTTP: %v", err)
}
}
}()
// Si se debe ejecutar solo una vez.
if *runOnce {
errors := services.RunAllServices(ctx, servicesList, false)
if len(errors) > 0 {
for _, e := range errors {
log.Printf("Error: %v", e)
}
os.Exit(1)
}
return
}
// Configurar primer cron
c := cron.New(cron.WithSeconds())
_, err = c.AddFunc(cfg.Schedule.FACTURA_SINCRONIZACION.Cron, func() {
log.Println("Iniciando ejecución programada de servicios")
execCtx, execCancel := context.WithCancel(ctx)
defer execCancel()
errors := services.RunAllServices(execCtx, servicesList, true)
if len(errors) > 0 {
errMsg := "Errores durante la ejecución programada:"
for _, err := range errors {
errMsg += "\n- " + err.Error()
}
if notifier != nil {
notifier.SendNotification("Errores en ejecución programada", errMsg)
}
log.Println(errMsg)
} else {
log.Println("Ejecución programada completada exitosamente")
}
})
if err != nil {
log.Fatalf("Error al programar tareas: %v", err)
}
// Configurar segundo cron
cronGetCode := cron.New(cron.WithSeconds())
_, err = cronGetCode.AddFunc(cfg.Schedule.FACTURA_CODIGO.Cron, func() {
log.Println("Iniciando ejecución programada para Obtener Codigos")
execCtx, cancel := context.WithCancel(context.Background())
defer cancel()
//execCtx, execCancel := context.WithCancel(ctx)
//defer execCancel()
errors := services.RunAllGetCodeServices(execCtx, servicesList2, true)
if len(errors) > 0 {
errMsg := "Errores durante la ejecución programada Obtener Codigos:"
for _, err := range errors {
errMsg += "\n- " + err.Error()
}
if notifier != nil {
notifier.SendNotification("Errores en ejecución programada Obtener Codigos", errMsg)
}
log.Println(errMsg)
} else {
log.Println("Ejecución programada completada exitosamente Obtener Codigos")
}
})
if err != nil {
log.Fatalf("Error al programar tareas Obtener Codigos: %v", err)
}
// Iniciar ambos cron
c.Start()
cronGetCode.Start()
log.Printf("Demonio de servicios iniciado. Programación: %s", cfg.Schedule.FACTURA_SINCRONIZACION.Cron)
log.Printf("Demonio de obtención de códigos iniciado. Programación: %s", cfg.Schedule.FACTURA_CODIGO.Cron)
if notifier != nil {
notifier.SendNotification("Servicios iniciados",
fmt.Sprintf("Los servicios SOAP han sido iniciados con programación: %s", cfg.Schedule.FACTURA_SINCRONIZACION.Cron))
}
// Esperar a que el contexto termine y luego detener ambos cron
<-ctx.Done()
c.Stop()
cronGetCode.Stop()
log.Println("Demonios detenidos correctamente")
}