package com.imprimelibros.erp.presupuesto; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; import java.util.Locale; import java.text.NumberFormat; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.stereotype.Service; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import java.math.BigDecimal; import java.math.RoundingMode; import com.imprimelibros.erp.configurationERP.VariableService; import com.imprimelibros.erp.presupuesto.Presupuesto.TipoCubierta; import com.imprimelibros.erp.presupuesto.classes.ImagenPresupuesto; import com.imprimelibros.erp.presupuesto.classes.PresupuestadorItems; import com.imprimelibros.erp.presupuesto.maquetacion.MaquetacionPrecios; import com.imprimelibros.erp.presupuesto.maquetacion.MaquetacionPreciosRepository; import com.imprimelibros.erp.presupuesto.classes.PresupuestoMaquetacion; import com.imprimelibros.erp.presupuesto.maquetacion.MaquetacionMatrices; import com.imprimelibros.erp.presupuesto.maquetacion.MaquetacionMatricesRepository; import com.imprimelibros.erp.externalApi.skApiClient; @Service public class PresupuestoService { @Autowired protected VariableService variableService; @Autowired protected MessageSource messageSource; @Autowired protected skApiClient skApiClient; @Autowired protected MaquetacionPreciosRepository maquetacionPreciosRepository; @Autowired protected MaquetacionMatricesRepository maquetacionMatricesRepository; private final PresupuestadorItems presupuestadorItems; public PresupuestoService(PresupuestadorItems presupuestadorItems) { this.presupuestadorItems = presupuestadorItems; } public boolean validateDatosGenerales(int[] tiradas) { for (int tirada : tiradas) { if (tirada <= 0) { return false; // Invalid tirada found } } return true; } public Boolean isPOD(Presupuesto presupuesto) { int pod_value = variableService.getValorEntero("POD"); return (presupuesto.getTirada1() != null && presupuesto.getTirada1() <= pod_value) || (presupuesto.getTirada2() != null && presupuesto.getTirada2() <= pod_value) || (presupuesto.getTirada3() != null && presupuesto.getTirada3() <= pod_value) || (presupuesto.getTirada4() != null && presupuesto.getTirada4() <= pod_value); } public Map obtenerOpcionesColor(Presupuesto presupuesto, Locale locale) { List opciones = new ArrayList<>(); if (presupuesto.getPaginasColor() > 0) { if (!this.isPOD(presupuesto)) { // POD solo color foto ImagenPresupuesto opcionColor = this.presupuestadorItems.getImpresionColor(locale); opcionColor.setSelected(Presupuesto.TipoImpresion.color.equals(presupuesto.getTipoImpresion())); opciones.add(opcionColor); } ImagenPresupuesto opcionColorHq = this.presupuestadorItems.getImpresionColorPremium(locale); if (Presupuesto.TipoImpresion.colorhq.equals(presupuesto.getTipoImpresion())) opcionColorHq.setSelected(true); opciones.add(opcionColorHq); } else { ImagenPresupuesto opcionNegro = this.presupuestadorItems.getImpresionNegro(locale); if (Presupuesto.TipoImpresion.negro.equals(presupuesto.getTipoImpresion())) opcionNegro.setSelected(true); opciones.add(opcionNegro); ImagenPresupuesto opcionNegroHq = this.presupuestadorItems.getImpresionNegroPremium(locale); if (Presupuesto.TipoImpresion.negrohq.equals(presupuesto.getTipoImpresion())) opcionNegroHq.setSelected(true); opciones.add(opcionNegroHq); } boolean opcionSeleccionada = opciones.stream().anyMatch(ImagenPresupuesto::isSelected); if (!opcionSeleccionada) { opciones.get(0).setSelected(true); presupuesto.setTipoImpresion(Presupuesto.TipoImpresion.valueOf(opciones.get(0).getId())); } Map response = new HashMap<>(); response.put("opciones_color", opciones); return response; } public Map obtenerOpcionesPapelInterior(Presupuesto presupuesto, Locale locale) { List opciones = new ArrayList<>(); opciones.add(this.presupuestadorItems.getPapelOffsetBlanco(locale)); if (presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.negro || presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.color) { opciones.add(this.presupuestadorItems.getPapelOffsetBlancoVolumen(locale)); } opciones.add(this.presupuestadorItems.getPapelOffsetAhuesado(locale)); if (presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.negro || presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.color) { opciones.add(this.presupuestadorItems.getPapelOffsetAhuesadoVolumen(locale)); } opciones.add(this.presupuestadorItems.getPapelEstucadoMate(locale)); for (ImagenPresupuesto imagenPresupuesto : opciones) { imagenPresupuesto.setSelected( presupuesto.getPapelInteriorId() != null && imagenPresupuesto.getExtra_data().get("sk-id").equals( String.valueOf(presupuesto.getPapelInteriorId()))); } boolean yaSeleccionado = opciones.stream().anyMatch(ImagenPresupuesto::isSelected); if (!yaSeleccionado && !opciones.isEmpty()) { ImagenPresupuesto primeraOpcion = opciones.get(0); primeraOpcion.setSelected(true); presupuesto.setPapelInteriorId(Integer.parseInt(primeraOpcion.getExtra_data().get("sk-id"))); } Map response = new HashMap<>(); response.put("opciones_papel_interior", opciones); return response; } public Map obtenerOpcionesGramajeInterior(Presupuesto presupuesto) { List gramajes = new ArrayList<>(); final int BLANCO_OFFSET_ID = 3; final int BLANCO_OFFSET_VOLUMEN_ID = 7; final int AHUESADO_OFFSET_ID = 4; final int AHUESADO_OFFSET_VOLUMEN_ID = 6; final int ESTUCADO_MATE_ID = 2; if (presupuesto.getPapelInteriorId() != null && presupuesto.getPapelInteriorId() == BLANCO_OFFSET_ID) { gramajes.add("80"); gramajes.add("90"); if (presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.negrohq || presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.colorhq) { gramajes.add("100"); gramajes.add("120"); gramajes.add("150"); gramajes.add("170"); } } else if (presupuesto.getPapelInteriorId() != null && presupuesto.getPapelInteriorId() == BLANCO_OFFSET_VOLUMEN_ID) { if (presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.negro || presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.color) { gramajes.add("80"); } } else if (presupuesto.getPapelInteriorId() != null && presupuesto.getPapelInteriorId() == AHUESADO_OFFSET_ID) { gramajes.add("80"); gramajes.add("90"); if (presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.negrohq || presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.colorhq) { gramajes.add("100"); } } else if (presupuesto.getPapelInteriorId() != null && presupuesto.getPapelInteriorId() == AHUESADO_OFFSET_VOLUMEN_ID) { if (presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.negro || presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.color) { gramajes.add("70"); gramajes.add("80"); } } else if (presupuesto.getPapelInteriorId() != null && presupuesto.getPapelInteriorId() == ESTUCADO_MATE_ID) { if (presupuesto.getTipoImpresion() != Presupuesto.TipoImpresion.color) { gramajes.add("90"); } if (presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.negrohq || presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.colorhq) { gramajes.add("100"); gramajes.add("115"); } if (presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.negro || presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.color) { gramajes.add("120"); } if (presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.negrohq || presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.colorhq) { gramajes.add("125"); gramajes.add("135"); gramajes.add("150"); gramajes.add("170"); gramajes.add("200"); } } Map response = new HashMap<>(); response.put("opciones_gramaje_interior", gramajes); return response; } public Map obtenerOpcionesPapelCubierta(Presupuesto presupuesto, Locale locale) { List opciones = new ArrayList<>(); if (presupuesto.getTipoCubierta() == Presupuesto.TipoCubierta.tapaBlanda) { opciones.add(this.presupuestadorItems.getCartulinaGraficaCubierta(locale)); } opciones.add(this.presupuestadorItems.getEstucadoMateCubierta(locale)); for (ImagenPresupuesto imagenPresupuesto : opciones) { imagenPresupuesto.setSelected( presupuesto.getPapelCubiertaId() != null && imagenPresupuesto.getExtra_data().get("sk-id").equals( String.valueOf(presupuesto.getPapelCubiertaId()))); } Map response = new HashMap<>(); response.put("opciones_papel_cubierta", opciones); return response; } public Map obtenerOpcionesGramajeCubierta(Presupuesto presupuesto) { List gramajes = new ArrayList<>(); final int CARTULINA_GRAFICA_ID = 5; final int ESTUCADO_MATE_ID = 2; if (presupuesto.getPapelCubiertaId() != null && presupuesto.getPapelCubiertaId() == CARTULINA_GRAFICA_ID) { gramajes.add("240"); gramajes.add("270"); gramajes.add("300"); gramajes.add("350"); } else if (presupuesto.getPapelCubiertaId() != null && presupuesto.getPapelCubiertaId() == ESTUCADO_MATE_ID) { if (presupuesto.getTipoCubierta() == Presupuesto.TipoCubierta.tapaBlanda) { gramajes.add("250"); gramajes.add("300"); gramajes.add("350"); } else { gramajes.add("170"); } } Map response = new HashMap<>(); response.put("opciones_gramaje_cubierta", gramajes); return response; } public Map toSkApiRequest(Presupuesto presupuesto) { final int SK_CLIENTE_ID = 1284; final int SK_PAGINAS_CUADERNILLO = 32; Map tamanio = Map.of( "ancho", presupuesto.getAncho(), "alto", presupuesto.getAlto()); Map interior = Map.of( "papelInterior", presupuesto.getPapelInteriorId(), "gramajeInterior", presupuesto.getGramajeInterior()); Map cubierta = Map.of( "tipoCubierta", presupuesto.getTipoCubierta().name(), "papelCubierta", presupuesto.getPapelCubiertaId(), "gramajeCubierta", presupuesto.getGramajeCubierta(), "carasImpresion", presupuesto.getCubiertaCaras(), "solapas", presupuesto.getSolapasCubierta() ? presupuesto.getTamanioSolapasCubierta() : 0, "acabado", presupuesto.getAcabado(), "cabezada", presupuesto.getCabezada(), "lomoRedondo", presupuesto.getTipoCubierta() == TipoCubierta.tapaDuraLomoRedondo ? 1 : 0); /* * Map servicios = Map.of( * "retractilado", 0, * "retractilado5", 0, * "ferro", 0, * "ferroDigital", 0, * "marcapaginas", 0, * "prototipo", 0); */ Map body = new HashMap<>(); body.put("tipo_impresion_id", this.getTipoImpresionId(presupuesto)); body.put("tirada", Arrays.stream(presupuesto.getTiradas()) .filter(Objects::nonNull) .collect(Collectors.toList())); body.put("tamanio", tamanio); body.put("tipo", presupuesto.getTipoEncuadernacion()); body.put("clienteId", SK_CLIENTE_ID); body.put("isColor", presupuesto.getTipoImpresion().name().contains("color") ? 1 : 0); body.put("isHq", presupuesto.getTipoImpresion().name().contains("hq") ? 1 : 0); body.put("paginas", presupuesto.getPaginasNegro() + presupuesto.getPaginasColor()); body.put("paginasColor", presupuesto.getPaginasColor()); body.put("paginasCuadernillo", SK_PAGINAS_CUADERNILLO); body.put("interior", interior); body.put("cubierta", cubierta); body.put("guardas", null); if (presupuesto.getSobrecubierta()) { Map sobrecubierta = new HashMap<>(); sobrecubierta.put("papel", presupuesto.getPapelSobrecubiertaId()); sobrecubierta.put("gramaje", presupuesto.getGramajeSobrecubierta()); sobrecubierta.put("solapas", presupuesto.getTamanioSolapasSobrecubierta()); sobrecubierta.put("acabado", presupuesto.getAcabadoSobrecubierta()); body.put("sobrecubierta", sobrecubierta); } if (presupuesto.getFaja()) { Map faja = new HashMap<>(); faja.put("papel", presupuesto.getPapelFajaId()); faja.put("gramaje", presupuesto.getGramajeFaja()); faja.put("solapas", presupuesto.getTamanioSolapasFaja()); faja.put("acabado", presupuesto.getAcabadoFaja()); faja.put("alto", presupuesto.getAltoFaja()); body.put("faja", faja); } // body.put("servicios", servicios); return body; } public Integer getTipoImpresionId(Presupuesto presupuesto) { if (presupuesto.getTipoEncuadernacion() == Presupuesto.TipoEncuadernacion.fresado) { if (presupuesto.getTipoCubierta() == Presupuesto.TipoCubierta.tapaDura || presupuesto.getTipoCubierta() == Presupuesto.TipoCubierta.tapaDuraLomoRedondo) { return 1; // Fresado tapa dura } else { return 2; // Fresado tapa blanda } } else if (presupuesto.getTipoEncuadernacion() == Presupuesto.TipoEncuadernacion.cosido) { if (presupuesto.getTipoCubierta() == Presupuesto.TipoCubierta.tapaDura || presupuesto.getTipoCubierta() == Presupuesto.TipoCubierta.tapaDuraLomoRedondo) { return 3; // Cosido tapa dura } else { return 4; // Cosido tapa blanda } } else if (presupuesto.getTipoEncuadernacion() == Presupuesto.TipoEncuadernacion.espiral) { if (presupuesto.getTipoCubierta() == Presupuesto.TipoCubierta.tapaDura || presupuesto.getTipoCubierta() == Presupuesto.TipoCubierta.tapaDuraLomoRedondo) { return 5; // Espiral tapa dura } else { return 6; // Espiral tapa blanda } } else if (presupuesto.getTipoEncuadernacion() == Presupuesto.TipoEncuadernacion.wireo) { if (presupuesto.getTipoCubierta() == Presupuesto.TipoCubierta.tapaDura || presupuesto.getTipoCubierta() == Presupuesto.TipoCubierta.tapaDuraLomoRedondo) { return 7; // Wireo tapa dura } else { return 8; // Wireo tapa blanda } } else if (presupuesto.getTipoEncuadernacion() == Presupuesto.TipoEncuadernacion.grapado) { return 21; // Grapado } else { return 0; // Default case, no valid type } } public Map obtenerOpcionesAcabadosCubierta(Presupuesto presupuesto, Locale locale) { Map resultado = new HashMap<>(); List opciones = new ArrayList<>(); opciones.add(new HashMap<>() { { put("name", messageSource.getMessage("presupuesto.acabado-ninguno", null, locale)); put("sk-id", 0); } }); opciones.add(new HashMap<>() { { put("name", messageSource.getMessage("presupuesto.acabado-plastificado-brillo-1c", null, locale)); put("sk-id", 1); } }); opciones.add(new HashMap<>() { { put("name", messageSource.getMessage("presupuesto.acabado-plastificado-mate-1c", null, locale)); put("sk-id", 5); } }); opciones.add(new HashMap<>() { { put("name", messageSource.getMessage("presupuesto.acabado-plastificado-mate-1c-antirrayado", null, locale)); put("sk-id", 8); } }); opciones.add(new HashMap<>() { { put("name", messageSource.getMessage("presupuesto.acabado-plastificado-mate-uvi", null, locale)); put("sk-id", 2); } }); opciones.add(new HashMap<>() { { put("name", messageSource.getMessage("presupuesto.acabado-plastificado-mate-uvi3d", null, locale)); put("sk-id", 3); } }); opciones.add(new HashMap<>() { { put("name", messageSource.getMessage("presupuesto.acabado-plastificado-mate-uvi-braile", null, locale)); put("sk-id", 4); } }); opciones.add(new HashMap<>() { { put("name", messageSource.getMessage("presupuesto.acabado-plastificado-sandy-1c", null, locale)); put("sk-id", 9); } }); resultado.put("opciones_acabados_cubierta", opciones); return resultado; } public Map aplicarMargenTiradas(Map data) { // implementar margenes return (Map) data; } public String obtenerPrecioRetractilado(Presupuesto presupuesto, Locale locale) { Integer[] tiradas = presupuesto.getTiradas(); Integer tirada_min = Arrays.stream(tiradas) .filter(Objects::nonNull) .min(Integer::compareTo) .orElse(0); Map requestBody = new HashMap<>(); requestBody.put("tirada", presupuesto.getSelectedTirada() != null ? presupuesto.getSelectedTirada() : tirada_min); Double precio_retractilado = skApiClient.getRetractilado(requestBody); return precio_retractilado != null ? NumberFormat.getNumberInstance(locale) .format(Math.round(precio_retractilado * 100.0) / 100.0) : "0,00"; } public Map obtenerServiciosExtras(Presupuesto presupuesto, Locale locale, skApiClient apiClient) { List opciones = new ArrayList<>(); Double price_prototipo = this.obtenerPrototipo(presupuesto, apiClient); opciones.add(new HashMap() { { put("id", "retractilado"); put("title", messageSource.getMessage("presupuesto.extras-retractilado", null, locale)); put("description", ""); put("price", obtenerPrecioRetractilado(presupuesto, locale)); put("priceUnit", messageSource.getMessage("app.currency-symbol", null, locale)); } }); opciones.add(new HashMap() { { put("id", "service-isbn"); put("title", messageSource.getMessage("presupuesto.extras-isbn", null, locale)); put("description", ""); put("price", "30"); put("priceUnit", messageSource.getMessage("app.currency-symbol", null, locale)); } }); opciones.add(new HashMap() { { put("id", "deposito-legal"); put("title", messageSource.getMessage("presupuesto.extras-deposito-legal", null, locale)); put("description", messageSource.getMessage("presupuesto.extras-deposito-legal-descripcion", null, locale)); put("price", "30"); put("priceUnit", messageSource.getMessage("app.currency-symbol", null, locale)); } }); opciones.add(new HashMap() { { put("id", "revision-archivos"); put("title", messageSource.getMessage("presupuesto.extras-revision-archivos", null, locale)); put("description", ""); put("price", "50"); put("priceUnit", messageSource.getMessage("app.currency-symbol", null, locale)); } }); opciones.add(new HashMap() { { put("id", "maquetacion-cubierta"); put("title", messageSource.getMessage("presupuesto.extras-maquetacion-cubierta", null, locale)); put("description", ""); put("price", "50"); put("priceUnit", messageSource.getMessage("app.currency-symbol", null, locale)); } }); opciones.add(new HashMap() { { put("id", "ferro-digital"); put("title", messageSource.getMessage("presupuesto.extras-ferro-digital", null, locale)); put("description", ""); put("price", "0"); put("priceUnit", messageSource.getMessage("app.currency-symbol", null, locale)); put("checked", "true"); put("allowChange", "false"); put("ribbonText", messageSource.getMessage("presupuesto.extras-ferro-digital-ribbon", null, locale)); } }); opciones.add(new HashMap() { { put("id", "ejemplar-prueba"); put("title", messageSource.getMessage("presupuesto.extras-ejemplar-prueba", null, locale)); put("description", ""); if (price_prototipo == 0.0) { put("price", messageSource.getMessage("presupuesto.consultar-soporte", null, locale)); put("priceUnit", ""); } else { put("price", NumberFormat.getNumberInstance(locale) .format(Math.round(price_prototipo * 100.0) / 100.0)); put("priceUnit", messageSource.getMessage("app.currency-symbol", null, locale)); } } }); opciones.add(new HashMap() { { put("id", "marcapaginas"); put("title", messageSource.getMessage("presupuesto.extras-marcapaginas", null, locale)); put("description", ""); put("price", messageSource.getMessage("presupuesto.extras-calcular", null, locale)); } }); opciones.add(new HashMap() { { put("id", "maquetacion"); put("title", messageSource.getMessage("presupuesto.extras-maquetacion", null, locale)); put("description", ""); put("price", messageSource.getMessage("presupuesto.extras-calcular", null, locale)); } }); Map response = new HashMap<>(); response.put("servicios_extra", opciones); return response; } private Double obtenerPrototipo(Presupuesto presupuesto, skApiClient apiClient) { // Obtenemos el precio de 1 unidad para el ejemplar de prueba HashMap price = new HashMap<>(); // make a copy of "presupuesto" to avoid modifying the original object Presupuesto presupuestoTemp = presupuesto.clone(); presupuestoTemp.setTirada1(1); presupuestoTemp.setTirada2(null); presupuestoTemp.setTirada3(null); presupuestoTemp.setTirada4(null); if (presupuestoTemp.getTipoImpresion() == Presupuesto.TipoImpresion.color) { presupuestoTemp.setTipoImpresion(Presupuesto.TipoImpresion.colorhq); } else if (presupuestoTemp.getTipoImpresion() == Presupuesto.TipoImpresion.negro) { presupuestoTemp.setTipoImpresion(Presupuesto.TipoImpresion.negrohq); } String priceStr = apiClient.getPrice(this.toSkApiRequest(presupuestoTemp)); Double price_prototipo = 0.0; try { price = new ObjectMapper().readValue(priceStr, new TypeReference<>() { }); price_prototipo = ((List) ((Map) price.get("data")).get("precios")).get(0); if (price_prototipo < 25) { price_prototipo = 25.0; } } catch (JsonProcessingException e) { } catch (Exception exception) { } return price_prototipo; } public HashMap getPrecioMaquetacion(PresupuestoMaquetacion presupuestoMaquetacion, Locale locale) { try { List lista = maquetacionPreciosRepository.findAll(); // helper para obtener un precio por clave java.util.function.Function price = key -> lista.stream() .filter(p -> key.equals(p.getKey())) .map(MaquetacionPrecios::getValue) .findFirst() .orElse(0.0); BigDecimal precio = BigDecimal.ZERO; // millar_maquetacion * (numCaracteres / 1000.0) BigDecimal millares = BigDecimal.valueOf(presupuestoMaquetacion.getNumCaracteres()).divide(BigDecimal.valueOf(1000), 6, RoundingMode.HALF_UP); precio = precio.add(millares.multiply(BigDecimal.valueOf(price.apply("millar_maquetacion")))); // Numero de paginas estimado int numPaginas = 0; Integer matricesPorPagina = maquetacionMatricesRepository.findMatrices( presupuestoMaquetacion.getFormato(), presupuestoMaquetacion.getCuerpoTexto()); if (matricesPorPagina != null && matricesPorPagina > 0) { numPaginas = presupuestoMaquetacion.getNumCaracteres() / matricesPorPagina; } // Precio por pagina estimado BigDecimal precioRedondeado = precio.setScale(2, RoundingMode.HALF_UP); double precioPaginaEstimado = 0.0; if (numPaginas > 0) { precioPaginaEstimado = precioRedondeado .divide(BigDecimal.valueOf(numPaginas), 2, RoundingMode.HALF_UP) .doubleValue(); } // tabla, columna, foto precio = precio .add(BigDecimal.valueOf(presupuestoMaquetacion.getNumTablas()).multiply(BigDecimal.valueOf(price.apply("tabla")))); precio = precio.add( BigDecimal.valueOf(presupuestoMaquetacion.getNumColumnas()).multiply(BigDecimal.valueOf(price.apply("columnas")))); precio = precio .add(BigDecimal.valueOf(presupuestoMaquetacion.getNumFotos()).multiply(BigDecimal.valueOf(price.apply("foto")))); if (presupuestoMaquetacion.isCorreccionOrtotipografica()) { precio = precio .add(millares.multiply(BigDecimal.valueOf(price.apply("correccion_ortotipografica")))); } if (presupuestoMaquetacion.isTextoMecanografiado()) { precio = precio.add(millares.multiply(BigDecimal.valueOf(price.apply("mecanoescritura_por_millar")))); } if (presupuestoMaquetacion.isDisenioPortada()) { precio = precio.add(BigDecimal.valueOf(price.apply("disenio_portada"))); } if (presupuestoMaquetacion.isEpub()) { precio = precio.add(BigDecimal.valueOf(price.apply("epub"))); } // redondeo final precioRedondeado = precio.setScale(2, RoundingMode.HALF_UP); HashMap out = new HashMap<>(); out.put("precio", precioRedondeado.doubleValue()); out.put("numPaginasEstimadas", numPaginas); out.put("precioPaginaEstimado", precioPaginaEstimado); HashMap language = new HashMap<>(); language.put("add_to_presupuesto", messageSource.getMessage("presupuesto.add-to-presupuesto", null, locale)); language.put("cancel", messageSource.getMessage("app.cancelar", null, locale)); language.put("presupuesto_maquetacion", messageSource.getMessage("presupuesto.maquetacion", null, locale)); out.put("language", language); return out; } catch (Exception e) { System.out.println("Error procesando presupuesto maquetacion: " + e.getMessage()); } HashMap out = new HashMap<>(); out.put("precio", 0.0); out.put("numPaginasEstimadas", 0); out.put("precioPaginaEstimado", 0.0); return out; } }