mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-12 16:38:48 +00:00
trabajando en el delete
This commit is contained in:
@ -46,6 +46,11 @@ public abstract class AbstractAuditedEntity {
|
||||
@Column(name = "deleted_at")
|
||||
private Instant deletedAt;
|
||||
|
||||
@LastModifiedBy
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "deleted_by")
|
||||
private User deletedBy;
|
||||
|
||||
// Getters/Setters
|
||||
public Long getId() { return id; }
|
||||
public void setId(Long id) { this.id = id; }
|
||||
@ -67,4 +72,7 @@ public abstract class AbstractAuditedEntity {
|
||||
|
||||
public Instant getDeletedAt() { return deletedAt; }
|
||||
public void setDeletedAt(Instant deletedAt) { this.deletedAt = deletedAt; }
|
||||
|
||||
public User getDeletedBy() { return deletedBy; }
|
||||
public void setDeletedBy(User deletedBy) { this.deletedBy = deletedBy; }
|
||||
}
|
||||
|
||||
@ -320,8 +320,6 @@ public class MargenPresupuestoController {
|
||||
|
||||
return repo.findById(id).map(u -> {
|
||||
try {
|
||||
|
||||
|
||||
u.setDeleted(true);
|
||||
u.setDeletedAt(LocalDateTime.now());
|
||||
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
package com.imprimelibros.erp.presupuesto;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.ui.Model;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@ -21,12 +25,15 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
@ -40,6 +47,9 @@ import com.imprimelibros.erp.presupuesto.classes.PresupuestoMarcapaginas;
|
||||
import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
|
||||
import com.imprimelibros.erp.presupuesto.service.PresupuestoService;
|
||||
import com.imprimelibros.erp.presupuesto.validation.PresupuestoValidationGroups;
|
||||
import com.imprimelibros.erp.users.UserDao;
|
||||
import com.imprimelibros.erp.users.User;
|
||||
import com.imprimelibros.erp.users.UserDetailsImpl;
|
||||
import com.imprimelibros.erp.presupuesto.service.PresupuestoFormDataMapper;
|
||||
import com.imprimelibros.erp.presupuesto.service.PresupuestoFormDataMapper.PresupuestoFormDataDto;
|
||||
|
||||
@ -66,16 +76,18 @@ public class PresupuestoController {
|
||||
private final PresupuestoDatatableService dtService;
|
||||
private final VariableService variableService;
|
||||
private final PresupuestoFormDataMapper formDataMapper;
|
||||
private final UserDao userRepo;
|
||||
|
||||
public PresupuestoController(ObjectMapper objectMapper, TranslationService translationService,
|
||||
PresupuestoDatatableService dtService, PresupuestoRepository presupuestoRepository,
|
||||
VariableService variableService, PresupuestoFormDataMapper formDataMapper) {
|
||||
VariableService variableService, PresupuestoFormDataMapper formDataMapper, UserDao userRepo) {
|
||||
this.objectMapper = objectMapper;
|
||||
this.translationService = translationService;
|
||||
this.dtService = dtService;
|
||||
this.presupuestoRepository = presupuestoRepository;
|
||||
this.variableService = variableService;
|
||||
this.formDataMapper = formDataMapper;
|
||||
this.userRepo = userRepo;
|
||||
}
|
||||
|
||||
@PostMapping("/public/validar/datos-generales")
|
||||
@ -122,7 +134,6 @@ public class PresupuestoController {
|
||||
errores.put(error.getField(), msg);
|
||||
});
|
||||
|
||||
|
||||
// errores globales (@ConsistentTiradas...)
|
||||
result.getGlobalErrors().forEach(error -> errores.put("global", error.getDefaultMessage()));
|
||||
|
||||
@ -151,7 +162,6 @@ public class PresupuestoController {
|
||||
errores.put(error.getField(), msg);
|
||||
});
|
||||
|
||||
|
||||
// errores globales (@ConsistentTiradas...)
|
||||
result.getGlobalErrors().forEach(error -> errores.put("global", error.getDefaultMessage()));
|
||||
|
||||
@ -187,7 +197,6 @@ public class PresupuestoController {
|
||||
errores.put(error.getField(), msg);
|
||||
});
|
||||
|
||||
|
||||
// errores globales (@ConsistentTiradas...)
|
||||
result.getGlobalErrors().forEach(error -> errores.put("global", error.getDefaultMessage()));
|
||||
|
||||
@ -219,7 +228,6 @@ public class PresupuestoController {
|
||||
errores.put(error.getField(), msg);
|
||||
});
|
||||
|
||||
|
||||
if (!errores.isEmpty()) {
|
||||
return ResponseEntity.badRequest().body(errores);
|
||||
}
|
||||
@ -271,7 +279,6 @@ public class PresupuestoController {
|
||||
errores.put(error.getField(), msg);
|
||||
});
|
||||
|
||||
|
||||
if (!errores.isEmpty()) {
|
||||
return ResponseEntity.badRequest().body(errores);
|
||||
}
|
||||
@ -305,7 +312,6 @@ public class PresupuestoController {
|
||||
errores.put(error.getField(), msg);
|
||||
});
|
||||
|
||||
|
||||
if (!errores.isEmpty()) {
|
||||
return ResponseEntity.badRequest().body(errores);
|
||||
}
|
||||
@ -484,7 +490,15 @@ public class PresupuestoController {
|
||||
@GetMapping
|
||||
public String getPresupuestoList(Model model, Authentication authentication, Locale locale) {
|
||||
|
||||
List<String> keys = List.of();
|
||||
List<String> keys = List.of(
|
||||
"presupuesto.delete.title",
|
||||
"presupuesto.delete.text",
|
||||
"presupuesto.eliminar",
|
||||
"presupuesto.delete.button",
|
||||
"app.yes",
|
||||
"app.cancelar",
|
||||
"presupuesto.delete.ok.title",
|
||||
"presupuesto.delete.ok.text");
|
||||
|
||||
Map<String, String> translations = translationService.getTranslations(locale, keys);
|
||||
model.addAttribute("languageBundle", translations);
|
||||
@ -570,4 +584,55 @@ public class PresupuestoController {
|
||||
return dtService.datatableAnonimos(dt, locale);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
@Transactional
|
||||
public ResponseEntity<?> delete(@PathVariable Long id, Authentication auth, Locale locale) {
|
||||
|
||||
Presupuesto p = presupuestoRepository.findById(id)
|
||||
.orElseThrow(() -> new ResponseStatusException(
|
||||
HttpStatus.NOT_FOUND,
|
||||
messageSource.getMessage("presupuesto.error.not-found", null, locale)));
|
||||
|
||||
boolean isUser = auth != null && auth.getAuthorities().stream()
|
||||
.anyMatch(a -> a.getAuthority().equals("ROLE_USER"));
|
||||
|
||||
// compara por IDs (no uses equals entre tipos distintos)
|
||||
Long ownerId = p.getUser() != null ? p.getUser().getId() : null;
|
||||
|
||||
User currentUser = null;
|
||||
Long currentUserId = null;
|
||||
if (auth != null && auth.getPrincipal() instanceof UserDetailsImpl udi) {
|
||||
currentUserId = udi.getId();
|
||||
currentUser = userRepo.findById(currentUserId).orElse(null);
|
||||
} else if (auth != null) {
|
||||
currentUserId = userRepo.findIdByUserNameIgnoreCase(auth.getName()).orElse(null); // fallback
|
||||
currentUser = userRepo.findById(currentUserId).orElse(null);
|
||||
}
|
||||
|
||||
boolean isOwner = ownerId != null && ownerId.equals(currentUserId);
|
||||
|
||||
if (isUser && !isOwner) {
|
||||
throw new ResponseStatusException(
|
||||
HttpStatus.FORBIDDEN,
|
||||
messageSource.getMessage("presupuesto.error.delete-permission-denied", null, locale));
|
||||
}
|
||||
|
||||
if (p.getEstado() != null && !p.getEstado().equals(Presupuesto.Estado.borrador)) {
|
||||
throw new ResponseStatusException(
|
||||
HttpStatus.FORBIDDEN,
|
||||
messageSource.getMessage("presupuesto.error.delete-not-draft", null, locale));
|
||||
}
|
||||
|
||||
// SOFT DELETE (no uses deleteById)
|
||||
p.setDeleted(true);
|
||||
p.setDeletedAt(Instant.now());
|
||||
p.setDeletedBy(currentUser);
|
||||
|
||||
presupuestoRepository.save(p);
|
||||
return ResponseEntity.ok(Map.of("message",
|
||||
messageSource.getMessage("presupuesto.exito.eliminado", null, locale)));
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -174,6 +174,7 @@ public class PresupuestoDatatableService {
|
||||
m.put("region", p.getRegion());
|
||||
m.put("ciudad", p.getCiudad());
|
||||
m.put("updatedAt", formatDate(p.getUpdatedAt(), locale));
|
||||
if(p.getEstado().equals(Presupuesto.Estado.borrador)){
|
||||
m.put("actions",
|
||||
"<div class=\"hstack gap-3 flex-wrap\">" +
|
||||
"<a href=\"javascript:void(0);\" data-id=\"" + p.getId()
|
||||
@ -182,6 +183,14 @@ public class PresupuestoDatatableService {
|
||||
+ "\" class=\"link-danger btn-delete-anonimo fs-15\"><i class=\"ri-delete-bin-5-line\"></i></a>"
|
||||
+
|
||||
"</div>");
|
||||
}
|
||||
else{
|
||||
m.put("actions",
|
||||
"<div class=\"hstack gap-3 flex-wrap\">" +
|
||||
"<a href=\"javascript:void(0);\" data-id=\"" + p.getId()
|
||||
+ "\" class=\"link-success btn-edit-anonimo fs-15\"><i class=\"ri-eye-line\"></i></a>" +
|
||||
"</div>");
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
presupuesto.title=Presupuestos
|
||||
presupuesto.editar.title=Editar presupuesto
|
||||
presupuesto.eliminar=Eliminar presupuesto
|
||||
presupuesto.datos-generales=Datos Generales
|
||||
presupuesto.interior=Interior
|
||||
presupuesto.cubierta=Cubierta
|
||||
@ -265,6 +266,18 @@ presupuesto.marcapaginas.acabado.plastificado-mate-2c=Plastificado mate 2/C
|
||||
presupuesto.marcapaginas.precio-unidad=Precio por unidad
|
||||
presupuesto.marcapaginas.precio-total=Precio total
|
||||
|
||||
# Mensajes de eliminación de presupuesto
|
||||
presupuesto.delete.title=Eliminar presupuesto
|
||||
presupuesto.delete.button=Si, ELIMINAR
|
||||
presupuesto.delete.text=¿Está seguro de que desea eliminar este presupuesto?<br>Esta acción no se puede deshacer.
|
||||
presupuesto.delete.ok.title=Presupuesto eliminado
|
||||
presupuesto.delete.ok.text=El presupuesto ha sido eliminado con éxito.
|
||||
presupuesto.exito.eliminado=Presupuesto eliminado con éxito.
|
||||
presupuesto.error.delete-internal-error=No se puede eliminar: error interno.
|
||||
presupuesto.error.delete-permission-denied=No se puede eliminar: permiso denegado.
|
||||
presupuesto.error.delete-not-found=No se puede eliminar: presupuesto no encontrado.
|
||||
presupuesto.error.delete-not-draft=Solo se pueden eliminar presupuestos en estado Borrador.
|
||||
|
||||
# Errores
|
||||
presupuesto.errores-title=Corrija los siguientes errores:
|
||||
presupuesto.errores.titulo=El título es obligatorio
|
||||
@ -291,4 +304,6 @@ presupuesto.errores.acabado-cubierta=Seleccione el acabado de la cubierta
|
||||
presupuesto.errores.presupuesto-no-existe=El presupuesto con ID {0} no existe.
|
||||
|
||||
presupuesto.errores.presupuesto-maquetacion=No se pudo calcular el presupuesto de maquetación.
|
||||
presupuesto.errores.presupuesto-marcapaginas=No se pudo calcular el presupuesto de marcapáginas.
|
||||
presupuesto.errores.presupuesto-marcapaginas=No se pudo calcular el presupuesto de marcapáginas.
|
||||
|
||||
presupuesto.info.presupuestos-anonimos-view=Estos presupuestos son anónimos y no están asociados a ningún cliente. No se guardarán los cambios (sólo consulta).
|
||||
@ -1,20 +1,24 @@
|
||||
$('.imagen-container-group').on('click', '.image-container', function (e) {
|
||||
e.preventDefault(); // <- evita que el label dispare el cambio nativo (2º change)
|
||||
e.stopPropagation();
|
||||
|
||||
$('.imagen-container-group').on('click', '.image-container', function () {
|
||||
const clicked = $(this);
|
||||
const group = clicked.closest('.imagen-container-group');
|
||||
|
||||
// Limpiar selección anterior
|
||||
// Si ya está seleccionado, no hagas nada
|
||||
const $radio = clicked.find('input[type="radio"]');
|
||||
if ($radio.prop('checked')) return;
|
||||
|
||||
// Limpiar selección anterior (solo clases/animación)
|
||||
group.find('.image-container').removeClass('selected')
|
||||
.find('.image-presupuesto').removeClass('zoom-anim');
|
||||
|
||||
// Marcar nuevo seleccionado
|
||||
// Marcar nuevo seleccionado (clases/animación)
|
||||
clicked.addClass('selected');
|
||||
|
||||
// Aplicar animación de zoom
|
||||
const img = clicked.find('.image-presupuesto');
|
||||
void img[0].offsetWidth; // Forzar reflow
|
||||
void img[0].offsetWidth;
|
||||
img.addClass('zoom-anim');
|
||||
|
||||
|
||||
clicked.find('input[type="radio"]').prop('checked', true).trigger('change');
|
||||
// Marca el radio y dispara UN único change
|
||||
$radio.prop('checked', true).trigger('change');
|
||||
});
|
||||
|
||||
@ -173,6 +173,9 @@ export default class PresupuestoWizard {
|
||||
this.summaryTableSobrecubierta = $('#summary-sobrecubierta');
|
||||
this.summaryTableFaja = $('#summary-faja');
|
||||
this.summaryTableExtras = $('#summary-servicios-extras');
|
||||
|
||||
// variable para evitar disparar eventos al cargar datos
|
||||
this._hydrating = false;
|
||||
}
|
||||
|
||||
async init() {
|
||||
@ -181,9 +184,10 @@ export default class PresupuestoWizard {
|
||||
const mode = root?.dataset.mode || 'public';
|
||||
const presupuestoId = root?.dataset.id || null;
|
||||
|
||||
this.opts = { mode, presupuestoId };
|
||||
|
||||
const stored = sessionStorage.getItem("formData");
|
||||
let stored = null;
|
||||
if(this.opts.useSessionCache) {
|
||||
stored = sessionStorage.getItem("formData");
|
||||
}
|
||||
|
||||
this.#initDatosGenerales();
|
||||
|
||||
@ -261,18 +265,11 @@ export default class PresupuestoWizard {
|
||||
});
|
||||
}
|
||||
|
||||
// Limpiar el sessionStorage al salir de la página
|
||||
window.addEventListener('beforeunload', () => {
|
||||
sessionStorage.removeItem('formData');
|
||||
});
|
||||
}
|
||||
|
||||
#cacheFormData() {
|
||||
if (!this.opts.useSessionCache) return;
|
||||
const key = this.opts.mode === 'edit' && this.opts.presupuestoId
|
||||
? `formData:edit:${this.opts.presupuestoId}`
|
||||
: `formData:${this.opts.mode}`;
|
||||
sessionStorage.setItem(key, JSON.stringify(this.formData));
|
||||
sessionStorage.setItem('formData', JSON.stringify(this.formData));
|
||||
}
|
||||
|
||||
#changeTab(idContenidoTab) {
|
||||
@ -382,8 +379,9 @@ export default class PresupuestoWizard {
|
||||
|
||||
// Eventos para el resumen
|
||||
$(document).on('change', 'input[name="tipoEncuadernacion"]', (e) => {
|
||||
|
||||
if ($(e.target).is(':checked')) {
|
||||
// Actualizar el resumen
|
||||
|
||||
Summary.updateEncuadernacion();
|
||||
}
|
||||
});
|
||||
@ -474,7 +472,7 @@ export default class PresupuestoWizard {
|
||||
paginasNegro: this.paginasNegro.val(),
|
||||
paginasColor: this.paginasColor.val(),
|
||||
posicionPaginasColor: this.posicionPaginasColor.val(),
|
||||
tipoEncuadernacion: ($('.tipo-libro.selected').length > 0) ? $('.tipo-libro.selected').attr('id') : 'fresado',
|
||||
tipoEncuadernacion: $('.tipo-libro input:checked').val() || 'fresado',
|
||||
};
|
||||
}
|
||||
|
||||
@ -519,7 +517,6 @@ export default class PresupuestoWizard {
|
||||
this.alto.val(this.formData.datosGenerales.alto);
|
||||
}
|
||||
|
||||
$('.tipo-libro').removeClass('selected');
|
||||
$('input[name="tipoEncuadernacion"][value="' + this.formData.datosGenerales.tipoEncuadernacion + '"]')
|
||||
.prop('checked', true);
|
||||
this.#updateTipoEncuadernacion();
|
||||
@ -565,7 +562,7 @@ export default class PresupuestoWizard {
|
||||
#updateTipoEncuadernacion() {
|
||||
|
||||
const paginas = parseInt($('#paginas').val());
|
||||
const selectedTipo = $('.tipo-libro.selected').attr('id');
|
||||
const selectedTipo = $('.tipo-libro input:checked').val();
|
||||
$('.tipo-libro').removeClass('selected');
|
||||
|
||||
if (paginas < 32) {
|
||||
@ -591,19 +588,17 @@ export default class PresupuestoWizard {
|
||||
$('.tipo-libro#grapado').removeClass('d-none');
|
||||
}
|
||||
|
||||
if (selectedTipo && $('.tipo-libro#' + selectedTipo).length > 0 && !$('.tipo-libro#' + selectedTipo).hasClass('d-none')) {
|
||||
$('.tipo-libro#' + selectedTipo).addClass('selected');
|
||||
}
|
||||
else {
|
||||
if (!(selectedTipo && $('.tipo-libro#' + selectedTipo).length > 0 && !$('.tipo-libro#' + selectedTipo).hasClass('d-none'))) {
|
||||
|
||||
let firstVisible = $('.tipo-libro').not('.d-none').first();
|
||||
|
||||
if (firstVisible.length) {
|
||||
firstVisible.addClass('selected');
|
||||
firstVisible.trigger('click');
|
||||
}
|
||||
}
|
||||
|
||||
if ($('.tipo-libro.selected').length > 0) {
|
||||
this.formData.datosGenerales.tipoEncuadernacion = $('.tipo-libro.selected').attr('id');
|
||||
if ($('.tipo-libro input:checked').length > 0) {
|
||||
this.formData.datosGenerales.tipoEncuadernacion = $('.tipo-libro input:checked').val();
|
||||
Summary.updateEncuadernacion();
|
||||
}
|
||||
else {
|
||||
@ -629,6 +624,8 @@ export default class PresupuestoWizard {
|
||||
|
||||
|
||||
$(document).on('change', 'input[name="tipoImpresion"]', (e) => {
|
||||
if (!$(e.target).is(':checked'))
|
||||
return;
|
||||
|
||||
const data = this.#getPresupuestoData();
|
||||
Summary.updateTipoImpresion();
|
||||
@ -681,6 +678,10 @@ export default class PresupuestoWizard {
|
||||
|
||||
|
||||
$(document).on('change', 'input[name="papelInterior"]', (e) => {
|
||||
|
||||
if (!$(e.target).is(':checked'))
|
||||
return;
|
||||
|
||||
const data = this.#getPresupuestoData();
|
||||
|
||||
Summary.updatePapelInterior();
|
||||
@ -951,6 +952,12 @@ export default class PresupuestoWizard {
|
||||
|
||||
$(document).on('change', 'input[name="tipoCubierta"]', (e) => {
|
||||
|
||||
if (!$(e.target).is(':checked'))
|
||||
return;
|
||||
|
||||
if(this._hydrating)
|
||||
return;
|
||||
|
||||
$('.tapa-dura-options').eq(0).removeClass('animate-fadeInUpBounce');
|
||||
$('.tapa-blanda-options').eq(0).removeClass('animate-fadeInUpBounce');
|
||||
|
||||
@ -971,6 +978,9 @@ export default class PresupuestoWizard {
|
||||
|
||||
$(document).on('change', 'input[name="solapasCubierta"]', (e) => {
|
||||
|
||||
if (!$(e.target).is(':checked'))
|
||||
return;
|
||||
|
||||
if (e.currentTarget.closest('.image-container').id === 'sin-solapas') {
|
||||
this.divSolapasCubierta.addClass('d-none');
|
||||
}
|
||||
@ -986,7 +996,7 @@ export default class PresupuestoWizard {
|
||||
});
|
||||
|
||||
|
||||
$(document).on('click', '.papel-cubierta', (e) => {
|
||||
$(document).on('change', 'input[name="papel-cubierta"]', (e) => {
|
||||
|
||||
const data = this.#getPresupuestoData();
|
||||
|
||||
@ -1026,6 +1036,9 @@ export default class PresupuestoWizard {
|
||||
|
||||
$(document).on('change', '.datos-cubierta', (e) => {
|
||||
|
||||
if(this._hydrating)
|
||||
return;
|
||||
|
||||
const dataToStore = this.#getCubiertaData();
|
||||
this.#updateCubiertaData(dataToStore);
|
||||
this.#cacheFormData();
|
||||
@ -1165,13 +1178,13 @@ export default class PresupuestoWizard {
|
||||
if (item.extraData["sk-id"] == this.formData.cubierta.papelCubiertaId) {
|
||||
item.setSelected(true);
|
||||
}
|
||||
item.group='papel-cubierta';
|
||||
this.divPapelCubierta.append(item.render());
|
||||
}
|
||||
|
||||
if (this.divPapelCubierta.find('.image-container.selected').length === 0) {
|
||||
this.divPapelCubierta.find('.image-container').first().addClass('selected');
|
||||
this.formData.cubierta.papelCubiertaId =
|
||||
this.divPapelCubierta.find('.image-container').first().data('sk-id') || 3;
|
||||
if (this.divPapelCubierta.find('input[name="papel-cubierta"]:checked').length === 0) {
|
||||
|
||||
this.divPapelCubierta.find('input[name="papel-cubierta"]').first().prop('checked', true).trigger('change');
|
||||
}
|
||||
|
||||
this.#addGramajesCubierta(data.opciones_gramaje_cubierta);
|
||||
@ -1192,13 +1205,13 @@ export default class PresupuestoWizard {
|
||||
|
||||
#getCubiertaData() {
|
||||
|
||||
const tipoCubierta = $('.tapa-cubierta.selected').attr('id') || 'tapaBlanda';
|
||||
const solapas = $('.solapas-cubierta.selected').id == 'sin-solapas' ? 0 : 1 || 0;
|
||||
const tipoCubierta = $('.tapa-cubierta input:checked').val() || 'tapaBlanda';
|
||||
const solapas = $('.solapas-cubierta input:checked').val() == 'sin-solapas' ? 0 : 1 || 0;
|
||||
const tamanioSolapasCubierta = $('#tamanio-solapas-cubierta').val() || '80';
|
||||
const cubiertaCaras = parseInt(this.carasImpresionCubierta.val()) || 2;
|
||||
const papelGuardasId = parseInt($('#papel-guardas option:selected').data('papel-id')) || 3;
|
||||
const gramajeGuardas = parseInt($('#papel-guardas option:selected').data('gramaje')) || 170;
|
||||
const guardasImpresas = parseInt(this.guardasImpresas) || 0;
|
||||
const guardasImpresas = parseInt(this.guardasImpresas.val()) || 0;
|
||||
const cabezada = this.cabezada.val() || 'WHI';
|
||||
const papelCubiertaId = $('#div-papel-cubierta .image-container input:checked').parent().data('sk-id') || this.formData.cubierta.papelCubiertaId || 3;
|
||||
const gramajeCubierta = $('input[name="gramaje-cubierta"]:checked').data('gramaje') || this.formData.cubierta.gramajeCubierta || 170;
|
||||
@ -1279,7 +1292,7 @@ export default class PresupuestoWizard {
|
||||
|
||||
for (let i = 0; i < gramajes.length; i++) {
|
||||
const gramaje = gramajes[i];
|
||||
this.#addGramaje(this.divGramajeCubierta, 'gramaje-cubierta datos-cubierta', gramaje, 'gramaje-cubierta');
|
||||
this.#addGramaje(this.divGramajeCubierta, 'gramaje-cubierta', gramaje, 'gramaje-cubierta');
|
||||
|
||||
// Seleccionar el gramaje por defecto
|
||||
if (this.formData.cubierta.gramajeCubierta === '' && i === 0) {
|
||||
@ -1298,9 +1311,11 @@ export default class PresupuestoWizard {
|
||||
|
||||
#loadCubiertaData() {
|
||||
|
||||
this._hydrating = true;
|
||||
|
||||
$('input[name="tipoCubierta"][value="' + this.formData.cubierta.tipoCubierta + '"]')
|
||||
.prop('checked', true);
|
||||
|
||||
|
||||
if (this.formData.cubierta.tipoCubierta === 'tapaBlanda') {
|
||||
$('.tapa-blanda-options').removeClass('d-none');
|
||||
$('.tapa-dura-options').addClass('d-none');
|
||||
@ -1315,15 +1330,16 @@ export default class PresupuestoWizard {
|
||||
this.cabezada.val(this.formData.cubierta.cabezada);
|
||||
}
|
||||
|
||||
this._hydrating = false;
|
||||
|
||||
$('input[name="tipoCubierta"][value="' + this.formData.cubierta.tipoCubierta + '"]').trigger('change');
|
||||
|
||||
if (this.formData.cubierta.solapasCubierta === 0) {
|
||||
$('.solapas-cubierta#sin-solapas').addClass('selected');
|
||||
$('.solapas-cubierta#sin-solapas input').prop('checked', true);
|
||||
this.divSolapasCubierta.addClass('d-none');
|
||||
}
|
||||
else {
|
||||
$('.solapas-cubierta').removeClass('selected');
|
||||
$(`.solapas-cubierta#con-solapas`).addClass('selected');
|
||||
$('.solapas-cubierta#con-solapas input').prop('checked', true);
|
||||
this.divSolapasCubierta.removeClass('d-none');
|
||||
this.carasImpresionCubierta.val(this.formData.cubierta.cubiertaCaras);
|
||||
this.tamanioSolapasCubierta.val(this.formData.cubierta.tamanioSolapasCubierta);
|
||||
|
||||
@ -67,6 +67,7 @@
|
||||
});
|
||||
|
||||
$('#presupuestos-anonimos-datatable').on('click', '.btn-edit-anonimo', function (e) {
|
||||
|
||||
e.preventDefault();
|
||||
const id = $(this).data('id');
|
||||
if (id) {
|
||||
@ -74,5 +75,48 @@
|
||||
}
|
||||
});
|
||||
|
||||
$('#presupuestos-anonimos-datatable').on('click', '.btn-delete-anonimo', function (e) {
|
||||
|
||||
e.preventDefault();
|
||||
const id = $(this).data('id');
|
||||
|
||||
Swal.fire({
|
||||
title: window.languageBundle.get(['presupuesto.delete.title']) || 'Eliminar presupuesto',
|
||||
html: window.languageBundle.get(['presupuesto.delete.text']) || 'Esta acción no se puede deshacer.',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-danger w-xs mt-2',
|
||||
cancelButton: 'btn btn-light w-xs mt-2'
|
||||
},
|
||||
confirmButtonText: window.languageBundle.get(['presupuesto.delete.button']) || 'Eliminar',
|
||||
cancelButtonText: window.languageBundle.get(['app.cancelar']) || 'Cancelar',
|
||||
}).then((result) => {
|
||||
if (!result.isConfirmed) return;
|
||||
|
||||
$.ajax({
|
||||
url: '/presupuesto/' + id,
|
||||
type: 'DELETE',
|
||||
success: function () {
|
||||
Swal.fire({
|
||||
icon: 'success', title: window.languageBundle.get(['presupuesto.delete.ok.title']) || 'Eliminado',
|
||||
text: window.languageBundle.get(['presupuesto.delete.ok.text']) || 'El presupuesto ha sido eliminado con éxito.',
|
||||
showConfirmButton: true,
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-secondary w-xs mt-2',
|
||||
},
|
||||
});
|
||||
$('#presupuestos-anonimos-datatable').DataTable().ajax.reload(null, false);
|
||||
},
|
||||
error: function (xhr) {
|
||||
// usa el mensaje del backend; fallback genérico por si no llega JSON
|
||||
const msg = (xhr.responseJSON && xhr.responseJSON.message)
|
||||
|| 'Error al eliminar el presupuesto.';
|
||||
Swal.fire({ icon: 'error', title: 'No se pudo eliminar', text: msg });
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
@ -60,7 +60,7 @@
|
||||
<div th:if="${#authentication.principal.role == 'SUPERADMIN'}">
|
||||
<li class="nav-item">
|
||||
<a href="/configuracion/margenes-presupuesto" class="nav-link">
|
||||
<i class="ri-discount-percent-line"></i>
|
||||
<i class="ri-percent-line"></i>
|
||||
<span th:text="#{margenes-presupuesto.titulo}">Márgenes de presupuesto</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
<div class="card-body checkout-tab">
|
||||
|
||||
<form action="#">
|
||||
<input type="hidden" id="cliente_id" th:value="${cliente_id} ?: null" />
|
||||
<div class="step-arrow-nav mt-n3 mx-n3 mb-3">
|
||||
|
||||
<ul class="nav nav-pills nav-justified custom-nav" role="tablist">
|
||||
|
||||
@ -37,6 +37,12 @@
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- alert info -->
|
||||
<div th:if="${appMode} == 'view'" class="alert alert-warning fade show" role="alert">
|
||||
<i class="ri-information-fill me-1 align-middle"></i>
|
||||
<span th:text="#{presupuesto.info.presupuestos-anonimos-view}"></span>
|
||||
</div>
|
||||
|
||||
<div th:insert="~{imprimelibros/presupuestos/presupuestador :: presupuestador}"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user