diff --git a/src/main/java/com/imprimelibros/erp/cart/CartController.java b/src/main/java/com/imprimelibros/erp/cart/CartController.java index 1741ddd..a73c9b9 100644 --- a/src/main/java/com/imprimelibros/erp/cart/CartController.java +++ b/src/main/java/com/imprimelibros/erp/cart/CartController.java @@ -10,6 +10,7 @@ import org.springframework.security.core.Authentication; import java.security.Principal; +import java.util.Locale; @Controller @RequestMapping("/cart") @@ -46,15 +47,15 @@ public class CartController { /** Vista del carrito */ @GetMapping - public String viewCart(Model model, Principal principal) { - var items = service.listItems(currentUserId(principal)); + public String viewCart(Model model, Principal principal, Locale locale) { + var items = service.listItems(currentUserId(principal), locale); model.addAttribute("items", items); return "imprimelibros/cart/cart"; // crea esta vista si quieres (tabla simple) } /** Añadir presupuesto via POST form */ @PostMapping("/add") - public String add(@RequestParam("presupuestoId") Long presupuestoId, Principal principal) { + public String add(@PathVariable(name = "presupuestoId", required = true) Long presupuestoId, Principal principal) { service.addPresupuesto(currentUserId(principal), presupuestoId); return "redirect:/cart"; } diff --git a/src/main/java/com/imprimelibros/erp/cart/CartService.java b/src/main/java/com/imprimelibros/erp/cart/CartService.java index 155f8f4..64ff257 100644 --- a/src/main/java/com/imprimelibros/erp/cart/CartService.java +++ b/src/main/java/com/imprimelibros/erp/cart/CartService.java @@ -1,19 +1,45 @@ package com.imprimelibros.erp.cart; +import jakarta.mail.Message; import jakarta.transaction.Transactional; + +import org.springframework.context.MessageSource; import org.springframework.stereotype.Service; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Locale; +import java.util.Map; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.imprimelibros.erp.presupuesto.classes.PresupuestoFormatter; +import com.imprimelibros.erp.presupuesto.dto.Presupuesto; +import com.imprimelibros.erp.presupuesto.PresupuestoRepository; +import com.imprimelibros.erp.presupuesto.service.PresupuestoService; + @Service public class CartService { private final CartRepository cartRepo; private final CartItemRepository itemRepo; + private final MessageSource messageSource; + private final PresupuestoFormatter presupuestoFormatter; + private final PresupuestoRepository presupuestoRepo; - public CartService(CartRepository cartRepo, CartItemRepository itemRepo) { + public CartService(CartRepository cartRepo, CartItemRepository itemRepo, + MessageSource messageSource, PresupuestoFormatter presupuestoFormatter, + PresupuestoRepository presupuestoRepo) { this.cartRepo = cartRepo; this.itemRepo = itemRepo; + this.messageSource = messageSource; + this.presupuestoFormatter = presupuestoFormatter; + this.presupuestoRepo = presupuestoRepo; } /** Devuelve el carrito activo o lo crea si no existe. */ @@ -30,9 +56,21 @@ public class CartService { /** Lista items (presupuestos) del carrito activo del usuario. */ @Transactional - public List listItems(Long userId) { + public List> listItems(Long userId, Locale locale) { Cart cart = getOrCreateActiveCart(userId); - return itemRepo.findByCartId(cart.getId()); + List> resultados = new ArrayList<>(); + List items = itemRepo.findByCartId(cart.getId()); + for (CartItem item : items) { + + Presupuesto p = presupuestoRepo.findById(item.getPresupuestoId()) + .orElseThrow(() -> new IllegalStateException("Presupuesto no encontrado: " + item.getPresupuestoId())); + + this.getElementoCart(p, locale); + Map elemento = getElementoCart(p, locale); + resultados.add(elemento); + } + System.out.println("Cart items: " + resultados); + return resultados; } /** Añade un presupuesto al carrito. Si ya está, no hace nada (idempotente). */ @@ -86,4 +124,73 @@ public class CartService { Cart cart = getOrCreateActiveCart(userId); return itemRepo.findByCartId(cart.getId()).size(); } + + private Map getElementoCart(Presupuesto presupuesto, Locale locale) { + + Map resumen = new HashMap<>(); + + resumen.put("titulo", presupuesto.getTitulo()); + + resumen.put("imagen", + "/assets/images/imprimelibros/presupuestador/" + presupuesto.getTipoEncuadernacion() + ".png"); + resumen.put("imagen_alt", + messageSource.getMessage("presupuesto." + presupuesto.getTipoEncuadernacion(), null, locale)); + + resumen.put("presupuestoId", presupuesto.getId()); + + ObjectMapper mapper = new ObjectMapper(); + List> servicios = new ArrayList<>(); + if (presupuesto.getServiciosJson() != null && !presupuesto.getServiciosJson().isBlank()) + try{ + servicios = mapper.readValue(presupuesto.getServiciosJson(), new TypeReference<>() { + }); + } catch (JsonProcessingException e) { + // Manejar la excepción + } + + boolean hayDepositoLegal = servicios != null && servicios.stream() + .map(m -> java.util.Objects.toString(m.get("id"), "")) + .map(String::trim) + .anyMatch("deposito-legal"::equals); + + List> lineas = new ArrayList<>(); + HashMap linea = new HashMap<>(); + Double precio_unitario = 0.0; + Double precio_total = 0.0; + linea.put("descripcion", presupuestoFormatter.resumen(presupuesto, servicios, locale)); + linea.put("cantidad", presupuesto.getSelectedTirada() != null ? presupuesto.getSelectedTirada() : 0); + precio_unitario = (presupuesto.getPrecioUnitario() != null ? presupuesto.getPrecioUnitario().doubleValue() : 0.0); + precio_total = (presupuesto.getPrecioTotalTirada() != null ? presupuesto.getPrecioTotalTirada().doubleValue() : 0.0); + linea.put("precio_unitario", precio_unitario); + linea.put("precio_total", BigDecimal.valueOf(precio_total).setScale(2, RoundingMode.HALF_UP)); + lineas.add(linea); + + if (hayDepositoLegal) { + linea = new HashMap<>(); + linea.put("descripcion", messageSource.getMessage("presupuesto.resumen-deposito-legal", null, locale)); + linea.put("cantidad", 4); + linea.put("precio_unitario", precio_unitario); + linea.put("precio_total", BigDecimal.valueOf(precio_unitario * 4).setScale(2, RoundingMode.HALF_UP)); + lineas.add(linea); + } + + List> serviciosExtras = new ArrayList<>(); + if (servicios != null) { + for (Map servicio : servicios) { + HashMap servicioData = new HashMap<>(); + servicioData.put("id", servicio.get("id")); + servicioData.put("descripcion", servicio.get("label")); + servicioData.put("precio", servicio.get("id").equals("marcapaginas") + ? Double.parseDouble(servicio.get("price").toString()) + / Double.parseDouble(servicio.get("units").toString()) + : servicio.get("price")); + servicioData.put("unidades", servicio.get("units")); + serviciosExtras.add(servicioData); + } + } + resumen.put("lineas", lineas); + resumen.put("servicios", serviciosExtras); + + return resumen; + } } diff --git a/src/main/resources/i18n/cart_en.properties b/src/main/resources/i18n/cart_en.properties new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/main/resources/i18n/cart_en.properties @@ -0,0 +1 @@ + diff --git a/src/main/resources/i18n/cart_es.properties b/src/main/resources/i18n/cart_es.properties new file mode 100644 index 0000000..4897b92 --- /dev/null +++ b/src/main/resources/i18n/cart_es.properties @@ -0,0 +1,4 @@ +cart.title=Cesta de la compra +cart.empty=Tu cesta de la compra está vacía. + +cart.item.presupuesto-numero=Presupuesto # diff --git a/src/main/resources/i18n/presupuesto_es.properties b/src/main/resources/i18n/presupuesto_es.properties index 8d69eaf..796c810 100644 --- a/src/main/resources/i18n/presupuesto_es.properties +++ b/src/main/resources/i18n/presupuesto_es.properties @@ -11,6 +11,7 @@ presupuesto.add-to-presupuesto=Añadir al presupuesto presupuesto.calcular=Calcular presupuesto.add=Añadir presupuesto presupuesto.guardar=Guardar +presupuesto.add-to-cart=Añadir a la cesta presupuesto.nav.presupuestos-cliente=Presupuestos cliente presupuesto.nav.presupuestos-anonimos=Presupuestos anónimos @@ -20,6 +21,7 @@ presupuesto.estado.aceptado=Aceptado presupuesto.estado.modificado=Modificado presupuesto.tabla.id=ID +presupuesto.tabla.numero=Número presupuesto.tabla.titulo=Título presupuesto.tabla.cliente=Cliente presupuesto.tabla.encuadernacion=Encuadernación @@ -100,8 +102,8 @@ presupuesto.offset-blanco-volumen=Offset Blanco Volumen presupuesto.offset-ahuesado=Offset Ahuesado presupuesto.offset-ahuesado-volumen=Offset Ahuesado Volumen presupuesto.estucado-mate=Estucado Mate -presupuesto.volver-datos-generales=Volver a datos generales -presupuesto.continuar-cubierta=Continuar a diseño cubierta +presupuesto.volver-datos-generales=Datos generales +presupuesto.continuar-cubierta=Diseño cubierta # Pestaña cubierta presupuesto.plantilla-cubierta=Plantilla de cubierta @@ -139,8 +141,8 @@ presupuesto.cartulina-grafica=Cartulina gráfica presupuesto.estucado-mate-cubierta=Estucado mate presupuesto.gramaje-cubierta=Gramaje cubierta presupuesto.gramaje-cubierta-descripcion=Seleccione el gramaje para la cubierta -presupuesto.volver-interior=Volver a diseño interior -presupuesto.continuar-seleccion-tirada=Continuar a selección de tirada +presupuesto.volver-interior=Diseño interior +presupuesto.continuar-seleccion-tirada=Selección de tirada presupuesto.offset=Offset presupuesto.estucado=Estucado presupuesto.verjurado=Verjurado @@ -176,8 +178,8 @@ presupuesto.precio-unidad=Precio por unidad presupuesto.seleccionar-tirada=Seleccionar tirada presupuesto.tirada-seleccionada=Seleccionada presupuesto.unidades=UNIDADES -presupuesto.volver-seleccion-tirada=Volver a selección de tirada -presupuesto.continuar-extras-libro=Continuar a extras del libro +presupuesto.volver-seleccion-tirada=Selección de tirada +presupuesto.continuar-extras-libro=Extras del libro presupuesto.error-obtener-precio=No se pudo obtener el precio para los datos introducidos. Por favor, contacte con el soporte técnico. #pestaña extras del libro @@ -195,7 +197,7 @@ presupuesto.extras-marcapaginas=Marcapáginas presupuesto.extras-maquetacion=Maquetación presupuesto.extras-ferro-digital-ribbon=Incluido presupuesto.extras-calcular=Calcular -presupuesto.volver-cubierta=Volver a diseño cubierta +presupuesto.volver-cubierta=Diseño cubierta presupuesto.finalizar=Finalizar presupuesto presupuesto.calcular-presupuesto=Calcular presupuesto presupuesto.consultar-soporte=Consultar con soporte @@ -221,7 +223,7 @@ presupuesto.resumen-texto-end= presupuesto.resumen-texto-sobrecubierta=
  • Sobrecubierta impresa en {0} {1} gr.
    • Acabado {2}
    • Solapas: {3} mm.
  • presupuesto.resumen-texto-faja=
  • Faja impresa en {0} {1} gr. con un alto de {2} mm.
    • Acabado {3}
    • Solapas: {4} mm.
  • presupuesto.resumen-deposito-legal=Ejemplares para el Depósito Legal -presupuesto.volver-extras=Volver a extras +presupuesto.volver-extras=Extras del libro presupuesto.resumen.inicie-sesion=Inicie sesión para continuar presupuesto.resumen.agregar-cesta=Agregar a la cesta diff --git a/src/main/resources/static/assets/js/app.js b/src/main/resources/static/assets/js/app.js index 521d5cc..071a390 100644 --- a/src/main/resources/static/assets/js/app.js +++ b/src/main/resources/static/assets/js/app.js @@ -49,9 +49,118 @@ location.replace(url); // alinea y no deja historial extra } + if (document.getElementById("topnav-hamburger-icon")) { + document.getElementById("topnav-hamburger-icon").addEventListener("click", toggleHamburgerMenu); + } + + window.addEventListener("resize", windowResizeHover); + windowResizeHover(); + initsAlert(); } + function windowResizeHover() { + feather.replace(); + var windowSize = document.documentElement.clientWidth; + if (windowSize < 1025 && windowSize > 767) { + document.body.classList.remove("twocolumn-panel"); + if (sessionStorage.getItem("data-layout") == "twocolumn") { + document.documentElement.setAttribute("data-layout", "twocolumn"); + if (document.getElementById("customizer-layout03")) { + document.getElementById("customizer-layout03").click(); + } + twoColumnMenuGenerate(); + initTwoColumnActiveMenu(); + isCollapseMenu(); + } + if (sessionStorage.getItem("data-layout") == "vertical") { + document.documentElement.setAttribute("data-sidebar-size", "sm"); + } + if (document.querySelector(".hamburger-icon")) { + document.querySelector(".hamburger-icon").classList.add("open"); + } + } else if (windowSize >= 1025) { + document.body.classList.remove("twocolumn-panel"); + if (sessionStorage.getItem("data-layout") == "twocolumn") { + document.documentElement.setAttribute("data-layout", "twocolumn"); + if (document.getElementById("customizer-layout03")) { + document.getElementById("customizer-layout03").click(); + } + twoColumnMenuGenerate(); + initTwoColumnActiveMenu(); + isCollapseMenu(); + } + if (sessionStorage.getItem("data-layout") == "vertical") { + document.documentElement.setAttribute( + "data-sidebar-size", + sessionStorage.getItem("data-sidebar-size") + ); + } + if (document.querySelector(".hamburger-icon")) { + document.querySelector(".hamburger-icon").classList.remove("open"); + } + } else if (windowSize <= 767) { + document.body.classList.remove("vertical-sidebar-enable"); + document.body.classList.add("twocolumn-panel"); + if (sessionStorage.getItem("data-layout") == "twocolumn") { + document.documentElement.setAttribute("data-layout", "vertical"); + hideShowLayoutOptions("vertical"); + isCollapseMenu(); + } + if (sessionStorage.getItem("data-layout") != "horizontal") { + document.documentElement.setAttribute("data-sidebar-size", "lg"); + } + if (document.querySelector(".hamburger-icon")) { + document.querySelector(".hamburger-icon").classList.add("open"); + } + } + + var isElement = document.querySelectorAll("#navbar-nav > li.nav-item"); + Array.from(isElement).forEach(function (item) { + item.addEventListener("click", menuItem.bind(this), false); + item.addEventListener("mouseover", menuItem.bind(this), false); + }); + } + + function menuItem(e) { + if (e.target && e.target.matches("a.nav-link span")) { + if (elementInViewport(e.target.parentElement.nextElementSibling) == false) { + e.target.parentElement.nextElementSibling.classList.add("dropdown-custom-right"); + e.target.parentElement.parentElement.parentElement.parentElement.classList.add("dropdown-custom-right"); + var eleChild = e.target.parentElement.nextElementSibling; + Array.from(eleChild.querySelectorAll(".menu-dropdown")).forEach(function (item) { + item.classList.add("dropdown-custom-right"); + }); + } else if (elementInViewport(e.target.parentElement.nextElementSibling) == true) { + if (window.innerWidth >= 1848) { + var elements = document.getElementsByClassName("dropdown-custom-right"); + while (elements.length > 0) { + elements[0].classList.remove("dropdown-custom-right"); + } + } + } + } + + if (e.target && e.target.matches("a.nav-link")) { + if (elementInViewport(e.target.nextElementSibling) == false) { + e.target.nextElementSibling.classList.add("dropdown-custom-right"); + e.target.parentElement.parentElement.parentElement.classList.add("dropdown-custom-right"); + var eleChild = e.target.nextElementSibling; + Array.from(eleChild.querySelectorAll(".menu-dropdown")).forEach(function (item) { + item.classList.add("dropdown-custom-right"); + }); + } else if (elementInViewport(e.target.nextElementSibling) == true) { + if (window.innerWidth >= 1848) { + var elements = document.getElementsByClassName("dropdown-custom-right"); + while (elements.length > 0) { + elements[0].classList.remove("dropdown-custom-right"); + } + } + } + } + } + + function initsAlert() { var alerts = document.querySelectorAll('.alert.alert-dismissible'); alerts.forEach(function (el) { @@ -67,4 +176,61 @@ } document.addEventListener("DOMContentLoaded", initLanguage); + + + function toggleHamburgerMenu() { + var windowSize = document.documentElement.clientWidth; + + if (windowSize > 767) + document.querySelector(".hamburger-icon").classList.toggle("open"); + + //For collapse horizontal menu + if (document.documentElement.getAttribute("data-layout") === "horizontal") { + document.body.classList.contains("menu") ? document.body.classList.remove("menu") : document.body.classList.add("menu"); + } + + //For collapse vertical menu + if (document.documentElement.getAttribute("data-layout") === "vertical") { + if (windowSize <= 1025 && windowSize > 767) { + document.body.classList.remove("vertical-sidebar-enable"); + document.documentElement.getAttribute("data-sidebar-size") == "sm" ? + document.documentElement.setAttribute("data-sidebar-size", "") : + document.documentElement.setAttribute("data-sidebar-size", "sm"); + } else if (windowSize > 1025) { + document.body.classList.remove("vertical-sidebar-enable"); + document.documentElement.getAttribute("data-sidebar-size") == "lg" ? + document.documentElement.setAttribute("data-sidebar-size", "sm") : + document.documentElement.setAttribute("data-sidebar-size", "lg"); + } else if (windowSize <= 767) { + document.body.classList.add("vertical-sidebar-enable"); + document.documentElement.setAttribute("data-sidebar-size", "lg"); + } + } + + // semibox menu + if (document.documentElement.getAttribute("data-layout") === "semibox") { + if (windowSize > 767) { + // (document.querySelector(".hamburger-icon").classList.contains("open")) ? document.documentElement.setAttribute('data-sidebar-visibility', "show"): ''; + if (document.documentElement.getAttribute('data-sidebar-visibility') == "show") { + document.documentElement.getAttribute("data-sidebar-size") == "lg" ? + document.documentElement.setAttribute("data-sidebar-size", "sm") : + document.documentElement.setAttribute("data-sidebar-size", "lg"); + } else { + document.getElementById("sidebar-visibility-show").click(); + document.documentElement.setAttribute("data-sidebar-size", document.documentElement.getAttribute("data-sidebar-size")); + } + } else if (windowSize <= 767) { + document.body.classList.add("vertical-sidebar-enable"); + document.documentElement.setAttribute("data-sidebar-size", "lg"); + } + } + + //Two column menu + if (document.documentElement.getAttribute("data-layout") == "twocolumn") { + document.body.classList.contains("twocolumn-panel") ? + document.body.classList.remove("twocolumn-panel") : + document.body.classList.add("twocolumn-panel"); + } + } + })(); diff --git a/src/main/resources/static/assets/js/pages/imprimelibros/presupuestador/wizard.js b/src/main/resources/static/assets/js/pages/imprimelibros/presupuestador/wizard.js index 1234501..3daadfb 100644 --- a/src/main/resources/static/assets/js/pages/imprimelibros/presupuestador/wizard.js +++ b/src/main/resources/static/assets/js/pages/imprimelibros/presupuestador/wizard.js @@ -33,7 +33,7 @@ export default class PresupuestoWizard { paginasColor: 0, posicionPaginasColor: '', tipoEncuadernacion: 'fresado', - entregaTipo: 'peninsula', + entregaTipo: 'peninsula', ivaReducido: true, }, interior: { @@ -254,67 +254,32 @@ export default class PresupuestoWizard { if (this.opts.canSave) { $('.guardar-presupuesto').on('click', async () => { - const alert = $('#form-errors'); - const servicios = []; - const payload = { - id: this.opts.presupuestoId, - mode: this.opts.mode, - presupuesto: this.#getPresupuestoData(), - servicios: this.formData.servicios.servicios, - datosMaquetacion: this.formData.servicios.datosMaquetacion, - datosMarcapaginas: this.formData.servicios.datosMarcapaginas, - cliente_id: $('#cliente_id').val() || null, - }; - try { - alert.addClass('d-none').find('ul').empty(); - $.ajax({ - url: '/presupuesto/api/save', - type: 'POST', - contentType: 'application/json', - data: JSON.stringify(payload) - }).then((data) => { - Swal.fire({ - icon: 'success', - title: window.languageBundle?.get('presupuesto.exito.guardado') || 'Guardado', - timer: 1800, - buttonsStyling: false, - customClass: { - confirmButton: 'btn btn-secondary me-2', // clases para el botón confirmar - cancelButton: 'btn btn-light' // clases para cancelar - }, - showConfirmButton: false - }); - // opcional: actualizar window.PRESUPUESTO_ID/resumen con el id devuelto - if (data.id) this.opts.presupuestoId = data.id; - }).catch((xhr, status, error) => { - - const errors = xhr.responseJSON; - if (errors && typeof errors === 'object') { - if (!this.DEBUG && xhr.responseJSON.error && xhr.responseJSON.error == 'Internal Server Error') { - console.error("Error al validar los datos generales. Internal Server Error"); - return; - } - Object.values(errors).forEach(errorMsg => { - alert.find('ul').append(`
  • ${errorMsg}
  • `); - }); - alert.removeClass('d-none'); - } else { - alert.find('ul').append('
  • Error desconocido. Por favor, inténtelo de nuevo más tarde.
  • '); - $(window).scrollTop(0); - alert.removeClass('d-none'); - } - window.scrollTo({ top: 0, behavior: 'smooth' }); - }); - } catch (e) { + const success = await this.#guardarPresupuesto(); + if (success) { Swal.fire({ - icon: 'error', - title: window.languageBundle?.get('presupuesto.add.error.save.title') || 'Error', - text: e?.message || '', + icon: 'success', + title: window.languageBundle?.get('presupuesto.exito.guardado') || 'Guardado', + timer: 1800, buttonsStyling: false, customClass: { confirmButton: 'btn btn-secondary me-2', // clases para el botón confirmar cancelButton: 'btn btn-light' // clases para cancelar }, + showConfirmButton: false + }); + + } + }); + + $('.add-cart-btn').on('click', async () => { + const success = await this.#guardarPresupuesto(); + if (success) { + await $.ajax({ + url: `/cart/add/${this.opts.presupuestoId}`, + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, }); } }); @@ -322,6 +287,68 @@ export default class PresupuestoWizard { } + async #guardarPresupuesto() { + + const alert = $('#form-errors'); + const servicios = []; + const payload = { + id: this.opts.presupuestoId, + mode: this.opts.mode, + presupuesto: this.#getPresupuestoData(), + servicios: this.formData.servicios.servicios, + datosMaquetacion: this.formData.servicios.datosMaquetacion, + datosMarcapaginas: this.formData.servicios.datosMarcapaginas, + cliente_id: $('#cliente_id').val() || null, + }; + + try { + alert.addClass('d-none').find('ul').empty(); + return await $.ajax({ + url: '/presupuesto/api/save', + type: 'POST', + contentType: 'application/json', + data: JSON.stringify(payload) + }).then((data) => { + + if (data.id) this.opts.presupuestoId = data.id; + + return true; + }).catch((xhr, status, error) => { + + const errors = xhr.responseJSON; + if (errors && typeof errors === 'object') { + if (!this.DEBUG && xhr.responseJSON.error && xhr.responseJSON.error == 'Internal Server Error') { + console.error("Error al validar los datos generales. Internal Server Error"); + return; + } + Object.values(errors).forEach(errorMsg => { + alert.find('ul').append(`
  • ${errorMsg}
  • `); + }); + alert.removeClass('d-none'); + } else { + alert.find('ul').append('
  • Error desconocido. Por favor, inténtelo de nuevo más tarde.
  • '); + $(window).scrollTop(0); + alert.removeClass('d-none'); + } + window.scrollTo({ top: 0, behavior: 'smooth' }); + return false; + + }); + } catch (e) { + Swal.fire({ + icon: 'error', + title: window.languageBundle?.get('presupuesto.add.error.save.title') || 'Error', + text: e?.message || '', + buttonsStyling: false, + customClass: { + confirmButton: 'btn btn-secondary me-2', // clases para el botón confirmar + cancelButton: 'btn btn-light' // clases para cancelar + }, + }); + return false; + } + } + #cacheFormData() { if (!this.opts.useSessionCache) return; sessionStorage.setItem('formData', JSON.stringify(this.formData)); @@ -1633,7 +1660,6 @@ export default class PresupuestoWizard { if ($target.prop('checked')) { this.formData.servicios.servicios.push( - $target.val(), { id: $target.attr('id') ?? $(`label[for="${$target.attr('id')}"] .service-title`).text().trim(), label: $(`label[for="${$target.attr('id')}"] .service-title`).text().trim(), @@ -1675,6 +1701,14 @@ export default class PresupuestoWizard { this.divExtras.append(item.render()); } + if(!this.formData.servicios.servicios.includes(s => s.id === "ferro-digital")) { + this.formData.servicios.servicios.push({ + id: "ferro-digital", + label: "Ferro Digital", + units: 1, + price: 0 + }); + } this.#cacheFormData(); Summary.updateExtras(); } @@ -1813,15 +1847,15 @@ export default class PresupuestoWizard { } $('#resumen-base').text(formateaMoneda(data.base_imponible, 2, locale)); - if(data.iva_importe_4 > 0) { + if (data.iva_importe_4 > 0) { $('#tr-resumen-iva4').removeClass('d-none'); $('#resumen-iva4').text(formateaMoneda(data.iva_importe_4, 2, locale)); } - else{ + else { $('#tr-resumen-iva4').addClass('d-none'); $('#resumen-iva4').text(formateaMoneda(0, 2, locale)); } - if(data.iva_importe_21 > 0) { + if (data.iva_importe_21 > 0) { $('#tr-resumen-iva21').removeClass('d-none'); $('#resumen-iva21').text(formateaMoneda(data.iva_importe_21, 2, locale)); } else { diff --git a/src/main/resources/templates/imprimelibros/cart/_cartItem.html b/src/main/resources/templates/imprimelibros/cart/_cartItem.html new file mode 100644 index 0000000..923ccb7 --- /dev/null +++ b/src/main/resources/templates/imprimelibros/cart/_cartItem.html @@ -0,0 +1,74 @@ + +
    +
    +
    + +
    +
    + portada +
    +
    + + +
    + +
    + + Presupuesto + +
    +
    + Presupuesto # + # +
    + + +
      +
      +
    • +
      +
    • +
      +
    +
    + + +
    +

    Precio estimado

    +
    + 0,00 € +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/src/main/resources/templates/imprimelibros/cart/cart.html b/src/main/resources/templates/imprimelibros/cart/cart.html new file mode 100644 index 0000000..bb28688 --- /dev/null +++ b/src/main/resources/templates/imprimelibros/cart/cart.html @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + +
    +
    + + +
    + +
    + +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/imprimelibros/partials/topbar.html b/src/main/resources/templates/imprimelibros/partials/topbar.html index 1310ac6..022a958 100644 --- a/src/main/resources/templates/imprimelibros/partials/topbar.html +++ b/src/main/resources/templates/imprimelibros/partials/topbar.html @@ -68,7 +68,9 @@ class="ms-1 header-item d-none d-sm-flex"> + +