añadidos los ficheros nuevos2

This commit is contained in:
Jaime Jiménez
2025-08-05 10:07:04 +02:00
parent e7589de194
commit 3f89f323cf
3 changed files with 250 additions and 0 deletions

View File

@ -0,0 +1,41 @@
package com.imprimelibros.erp.externalApi;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
@Service
public class AuthService {
@Value("${safekat.api.url}")
private String skApiUrl;
@Value("${safekat.api.email}")
private String skApiEmail;
@Value("${safekat.api.password}")
private String skApiPassword;
private final RestTemplate restTemplate = new RestTemplate();
private String currentToken;
public synchronized String getToken() {
if (currentToken == null) {
currentToken = fetchNewToken();
}
return currentToken;
}
public synchronized void invalidateToken() {
currentToken = null;
}
private String fetchNewToken() {
Map<String, String> credentials = Map.of(
"email", this.skApiEmail,
"password", this.skApiPassword);
ResponseEntity<Map> response = restTemplate.postForEntity(this.skApiUrl + "auth/jwt", credentials, Map.class);
return (String) response.getBody().get("access_token");
}
}

View File

@ -0,0 +1,127 @@
package com.imprimelibros.erp.externalApi;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
import java.util.HashMap;
import java.util.function.Supplier;
import java.util.List;
@Service
public class skApiClient {
@Value("${safekat.api.url}")
private String skApiUrl;
private final AuthService authService;
private final RestTemplate restTemplate;
public skApiClient(AuthService authService) {
this.authService = authService;
this.restTemplate = new RestTemplate();
}
public String getPrice(Map<String, Object> requestBody) {
return performWithRetry(() -> {
String url = this.skApiUrl + "api/calcular";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setBearerAuth(authService.getToken());
HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);
ResponseEntity<String> response = restTemplate.exchange(
url,
HttpMethod.POST,
entity,
String.class);
return response.getBody();
});
}
public Integer getMaxSolapas(Map<String, Object> requestBody) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setBearerAuth(authService.getToken());
Map<String, Object> request = new HashMap<>(requestBody);
Map<String, Object> data = new HashMap<>();
try {
String jsonResponse = performWithRetry(() -> {
String url = this.skApiUrl + "api/calcular-solapas";
data.put("clienteId", request.get("clienteId"));
data.put("tamanio", (Map<String, Object>) request.get("tamanio"));
data.put("tirada", requestBody.get("tirada"));
data.put("paginas", request.get("paginas"));
data.put("paginasColor", request.get("paginasColor"));
data.put("papelInteriorDiferente", 0);
data.put("paginasCuadernillo", request.get("paginasCuadernillo"));
data.put("tipo", request.get("tipo"));
data.put("isColor", request.get("isColor"));
data.put("isHq", request.get("isHq"));
data.put("interior", request.get("interior"));
HttpEntity<Map<String, Object>> entity = new HttpEntity<>(data, headers);
ResponseEntity<String> response = restTemplate.exchange(
url,
HttpMethod.POST,
entity,
String.class);
return response.getBody();
});
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(jsonResponse);
if (root.get("data") == null || !root.get("data").isInt()) {
throw new RuntimeException("Respuesta inesperada de calcular-solapas: " + jsonResponse);
}
int solapas = root.get("data").asInt();
return solapas;
} catch (JsonProcessingException e) {
// No se puede calcular el interior, por lo que las solapas seran el 80% del
// ancho
Map<String, Object> tamanio = (Map<String, Object>)data.get("tamanio");
if (tamanio == null || tamanio.get("ancho") == null)
throw new RuntimeException("Tamaño no válido en la solicitud: " + data);
else {
int ancho = (int) tamanio.get("ancho");
return (int) Math.floor(ancho * 0.8); // 80% del ancho
}
}
}
/******************
* PRIVATE METHODS
******************/
private String performWithRetry(Supplier<String> request) {
try {
return request.get();
} catch (HttpClientErrorException.Unauthorized e) {
// Token expirado, renovar y reintentar
authService.invalidateToken();
try {
return request.get(); // segundo intento
} catch (HttpClientErrorException ex) {
throw new RuntimeException("La autenticación ha fallado tras renovar el token.", ex);
}
}
}
}

View File

@ -0,0 +1,82 @@
package com.imprimelibros.erp;
import static org.junit.jupiter.api.Assertions.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.imprimelibros.erp.externalApi.skApiClient;
@SpringBootTest
class skApiClientTest {
@Autowired
private skApiClient apiClient;
@Test
void testPrecioCalculadoDevuelveJson() {
String resultado = this.test();
System.out.println("📦 Resultado de la API:");
System.out.println(resultado);
assertNotNull(resultado, "El resultado no debe ser null");
assertTrue(resultado.trim().startsWith("{"), "El resultado debe comenzar con { (JSON)");
assertTrue(resultado.trim().endsWith("}"), "El resultado debe terminar con } (JSON)");
}
public String test() {
Map<String, Object> tamanio = Map.of("ancho", 148, "alto", 210);
Map<String, Object> interior = Map.of("papelInterior", "3", "gramajeInterior", 90);
Map<String, Object> cubierta = Map.of(
"tipoCubierta", "tapaBlanda",
"papelCubierta", "2",
"gramajeCubierta", 300,
"carasImpresion", 2,
"solapas", 0,
"acabado", "1",
"cabezada", "WHI",
"lomoRedondo", 0);
// ✅ Corregido: usamos HashMap porque Map.of no permite null
Map<String, Object> sobrecubierta = new HashMap<>();
sobrecubierta.put("papel", "2");
sobrecubierta.put("gramaje", 170);
sobrecubierta.put("solapas", 80);
sobrecubierta.put("acabado", null);
Map<String, Object> servicios = Map.of(
"retractilado", 0,
"retractilado5", 0,
"ferro", 0,
"ferroDigital", 0,
"marcapaginas", 0,
"prototipo", 0);
Map<String, Object> body = new HashMap<>();
body.put("tirada", List.of(50, 100, 150, 500));
body.put("tamanio", tamanio);
body.put("tipo", "fresado");
body.put("clienteId", 1284);
body.put("isColor", 1);
body.put("isHq", 0);
body.put("paginas", 112);
body.put("paginasColor", 80);
body.put("paginasCuadernillo", 32);
body.put("interior", interior);
body.put("cubierta", cubierta);
body.put("sobrecubierta", sobrecubierta);
body.put("guardas", null);
body.put("faja", false);
body.put("servicios", servicios);
return apiClient.getPrice(body);
}
}