mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-12 16:38:48 +00:00
arreglados problemas presupuesto, botones css etc
This commit is contained in:
2
pom.xml
2
pom.xml
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.5.3</version>
|
||||
<version>3.5.6</version>
|
||||
<relativePath /> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.imprimelibros</groupId>
|
||||
|
||||
@ -478,14 +478,19 @@ public class PresupuestoController {
|
||||
Presupuesto p = objectMapper.convertValue(body.get("presupuesto"), Presupuesto.class);
|
||||
Boolean save = objectMapper.convertValue(body.get("save"), Boolean.class);
|
||||
String mode = objectMapper.convertValue(body.get("mode"), String.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> serviciosList = (List<Map<String, Object>>) body.getOrDefault("servicios", List.of());
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> datosMaquetacion = (Map<String, Object>) objectMapper
|
||||
.convertValue(body.get("datosMaquetacion"), Map.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> datosMarcapaginas = (Map<String, Object>) objectMapper
|
||||
.convertValue(body.get("datosMarcapaginas"), Map.class);
|
||||
|
||||
String sessionId = request.getSession(true).getId();
|
||||
String ip = IpUtils.getClientIp(request);
|
||||
|
||||
var resumen = presupuestoService.getResumen(p, serviciosList, save, mode, locale, sessionId, ip);
|
||||
var resumen = presupuestoService.getResumen(p, serviciosList, datosMaquetacion, datosMarcapaginas, save, mode, locale, sessionId, ip);
|
||||
|
||||
return ResponseEntity.ok(resumen);
|
||||
}
|
||||
@ -705,7 +710,7 @@ public class PresupuestoController {
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(path = "api/save")
|
||||
@PostMapping(path = "/api/save")
|
||||
public ResponseEntity<?> save(
|
||||
@RequestBody Map<String, Object> body,
|
||||
Locale locale, HttpServletRequest request) {
|
||||
|
||||
@ -119,13 +119,11 @@ public class PresupuestoService {
|
||||
opcionColorHq.setSelected(true);
|
||||
opciones.add(opcionColorHq);
|
||||
} else {
|
||||
if (!this.isPOD(presupuesto)) {
|
||||
// POD solo negro premium
|
||||
ImagenPresupuesto opcionNegro = this.presupuestadorItems.getImpresionNegro(locale);
|
||||
if (Presupuesto.TipoImpresion.negro.equals(presupuesto.getTipoImpresion()))
|
||||
opcionNegro.setSelected(true);
|
||||
opciones.add(opcionNegro);
|
||||
}
|
||||
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);
|
||||
@ -148,12 +146,14 @@ public class PresupuestoService {
|
||||
List<ImagenPresupuesto> opciones = new ArrayList<>();
|
||||
|
||||
opciones.add(this.presupuestadorItems.getPapelOffsetBlanco(locale));
|
||||
if (presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.negro ||
|
||||
if ((presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.negro
|
||||
&& !this.isPOD(presupuesto)) ||
|
||||
presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.color) {
|
||||
opciones.add(this.presupuestadorItems.getPapelOffsetBlancoVolumen(locale));
|
||||
}
|
||||
opciones.add(this.presupuestadorItems.getPapelOffsetAhuesado(locale));
|
||||
if (presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.negro ||
|
||||
if ((presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.negro
|
||||
&& !this.isPOD(presupuesto)) ||
|
||||
presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.color) {
|
||||
opciones.add(this.presupuestadorItems.getPapelOffsetAhuesadoVolumen(locale));
|
||||
}
|
||||
@ -226,7 +226,8 @@ public class PresupuestoService {
|
||||
gramajes.add("100");
|
||||
gramajes.add("115");
|
||||
}
|
||||
if (presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.negro ||
|
||||
if ((presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.negro
|
||||
&& !this.isPOD(presupuesto)) ||
|
||||
presupuesto.getTipoImpresion() == Presupuesto.TipoImpresion.color) {
|
||||
gramajes.add("120");
|
||||
}
|
||||
@ -812,6 +813,11 @@ public class PresupuestoService {
|
||||
for (Map<String, Object> servicio : servicios) {
|
||||
HashMap<String, Object> servicioData = new HashMap<>();
|
||||
servicioData.put("id", servicio.get("id"));
|
||||
if (servicio.get("id").equals("marcapaginas")) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
servicioData.put("descripcion", servicio.get("label"));
|
||||
servicioData.put("precio", servicio.get("id").equals("marcapaginas")
|
||||
? Double.parseDouble(servicio.get("price").toString())
|
||||
@ -834,6 +840,8 @@ public class PresupuestoService {
|
||||
public Map<String, Object> getResumen(
|
||||
Presupuesto presupuesto,
|
||||
List<Map<String, Object>> servicios,
|
||||
Map<String, Object> datosMaquetacion,
|
||||
Map<String, Object> datosMarcapaginas,
|
||||
Boolean save,
|
||||
String mode,
|
||||
Locale locale,
|
||||
@ -841,6 +849,15 @@ public class PresupuestoService {
|
||||
String ip) {
|
||||
|
||||
// 1) Calcula el resumen (como ya haces)
|
||||
try {
|
||||
presupuesto.setDatosMaquetacionJson(
|
||||
datosMaquetacion != null ? new ObjectMapper().writeValueAsString(datosMaquetacion) : null);
|
||||
presupuesto.setDatosMarcapaginasJson(
|
||||
datosMarcapaginas != null ? new ObjectMapper().writeValueAsString(datosMarcapaginas) : null);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error guardando datos adicionales: " + e.getMessage());
|
||||
}
|
||||
|
||||
Map<String, Object> resumen = getTextosResumen(presupuesto, servicios, locale);
|
||||
if (resumen.containsKey("error"))
|
||||
return resumen;
|
||||
@ -876,6 +893,7 @@ public class PresupuestoService {
|
||||
entidad = mergePresupuesto(entidad, presupuesto);
|
||||
|
||||
if (save != null && save) {
|
||||
|
||||
// Si NO es para guardar (solo calcular resumen), devolver sin persistir
|
||||
presupuestoRepository.saveAndFlush(presupuesto);
|
||||
}
|
||||
|
||||
@ -7,6 +7,8 @@ app.guardar=Guardar
|
||||
app.editar=Editar
|
||||
app.eliminar=Eliminar
|
||||
app.imprimir=Imprimir
|
||||
app.acciones.siguiente=Siguiente
|
||||
app.acciones.anterior=Anterior
|
||||
|
||||
app.bienvenido=Bienvenido
|
||||
app.perfil=Perfil
|
||||
|
||||
@ -1,3 +1,10 @@
|
||||
/* habilita container queries en tu contenedor principal */
|
||||
#presupuesto-row {
|
||||
container-type: inline-size;
|
||||
container-name: presupuesto;
|
||||
}
|
||||
|
||||
|
||||
/* === Contenedor de cada opción === */
|
||||
.image-container {
|
||||
position: relative;
|
||||
@ -248,6 +255,10 @@
|
||||
transform-origin: center center;
|
||||
will-change: transform;
|
||||
transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease, background .22s ease;
|
||||
display: block;
|
||||
width: clamp(155px, 28vw, 250px); /* crece fluido pero nunca <155 ni >250 */
|
||||
min-width: 155px !important;
|
||||
max-width: 250px !important;
|
||||
}
|
||||
|
||||
/* sin elevación al hover */
|
||||
@ -485,4 +496,85 @@
|
||||
#presupuesto-row .summary-col{
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ==== BOTONES ==== */
|
||||
/* --- Base de la barra (dos filas) --- */
|
||||
.buttons-bar{
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
gap:.75rem;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
/* Fila 1: acciones centradas */
|
||||
.buttons-row.center{
|
||||
display:flex;
|
||||
flex-wrap:wrap;
|
||||
justify-content:center;
|
||||
gap:.75rem;
|
||||
}
|
||||
|
||||
/* Fila 2: extremos (prev izq / next dcha) */
|
||||
.buttons-row.split{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:space-between;
|
||||
gap:.75rem;
|
||||
}
|
||||
|
||||
/* El “slot” derecho (puede contener Siguiente o Login) */
|
||||
.buttons-row.split .right-slot{
|
||||
margin-left:auto; /* en desktop empuja a la derecha */
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:.75rem;
|
||||
}
|
||||
|
||||
/* --- Limpieza de márgenes heredados para consistencia de gap --- */
|
||||
.buttons-bar .btn.mx-2{ margin-left:0 !important; margin-right:0 !important; }
|
||||
|
||||
/* ================= MOBILE / CONTENEDOR ESTRECHO ================= */
|
||||
/* A partir de aquí, todo ocurre cuando el contenedor #presupuesto-row
|
||||
es estrecho (p.ej., móvil u offcanvas abierto). Ajusta 576px si lo necesitas */
|
||||
@container presupuesto (max-width: 576px){
|
||||
|
||||
/* Fila 1: acciones apiladas y a 100% ancho */
|
||||
.buttons-row.center{
|
||||
width:100%;
|
||||
}
|
||||
.buttons-row.center .btn{
|
||||
width:100%;
|
||||
justify-content:center; /* icono + texto centrados */
|
||||
max-width: 100%; /* sin límites */
|
||||
}
|
||||
|
||||
/* Fila 2: apilar elementos; cada bloque a 100% */
|
||||
.buttons-row.split{
|
||||
flex-direction:column;
|
||||
align-items:stretch; /* hace que los hijos estiren a 100% */
|
||||
justify-content:flex-start;
|
||||
}
|
||||
.buttons-row.split > *{
|
||||
width:100%;
|
||||
}
|
||||
|
||||
/* Botón “Anterior” si existe → 100% y centrado */
|
||||
.buttons-row.split > button.btn{
|
||||
width:100%;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
/* Bloque derecho (Siguiente / Login) a 100% */
|
||||
.buttons-row.split .right-slot{
|
||||
width:100%;
|
||||
margin-left:0; /* neutraliza el empuje a la derecha */
|
||||
justify-content:stretch; /* estira su contenido */
|
||||
}
|
||||
.buttons-row.split .right-slot .btn{
|
||||
width:100%;
|
||||
justify-content:center; /* texto centrado */
|
||||
}
|
||||
}
|
||||
@ -152,11 +152,11 @@ $(document).on('change', '.marcapaginas-item', () => {
|
||||
|
||||
const payload = {
|
||||
marcapaginas_tirada: parseInt($('#marcapaginas-tirada').val()) || 100,
|
||||
tamanio_marcapaginas: $('#tamanio-marcapaginas').val() || '_50x140_',
|
||||
caras_impresion: $('#caras-impresion').val() || 'una_cara',
|
||||
papel_marcapaginas: $('#papel-marcapaginas').val() || 'cartulina_grafica',
|
||||
gramaje_marcapaginas: parseInt($('#gramaje-marcapaginas').val()) || 300,
|
||||
acabado_marcapaginas: $('#acabado-marcapaginas').val() || 'ninguno',
|
||||
tamanio: $('#tamanio-marcapaginas').val() || '_50x140_',
|
||||
carasImpresion: $('#caras-impresion').val() || 'una_cara',
|
||||
papel: $('#papel-marcapaginas').val() || 'cartulina_grafica',
|
||||
gramaje: parseInt($('#gramaje-marcapaginas').val()) || 300,
|
||||
acabado: $('#acabado-marcapaginas').val() || 'ninguno',
|
||||
};
|
||||
$(document).trigger('marcapaginas:update', [payload]);
|
||||
});
|
||||
@ -167,11 +167,11 @@ function loadMarcapaginasData() {
|
||||
|
||||
$(document).one('marcapaginas:response', (e, stored) => {
|
||||
$('#marcapaginas-tirada').val(stored.marcapaginas_tirada);
|
||||
$('#tamanio-marcapaginas').val(stored.tamanio_marcapaginas);
|
||||
$('#caras-impresion').val(stored.caras_impresion);
|
||||
$('#papel-marcapaginas').val(stored.papel_marcapaginas);
|
||||
$('#gramaje-marcapaginas').val(stored.gramaje_marcapaginas);
|
||||
$('#acabado-marcapaginas').val(stored.acabado_marcapaginas);
|
||||
$('#tamanio-marcapaginas').val(stored.tamanio);
|
||||
$('#caras-impresion').val(stored.carasImpresion);
|
||||
$('#papel-marcapaginas').val(stored.papel);
|
||||
$('#gramaje-marcapaginas').val(stored.gramaje);
|
||||
$('#acabado-marcapaginas').val(stored.acabado);
|
||||
});
|
||||
|
||||
$(document).trigger('marcapaginas:request');
|
||||
|
||||
@ -36,7 +36,7 @@ class TiradaCard {
|
||||
|
||||
const col = $(`
|
||||
<div class="col d-flex">
|
||||
<label class="tirada-card ${this.selected ? 'selected' : ''} w-100 h-100" for="tirada-${this.id}">
|
||||
<label class="tirada-card ${this.selected ? 'selected' : ''} h-100" for="tirada-${this.id}">
|
||||
<input type="radio" name="${this.name}" id="tirada-${this.id}" value="${this.unidades}" ${this.selected ? 'checked' : ''}>
|
||||
<div class="title">${this.#title()}</div>
|
||||
|
||||
|
||||
@ -70,14 +70,19 @@ export default class PresupuestoWizard {
|
||||
}
|
||||
},
|
||||
servicios: {
|
||||
servicios: [],
|
||||
servicios: [{
|
||||
"id": "ferro-digital",
|
||||
"label": "Ferro Digital",
|
||||
"price": 0,
|
||||
"units": 1
|
||||
}],
|
||||
datosMarcapaginas: {
|
||||
marcapaginas_tirada: 100,
|
||||
tamanio_marcapaginas: '_50x140_',
|
||||
caras_impresion: 'una_cara',
|
||||
papel_marcapaginas: 'cartulina_grafica',
|
||||
gramaje_marcapaginas: 300,
|
||||
acabado_marcapaginas: 'ninguno',
|
||||
tamanio: '_50x140_',
|
||||
carasImpresion: 'una_cara',
|
||||
papel: 'cartulina_grafica',
|
||||
gramaje: 300,
|
||||
acabado: 'ninguno',
|
||||
resultado: {
|
||||
precio_unitario: 0,
|
||||
precio: 0
|
||||
@ -127,7 +132,6 @@ export default class PresupuestoWizard {
|
||||
this.entregaTipo = $('#entregaTipo');
|
||||
this.ivaReducido = $('#iva-reducido');
|
||||
this.btnIvaReducidoDetail = $('#btn-iva-reducido-detail');
|
||||
this.btn_next_datos_generales = $('#next-datos-generales');
|
||||
this.datos_generales_alert = $('#datos-generales-alert');
|
||||
|
||||
// pestaña interior
|
||||
@ -481,7 +485,7 @@ export default class PresupuestoWizard {
|
||||
Summary.updateFormato();
|
||||
});
|
||||
|
||||
this.btn_next_datos_generales.on('click', () => {
|
||||
$('.btn-change-tab-datos-generales').on('click', () => {
|
||||
this.#nextDatosGenerales();
|
||||
});
|
||||
|
||||
@ -715,7 +719,7 @@ export default class PresupuestoWizard {
|
||||
$('.tipo-libro#grapado').removeClass('d-none');
|
||||
}
|
||||
|
||||
if (!(selectedTipo && $('.tipo-libro#' + selectedTipo).length > 0 && !$('.tipo-libro#' + selectedTipo).hasClass('d-none'))) {
|
||||
if (!(selectedTipo && $(`.tipo-libro input[value="${selectedTipo}"]`).length && !$(`.tipo-libro input[value="${selectedTipo}"]`).closest('.tipo-libro').hasClass('d-none'))) {
|
||||
|
||||
let firstVisible = $('.tipo-libro').not('.d-none').first();
|
||||
|
||||
@ -883,7 +887,7 @@ export default class PresupuestoWizard {
|
||||
$('.btn-change-tab-interior').on('click', (e) => {
|
||||
|
||||
let data = this.#getPresupuestoData();
|
||||
const id = e.currentTarget.id;
|
||||
const action = $(e.currentTarget).data('btn-action') || 'next';
|
||||
this.interior_alert.addClass('d-none').find('#form-errors-alert-list').empty();
|
||||
|
||||
$.ajax({
|
||||
@ -891,7 +895,7 @@ export default class PresupuestoWizard {
|
||||
type: 'POST',
|
||||
data: data,
|
||||
success: (data) => {
|
||||
if (id === 'btn-prev-interior') {
|
||||
if (action === 'previous') {
|
||||
this.summaryTableInterior.addClass('d-none');
|
||||
this.#changeTab('pills-general-data');
|
||||
} else {
|
||||
@ -1247,9 +1251,9 @@ export default class PresupuestoWizard {
|
||||
$('.btn-change-tab-cubierta').on('click', (e) => {
|
||||
|
||||
const data = this.#getPresupuestoData();
|
||||
const id = e.currentTarget.id;
|
||||
const action = $(e.currentTarget).data('btn-action') || 'next';
|
||||
|
||||
if (id === 'btn-prev-cubierta') {
|
||||
if (action === 'previous') {
|
||||
data.calcular = false;
|
||||
}
|
||||
else {
|
||||
@ -1261,7 +1265,7 @@ export default class PresupuestoWizard {
|
||||
type: 'POST',
|
||||
data: data,
|
||||
success: (data) => {
|
||||
if (id === 'btn-prev-cubierta') {
|
||||
if (action === 'previous') {
|
||||
this.summaryTableCubierta.addClass('d-none');
|
||||
this.#changeTab('pills-inside');
|
||||
}
|
||||
@ -1272,7 +1276,7 @@ export default class PresupuestoWizard {
|
||||
}
|
||||
},
|
||||
error: (xhr, status, error) => {
|
||||
if (id === 'btn-prev-cubierta') {
|
||||
if (action === 'previous') {
|
||||
this.#changeTab('pills-inside');
|
||||
return;
|
||||
}
|
||||
@ -1540,9 +1544,9 @@ export default class PresupuestoWizard {
|
||||
|
||||
$(document).on('click', '.btn-change-tab-seleccion-tirada', (e) => {
|
||||
|
||||
const id = e.currentTarget.id;
|
||||
const action = $(e.currentTarget).data('btn-action') || 'next';
|
||||
|
||||
if (id === 'btn-prev-seleccion-tirada') {
|
||||
if (action === 'previous') {
|
||||
this.#changeTab('pills-cover');
|
||||
} else {
|
||||
const data = this.#getPresupuestoData();
|
||||
@ -1621,9 +1625,9 @@ export default class PresupuestoWizard {
|
||||
|
||||
$(document).on('click', '.btn-change-tab-extras', (e) => {
|
||||
|
||||
const id = e.currentTarget.id;
|
||||
const action = $(e.currentTarget).data('btn-action') || 'next';
|
||||
|
||||
if (id === 'btn-prev-extras') {
|
||||
if (action === 'previous') {
|
||||
this.#changeTab('pills-seleccion-tirada');
|
||||
this.summaryTableExtras.addClass('d-none');
|
||||
} else {
|
||||
@ -1631,11 +1635,22 @@ export default class PresupuestoWizard {
|
||||
const servicios = [];
|
||||
$('.service-checkbox:checked').each(function () {
|
||||
const $servicio = $(this);
|
||||
let price = 0;
|
||||
if ($servicio.attr('id') === 'marcapaginas') {
|
||||
price = self.formData.servicios.datosMarcapaginas.resultado.precio;
|
||||
}
|
||||
else if ($servicio.attr('id') === 'maquetacion') {
|
||||
price = self.formData.servicios.datosMaquetacion.resultado.precio;
|
||||
}
|
||||
else {
|
||||
price = $servicio.data('price') ?? $(`label[for="${$servicio.attr('id')}"] .service-price`).text().trim().replace(" " + self.divExtras.data('currency'), '');
|
||||
}
|
||||
|
||||
servicios.push({
|
||||
id: $servicio.attr('id') ?? $(`label[for="${$servicio.attr('id')}"] .service-title`).text().trim(),
|
||||
label: $(`label[for="${$servicio.attr('id')}"] .service-title`).text().trim(),
|
||||
units: $servicio.attr('id') === 'marcapaginas' ? self.formData.servicios.datosMarcapaginas.marcapaginas_tirada : 1,
|
||||
price: $servicio.data('price') ?? $(`label[for="${$servicio.attr('id')}"] .service-price`).text().trim().replace(" " + self.divExtras.data('currency'), ''),
|
||||
price: price,
|
||||
});
|
||||
});
|
||||
|
||||
@ -1643,7 +1658,9 @@ export default class PresupuestoWizard {
|
||||
presupuesto: this.#getPresupuestoData(),
|
||||
save: !this.opts.canSave,
|
||||
mode: this.opts.mode,
|
||||
servicios: servicios
|
||||
servicios: servicios,
|
||||
datosMaquetacion: this.formData.servicios.datosMaquetacion,
|
||||
datosMarcapaginas: this.formData.servicios.datosMarcapaginas,
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
@ -1673,15 +1690,25 @@ export default class PresupuestoWizard {
|
||||
const $target = $(e.currentTarget);
|
||||
|
||||
if ($target.prop('checked')) {
|
||||
let price = 0;
|
||||
if ($target.attr('id') === 'marcapaginas') {
|
||||
price = self.formData.servicios.datosMarcapaginas.resultado.precio;
|
||||
}
|
||||
else if ($target.attr('id') === 'maquetacion') {
|
||||
price = self.formData.servicios.datosMaquetacion.resultado.precio;
|
||||
}
|
||||
else {
|
||||
price = $target.data('price') ?? $(`label[for="${$target.attr('id')}"] .service-price`).text().trim().replace(" " + self.divExtras.data('currency'), '');
|
||||
}
|
||||
this.formData.servicios.servicios.push(
|
||||
{
|
||||
id: $target.attr('id') ?? $(`label[for="${$target.attr('id')}"] .service-title`).text().trim(),
|
||||
label: $(`label[for="${$target.attr('id')}"] .service-title`).text().trim(),
|
||||
units: $target.attr('id') === 'marcapaginas' ? self.formData.servicios.datosMarcapaginas.marcapaginas_tirada : 1,
|
||||
price: $target.data('price') ?? $(`label[for="${$target.attr('id')}"] .service-price`).text().trim().replace(" " + self.divExtras.data('currency'), ''),
|
||||
price: price,
|
||||
});
|
||||
} else {
|
||||
const index = this.formData.servicios.servicios.indexOf($target.val());
|
||||
const index = this.formData.servicios.servicios.findIndex(item => item.id == $target.attr('id'));
|
||||
if (index > -1) {
|
||||
this.formData.servicios.servicios.splice(index, 1);
|
||||
}
|
||||
@ -1705,7 +1732,7 @@ export default class PresupuestoWizard {
|
||||
if (this.formData.servicios.servicios.some(s => s.id === extra.id) && !extra.checked) {
|
||||
extra.checked = true;
|
||||
if (extra.id === "marcapaginas" || extra.id === "maquetacion") {
|
||||
extra.price = extra.id === "marcapaginas" ?
|
||||
extra.price = (extra.id === "marcapaginas") ?
|
||||
this.formData.servicios.datosMarcapaginas.resultado.precio :
|
||||
this.formData.servicios.datosMaquetacion.resultado.precio;
|
||||
extra.priceUnit = this.divExtras.data('currency');
|
||||
@ -1749,9 +1776,6 @@ export default class PresupuestoWizard {
|
||||
...result,
|
||||
};
|
||||
|
||||
const list = this.formData.servicios.servicios;
|
||||
if (!list.includes('maquetacion')) list.push('maquetacion');
|
||||
|
||||
this.#cacheFormData();
|
||||
});
|
||||
}
|
||||
@ -1779,10 +1803,6 @@ export default class PresupuestoWizard {
|
||||
...result,
|
||||
};
|
||||
|
||||
// asegúrate de añadir el servicio seleccionado
|
||||
const list = this.formData.servicios.servicios;
|
||||
if (!list.includes('marcapaginas')) list.push('marcapaginas');
|
||||
|
||||
this.#cacheFormData();
|
||||
});
|
||||
|
||||
@ -1811,7 +1831,8 @@ export default class PresupuestoWizard {
|
||||
|
||||
// 2) Botón "atrás" en Resumen
|
||||
$(document).on('click', '.btn-change-tab-resumen', (e) => {
|
||||
if (e.currentTarget.id === 'btn-prev-resumen') {
|
||||
const action = $(e.currentTarget).data('btn-action') || 'next';
|
||||
if (action === 'previous') {
|
||||
this.#changeTab('pills-extras');
|
||||
}
|
||||
});
|
||||
|
||||
@ -1,21 +1,57 @@
|
||||
<!-- templates/fragments/common.html -->
|
||||
<div th:fragment="buttons(appMode)"
|
||||
class="order-3 order-md-2 mx-md-auto d-flex">
|
||||
<button th:if="${appMode == 'add' or appMode == 'edit'}" id="btn-guardar" type="button"
|
||||
class="btn btn-secondary d-flex align-items-center mx-2 guardar-presupuesto">
|
||||
<i class="ri-save-3-line me-2"></i>
|
||||
<span th:text="#{presupuesto.guardar}">Guardar</span>
|
||||
</button>
|
||||
<div th:fragment="buttons(appMode, btnClass, showPrev, showNext, showActions, showCart)"
|
||||
class="buttons-bar mt-2">
|
||||
|
||||
<button th:if="${appMode == 'add' or appMode == 'edit'}" id="btn-add-cart" type="button"
|
||||
class="btn btn-secondary d-flex align-items-center mx-2 add-cart-btn">
|
||||
<i class="ri-shopping-cart-line me-2"></i>
|
||||
<span th:text="#{presupuesto.add-to-cart}">Añadir al carrito</span>
|
||||
</button>
|
||||
<!-- Fila 1: ACCIONES, centradas -->
|
||||
<div class="buttons-row center" th:if="${showActions}">
|
||||
<button th:if="${appMode == 'add' or appMode == 'edit'}"
|
||||
type="button"
|
||||
class="btn btn-secondary d-flex align-items-center mx-2 guardar-presupuesto">
|
||||
<i class="ri-save-3-line me-2"></i>
|
||||
<span th:text="#{presupuesto.guardar}">Guardar</span>
|
||||
</button>
|
||||
|
||||
<button id="btn-imprimir" type="button"
|
||||
class="btn btn-secondary d-flex align-items-center mx-2 imprimir-presupuesto">
|
||||
<i class="ri-printer-line me-2"></i>
|
||||
<span th:text="#{app.imprimir}">Imprimir</span>
|
||||
</button>
|
||||
<button th:if="${appMode == 'add' or appMode == 'edit'}"
|
||||
type="button"
|
||||
class="btn btn-secondary d-flex align-items-center mx-2 add-cart-btn">
|
||||
<i class="ri-shopping-cart-line me-2"></i>
|
||||
<span th:text="#{presupuesto.add-to-cart}">Añadir a la cesta</span>
|
||||
</button>
|
||||
|
||||
<button type="button"
|
||||
class="btn btn-secondary d-flex align-items-center mx-2 btn-imprimir">
|
||||
<i class="ri-printer-line me-2"></i>
|
||||
<span th:text="#{app.imprimir}">Imprimir</span>
|
||||
</button>
|
||||
|
||||
<!-- Alternativa cuando no está autenticado -->
|
||||
<button sec:authorize="!isAuthenticated()"
|
||||
type="button"
|
||||
class="btn btn-secondary d-flex align-items-center btn-login-required ms-2">
|
||||
<i class="mdi mdi-login label-icon align-middle fs-16 me-2"></i>
|
||||
<span th:text="#{presupuesto.resumen.inicie-sesion}">Inicie sesión para continuar</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Fila 2: PREV (izq) / NEXT o LOGIN (dcha) -->
|
||||
<div class="buttons-row split">
|
||||
<button th:if="${showPrev}"
|
||||
th:id="|${btnClass}-prev|"
|
||||
data-btn-action="previous"
|
||||
th:class="'btn btn-light ' + ${btnClass}"
|
||||
type="button">
|
||||
<i class="ri-arrow-left-circle-line label-icon align-middle fs-16 me-2"></i>
|
||||
<span th:text="#{app.acciones.anterior}">Anterior</span>
|
||||
</button>
|
||||
|
||||
<div class="right-slot d-flex align-items-center">
|
||||
<button th:if="${showNext}"
|
||||
data-btn-action="next"
|
||||
th:id="|${btnClass}-next|"
|
||||
th:class="'btn btn-secondary d-flex align-items-center ' + ${btnClass}"
|
||||
type="button">
|
||||
<span th:text="#{app.acciones.siguiente}">Siguiente</span>
|
||||
<i class="ri-arrow-right-circle-line fs-16 ms-2"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -408,18 +408,6 @@
|
||||
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mt-4 w-100">
|
||||
<button id="btn-prev-cubierta" type="button"
|
||||
class="btn btn-light d-flex align-items-center btn-change-tab-cubierta order-1">
|
||||
<i class=" ri-arrow-left-circle-line label-icon align-middle fs-16 me-2"></i>
|
||||
<span th:text="#{presupuesto.volver-interior}">Volver a interior</span>
|
||||
</button>
|
||||
|
||||
<div th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode})}"></div>
|
||||
|
||||
<button id="btn-next-cubierta" type="button"
|
||||
class="btn btn-secondary d-flex align-items-center btn-change-tab-cubierta order-2 order-md-3">
|
||||
<span th:text="#{presupuesto.continuar-seleccion-tirada}">Continuar a selección de tirada</span>
|
||||
<i class="ri-arrow-right-circle-line fs-16 ms-2"></i>
|
||||
</button>
|
||||
<div th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-cubierta', true, true, true, false)}"></div>
|
||||
</div>
|
||||
</div>
|
||||
@ -270,7 +270,7 @@
|
||||
<div
|
||||
class="form-check form-switch form-switch-custom form-switch-presupuesto mb-3 d-flex align-items-center">
|
||||
<input type="checkbox" class="form-check-input datos-generales-data me-2" id="iva-reducido"
|
||||
name="iva-reducido" checked/>
|
||||
name="iva-reducido" checked />
|
||||
<label for="iva-reducido" class="form-label d-flex align-items-center mb-0">
|
||||
<span th:text="#{presupuesto.iva-reducido}" class="me-2">I.V. reducido</span>
|
||||
<button type="button" id="btn-iva-reducido-detail"
|
||||
@ -282,7 +282,8 @@
|
||||
</div>
|
||||
<div class="row justify-content-center mb-2">
|
||||
<div class="col-sm-3 justify-content-center">
|
||||
<label for="entregaTipo" class="form-label mt-2" th:text="#{presupuesto.entrega}">Entrega</label>
|
||||
<label for="entregaTipo" class="form-label mt-2"
|
||||
th:text="#{presupuesto.entrega}">Entrega</label>
|
||||
<select class="form-select select2 datos-generales-data" id="entregaTipo" name="entregaTipo">
|
||||
<option selected value="peninsula" th:text="#{presupuesto.entrega.peninsula}">Península
|
||||
y
|
||||
@ -297,12 +298,9 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div class="d-flex align-items-center justify-content-center gap-3 mt-3">
|
||||
|
||||
<button type="button" id="next-datos-generales"
|
||||
class="btn btn-secondary d-flex align-items-center ms-auto order-2 order-md-3">
|
||||
<span th:text="#{presupuesto.continuar-interior}">Continuar a diseño interior</span>
|
||||
<i class="ri-arrow-right-circle-line fs-16 ms-2"></i>
|
||||
</button>
|
||||
<div
|
||||
th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-datos-generales', false, true, false, false)}">
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
@ -17,18 +17,6 @@
|
||||
<!-- End Ribbon Shape -->
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mt-4 w-100">
|
||||
<button id="btn-prev-extras" type="button"
|
||||
class="btn btn-light d-flex align-items-center btn-change-tab-extras order-1">
|
||||
<i class=" ri-arrow-left-circle-line label-icon align-middle fs-16 me-2"></i>
|
||||
<span th:text="#{presupuesto.volver-seleccion-tirada}">Volver a selección de tirada</span>
|
||||
</button>
|
||||
|
||||
<div th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode})}"></div>
|
||||
|
||||
<button id="btn-next-extras" type="button"
|
||||
class="btn btn-secondary d-flex align-items-center btn-change-tab-extras order-2 order-md-3">
|
||||
<span><b th:text="#{presupuesto.resumen}">Resumen</b></span>
|
||||
<i class="ri-arrow-right-circle-line fs-16 ms-2"></i>
|
||||
</button>
|
||||
<div th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-extras', true, true, true, false)}"></div>
|
||||
</div>
|
||||
</div>
|
||||
@ -57,20 +57,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mt-4 w-100">
|
||||
<button id="btn-prev-interior" type="button"
|
||||
class="btn btn-change-tab-interior btn-light d-flex align-items-center order-1">
|
||||
<i class=" ri-arrow-left-circle-line label-icon align-middle fs-16 me-2"></i>
|
||||
<span th:text="#{presupuesto.volver-datos-generales}">Volver a datos generales</span>
|
||||
</button>
|
||||
|
||||
<div th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode})}"></div>
|
||||
|
||||
<button id="btn-next-interior" type="button"
|
||||
class="btn btn-change-tab-interior btn-secondary d-flex align-items-center order-2 order-md-3">
|
||||
<span th:text="#{presupuesto.continuar-cubierta}">Continuar a diseño cubierta</span>
|
||||
<i class="ri-arrow-right-circle-line fs-16 ms-2"></i>
|
||||
</button>
|
||||
<div
|
||||
th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-interior', true, true, true, false)}">
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
@ -50,24 +50,8 @@
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mt-4 w-100">
|
||||
<button id="btn-prev-resumen" type="button"
|
||||
class="btn btn-light d-flex align-items-center btn-change-tab-resumen order-1">
|
||||
<i class=" ri-arrow-left-circle-line label-icon align-middle fs-16 me-2"></i>
|
||||
<span th:text="#{presupuesto.volver-extras}">Volver a extras</span>
|
||||
</button>
|
||||
|
||||
|
||||
<div th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode})}"></div>
|
||||
|
||||
<button th:unless="${#authorization.expression('isAuthenticated()')}" id="btn-add-cart" type="button"
|
||||
class="btn btn-secondary d-flex align-items-center order-2 order-md-3">
|
||||
<i class="mdi mdi-login label-icon align-middle fs-16 me-2"></i>
|
||||
<span th:text="#{presupuesto.resumen.inicie-sesion}">Inicie sesión para continuar</span>
|
||||
</button>
|
||||
<button th:if="${#authorization.expression('isAuthenticated()')}" id="btn-add-cart" type="button"
|
||||
class="btn btn-secondary d-flex align-items-center order-2 order-md-3">
|
||||
<span th:text="#{presupuesto.resumen.agregar-cesta}">Agregar a la cesta</span>
|
||||
<i class="ri-shopping-cart-2-line fs-16 ms-2"></i>
|
||||
</button>
|
||||
<div
|
||||
th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-resumen', true, false, true, true)}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
</div>
|
||||
<div id="div-tiradas"
|
||||
class="row row-cols-1 row-cols-sm-2 row-cols-lg-4 g-4 justify-content-center align-items-stretch mx-auto mb-4"
|
||||
class="row row-cols-auto justify-content-center g-4 mx-auto mb-4"
|
||||
style="max-width:1120px" th:data-per-unit="#{presupuesto.precio-unidad}"
|
||||
th:data-total="#{presupuesto.total}" th:data-select="#{presupuesto.seleccionar-tirada}"
|
||||
th:data-selected="#{presupuesto.tirada-seleccionada}" th:data-units="#{presupuesto.unidades}">
|
||||
@ -27,18 +27,6 @@
|
||||
<!-- End Ribbon Shape -->
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mt-4 w-100">
|
||||
<button id="btn-prev-seleccion-tirada" type="button"
|
||||
class="btn btn-light d-flex align-items-center btn-change-tab-seleccion-tirada order-1">
|
||||
<i class=" ri-arrow-left-circle-line label-icon align-middle fs-16 me-2"></i>
|
||||
<span th:text="#{presupuesto.volver-cubierta}">Volver a diseño de cubierta</span>
|
||||
</button>
|
||||
|
||||
<div th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode})}"></div>
|
||||
|
||||
<button id="btn-next-seleccion-tirada" type="button"
|
||||
class="btn btn-secondary d-flex align-items-center btn-change-tab-seleccion-tirada order-2 order-md-3">
|
||||
<span><b th:text="#{presupuesto.continuar-extras-libro}">Continuar a extras del libro</b></span>
|
||||
<i class="ri-arrow-right-circle-line fs-16 ms-2"></i>
|
||||
</button>
|
||||
<div th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-seleccion-tirada', true, true, true, false)}"></div>
|
||||
</div>
|
||||
</div>
|
||||
@ -32,8 +32,8 @@
|
||||
data-bs-target="#pills-general-data" type="button" role="tab"
|
||||
aria-controls="pills-general-data" aria-selected="true">
|
||||
<i
|
||||
class="ri-information-line fs-16 p-2 bg-soft-primary text-primary rounded-circle align-middle me-2"></i>
|
||||
<label th:text="#{presupuesto.datos-generales}">Datos Generales</label>
|
||||
class="ri-information-line fs-5 p-1 bg-soft-primary text-primary rounded-circle align-middle me-2"></i>
|
||||
<label class="fs-13 my-2" th:text="#{presupuesto.datos-generales}">Datos Generales</label>
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
@ -41,8 +41,8 @@
|
||||
data-bs-target="#pills-inside" type="button" role="tab"
|
||||
aria-controls="pills-inside" aria-selected="false">
|
||||
<i
|
||||
class="ri-book-open-line fs-16 p-2 bg-soft-primary text-primary rounded-circle align-middle me-2"></i>
|
||||
<label th:text="#{presupuesto.interior}">Interior</label>
|
||||
class="ri-book-open-line fs-5 p-1 bg-soft-primary text-primary rounded-circle align-middle me-2"></i>
|
||||
<label class="fs-13 my-2" th:text="#{presupuesto.interior}">Interior</label>
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
@ -50,8 +50,8 @@
|
||||
data-bs-target="#pills-cover" type="button" role="tab"
|
||||
aria-controls="pills-cover" aria-selected="false">
|
||||
<i
|
||||
class="ri-book-2-line fs-16 p-2 bg-soft-primary text-primary rounded-circle align-middle me-2"></i>
|
||||
<label th:text="#{presupuesto.cubierta}">Cubierta</label>
|
||||
class="ri-book-2-line fs-5 p-1 bg-soft-primary text-primary rounded-circle align-middle me-2"></i>
|
||||
<label class="fs-13 my-2" th:text="#{presupuesto.cubierta}">Cubierta</label>
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
@ -59,8 +59,8 @@
|
||||
data-bs-target="#pills-seleccion-tirada" type="button" role="tab"
|
||||
aria-controls="pills-seleccion-tirada" aria-selected="false">
|
||||
<i
|
||||
class="ri-add-box-line fs-16 p-2 bg-soft-primary text-primary rounded-circle align-middle me-2"></i>
|
||||
<label th:text="#{presupuesto.seleccion-tirada}">Seleccion de tirada</label>
|
||||
class="ri-add-box-line fs-5 p-1 bg-soft-primary text-primary rounded-circle align-middle me-2"></i>
|
||||
<label class="fs-13 my-2" th:text="#{presupuesto.seleccion-tirada}">Seleccion de tirada</label>
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
@ -68,8 +68,8 @@
|
||||
data-bs-target="#pills-extras" type="button" role="tab"
|
||||
aria-controls="pills-extras" aria-selected="false">
|
||||
<i
|
||||
class="ri-add-box-line fs-16 p-2 bg-soft-primary text-primary rounded-circle align-middle me-2"></i>
|
||||
<label th:text="#{presupuesto.extras}">Extras</label>
|
||||
class="ri-add-box-line fs-5 p-1 bg-soft-primary text-primary rounded-circle align-middle me-2"></i>
|
||||
<label class="fs-13 my-2" th:text="#{presupuesto.extras}">Extras</label>
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
@ -77,8 +77,8 @@
|
||||
data-bs-target="#pills-resumen" type="button" role="tab"
|
||||
aria-controls="pills-resumen" aria-selected="false">
|
||||
<i
|
||||
class="ri-add-box-line fs-16 p-2 bg-soft-primary text-primary rounded-circle align-middle me-2"></i>
|
||||
<label th:text="#{presupuesto.resumen}">Resumen</label>
|
||||
class="ri-add-box-line fs-5 p-1 bg-soft-primary text-primary rounded-circle align-middle me-2"></i>
|
||||
<label class="fs-13 my-2" th:text="#{presupuesto.resumen}">Resumen</label>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user