trabajando en el delete

This commit is contained in:
2025-10-10 13:28:03 +02:00
parent 6c4b63daa6
commit d4d83fe118
11 changed files with 221 additions and 55 deletions

View File

@ -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)));
}
}