// service/cuis_service.go package services import ( "context" "daemonService/internal/models/obtencionCodigos" "daemonService/internal/models/obtencionCodigos/request" "daemonService/internal/utils" "database/sql" "fmt" "log" "strconv" ) type CuisService struct { Model obtencionCodigos.CuisServiceModel Logger *log.Logger } // En services/cuis_service.go func NewCuisService( model obtencionCodigos.CuisServiceModel, logger *log.Logger, ) *CuisService { return &CuisService{Model: model, Logger: logger} } // GetName retorna el nombre del servicio func (s *CuisService) GetName() string { return s.Model.Name } // logMessage registra un mensaje con el prefijo del servicio func (s *CuisService) LogMessage(format string, v ...interface{}) { if s.Logger != nil { s.Logger.Printf(format, v...) } } // registra un error y devuelve el mismo error func (s *CuisService) LogError(format string, err error, v ...interface{}) error { args := append([]interface{}{err}, v...) if s.Logger != nil { s.Logger.Printf(format, args...) } return fmt.Errorf(format, args...) } // crea una solicitud CUIS a partir de datos de empresa func (s *CuisService) BuildCuisRequestFromEmpresa(ec obtencionCodigos.EmpresaConCuis) request.SolicitudCuisCufd { return request.SolicitudCuisCufd{ CodigoAmbiente: strconv.Itoa(ec.CodigoAmbiente), CodigoModalidad: strconv.Itoa(ec.CodigoModalidad), CodigoPuntoVenta: strconv.Itoa(ec.CodigoPuntoVenta), CodigoSistema: ec.CodigoSistema, CodigoSucursal: strconv.Itoa(ec.CodigoSucursal), Nit: ec.Nit, KeyToken: ec.TokenKey, ValueToken: ec.TokenValue, NombreArchivoClavePrivada: ec.NombreArchivoClavePrivada, NombreArchivoCertificado: ec.NombreArchivoCertificado, } } // actualiza un registro existente de empresa y CUIS func (s *CuisService) actualizarRegistro(ctx context.Context, empresaID int, cuisID int64, req request.SolicitudCuisCufd, respRaw interface{}) error { currentBolivia, err := utils.GetCurrentBoliviaTime() if err != nil { return err } // 1. Iniciar tx tx, err := s.Model.DB.BeginTx(ctx, nil) if err != nil { return fmt.Errorf("iniciar transacción: %w", err) } defer tx.Rollback() // 2. Parsear respuesta nuevoCuis, fechaVigencia, _, err := utils.ParseSoapCuisResponse(respRaw) if err != nil { return err } // 3. Actualizar empresa _, err = tx.ExecContext(ctx, ` UPDATE registroEmpresa SET codigo_ambiente=$1, codigo_modalidad=$2, codigo_punto_venta=$3, codigo_sistema=$4, codigo_sucursal=$5, nit=$6, fecha_actualizacion=$7 WHERE id=$8 `, req.CodigoAmbiente, req.CodigoModalidad, req.CodigoPuntoVenta, req.CodigoSistema, req.CodigoSucursal, req.Nit, currentBolivia, empresaID, ) if err != nil { return fmt.Errorf("actualizar registroEmpresa: %w", err) } // 4. Comprobar si hay un CUIS existente var existingCuis string err = tx.QueryRowContext(ctx, `SELECT cuis FROM cuis WHERE id=$1 AND registro_empresa_id=$2`, cuisID, empresaID).Scan(&existingCuis) if err != nil && err != sql.ErrNoRows { return fmt.Errorf("consultar cuis existente: %w", err) } // 5. Insertar o actualizar if err == sql.ErrNoRows { _, err = tx.ExecContext(ctx, `INSERT INTO cuis (registro_empresa_id, cuis) VALUES ($1, $2)`, empresaID, nuevoCuis) if err != nil { return fmt.Errorf("insertar nuevo cuis: %w", err) } } else if existingCuis != nuevoCuis { _, err = tx.ExecContext(ctx, `UPDATE cuis SET cuis=$1, fecha_vigencia=$2, fecha_actualizacion=$3 WHERE id=$4`, nuevoCuis, fechaVigencia, currentBolivia, cuisID) if err != nil { return fmt.Errorf("actualizar cuis existente: %w", err) } } // 6. Confirmar tx if err := tx.Commit(); err != nil { return fmt.Errorf("confirmar transacción: %w", err) } return nil }