terminado carrito

This commit is contained in:
2025-10-31 11:36:03 +01:00
parent 90c191d8f8
commit 40dc719e89
13 changed files with 234 additions and 59 deletions

View File

@ -59,6 +59,8 @@ public class CartController {
"cart.shipping.send-in-palets",
"cart.shipping.send-in-palets.info",
"cart.shipping.tipo-envio",
"cart.pass-to.customer.error",
"cart.pass-to.customer.error-move",
"app.yes",
"app.aceptar",
"app.cancelar");
@ -73,14 +75,14 @@ public class CartController {
model.addAttribute("items", items);
Map<String, Object> direcciones = service.getCartDirecciones(cart.getId(), locale);
if(direcciones != null && direcciones.containsKey("mainDir"))
if (direcciones != null && direcciones.containsKey("mainDir"))
model.addAttribute("mainDir", direcciones.get("mainDir"));
else if(direcciones != null && direcciones.containsKey("direcciones"))
else if (direcciones != null && direcciones.containsKey("direcciones"))
model.addAttribute("direcciones", direcciones.get("direcciones"));
var summary = service.getCartSummary(cart, locale);
model.addAttribute("cartSummary", summary);
if(summary.get("errorShipmentCost") != null && (Boolean)summary.get("errorShipmentCost"))
if (summary.get("errorShipmentCost") != null && (Boolean) summary.get("errorShipmentCost"))
model.addAttribute("errorEnvio", true);
else
model.addAttribute("errorEnvio", false);
@ -158,7 +160,8 @@ public class CartController {
}
@PostMapping(value = "/update/{id}", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String updateCart(@PathVariable Long id, UpdateCartRequest updateRequest, Model model, Locale locale, Principal principal) {
public String updateCart(@PathVariable Long id, UpdateCartRequest updateRequest, Model model, Locale locale,
Principal principal) {
try {
service.updateCart(id, updateRequest);
@ -174,7 +177,26 @@ public class CartController {
model.addAttribute("errorMessage", errorMessage);
return "redirect:/cart";
}
}
@PostMapping(value = "/pass-to-customer/{customerId}")
public ResponseEntity<?> moveToCustomer(
@PathVariable Long customerId,
Principal principal) {
if(!Utils.isCurrentUserAdmin()) {
return ResponseEntity.status(403).body(Map.of("error", "Forbidden"));
}
Long userId = Utils.currentUserId(principal);
Cart cart = service.getOrCreateActiveCart(userId);
boolean ok = service.moveCartToCustomer(cart.getId(), customerId);
if (ok)
return ResponseEntity.ok().build();
return ResponseEntity.status(400).body(Map.of("error", "cart.errors.move-cart"));
}
}

View File

@ -112,8 +112,9 @@ public class CartService {
@Transactional
public void removeByPresupuesto(Long userId, Long presupuestoId) {
Cart cart = getOrCreateActiveCart(userId);
itemRepo.findByCartIdAndPresupuestoId(cart.getId(), presupuestoId)
.ifPresent(itemRepo::delete);
CartItem item = itemRepo.findByCartIdAndPresupuestoId(cart.getId(), presupuestoId)
.orElseThrow(() -> new IllegalArgumentException("Item no encontrado"));
itemRepo.deleteById(item.getId());
}
/** Vacía todo el carrito activo. */
@ -355,6 +356,33 @@ public class CartService {
}
}
public Boolean moveCartToCustomer(Long cartId, Long customerId) {
try {
// Remove the cart from the customer if they have one
Cart existingCart = cartRepo.findByUserIdAndStatus(customerId, Cart.Status.ACTIVE)
.orElse(null);
if (existingCart != null) {
cartRepo.delete(existingCart);
}
Cart cart = cartRepo.findById(cartId)
.orElseThrow(() -> new IllegalArgumentException("Carrito no encontrado"));
cart.setUserId(customerId);
cartRepo.save(cart);
return true;
} catch (Exception e) {
// Manejo de excepciones
return false;
}
}
/***************************************
* MÉTODOS PRIVADOS
***************************************/
private Map<String, Object> getShippingCost(
CartDireccion cd,
Double peso,

View File

@ -14,6 +14,7 @@ import java.util.function.BiFunction;
import org.springframework.context.MessageSource;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.core.JsonProcessingException;
@ -44,6 +45,12 @@ public class Utils {
this.messageSource = messageSource;
}
public static boolean isCurrentUserAdmin() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
return auth.getAuthorities().stream()
.anyMatch(a -> a.getAuthority().equals("ROLE_ADMIN") || a.getAuthority().equals("ROLE_SUPERADMIN"));
}
public static Long currentUserId(Principal principal) {
if (principal == null) {

View File

@ -4,6 +4,7 @@ import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import java.security.Principal;
import java.time.Instant;
import java.util.HashMap;
import java.util.Locale;
@ -621,14 +622,14 @@ public class PresupuestoController {
@ResponseBody
public DataTablesResponse<Map<String, Object>> datatable(
HttpServletRequest request, Authentication auth, Locale locale,
@PathVariable("tipo") String tipo) {
@PathVariable("tipo") String tipo, Principal principal) {
DataTablesRequest dt = DataTablesParser.from(request);
if ("anonimos".equals(tipo)) {
return dtService.datatablePublicos(dt, locale);
return dtService.datatablePublicos(dt, locale, principal);
} else if ("clientes".equals(tipo)) {
return dtService.datatablePrivados(dt, locale);
return dtService.datatablePrivados(dt, locale, principal);
} else {
throw new IllegalArgumentException("Tipo de datatable no válido");
}

View File

@ -1,15 +1,18 @@
package com.imprimelibros.erp.presupuesto;
import com.imprimelibros.erp.common.Utils;
import com.imprimelibros.erp.configuracion.margenes_presupuestos.MargenPresupuesto;
import com.imprimelibros.erp.datatables.*;
import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
import jakarta.persistence.criteria.Expression;
import org.springframework.context.MessageSource;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.security.Principal;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
@ -26,18 +29,29 @@ public class PresupuestoDatatableService {
}
@Transactional(readOnly = true)
public DataTablesResponse<Map<String, Object>> datatablePublicos(DataTablesRequest dt, Locale locale) {
return commonDataTable(dt, locale, "publico", true);
public DataTablesResponse<Map<String, Object>> datatablePublicos(DataTablesRequest dt, Locale locale,
Principal principal) {
return commonDataTable(dt, locale, "publico", true, principal);
}
@Transactional(readOnly = true)
public DataTablesResponse<Map<String, Object>> datatablePrivados(DataTablesRequest dt, Locale locale) {
return commonDataTable(dt, locale, "privado", false);
public DataTablesResponse<Map<String, Object>> datatablePrivados(DataTablesRequest dt, Locale locale,
Principal principal) {
return commonDataTable(dt, locale, "privado", false, principal);
}
private DataTablesResponse<Map<String, Object>> commonDataTable(DataTablesRequest dt, Locale locale, String origen,
boolean publico) {
Long count = repo.findAllByOrigen(Presupuesto.Origen.valueOf(origen)).stream().count();
boolean publico, Principal principal) {
Specification<Presupuesto> base = Specification.allOf(
(root, query, cb) -> cb.equal(root.get("origen"), Presupuesto.Origen.valueOf(origen)));
Boolean isAdmin = Utils.isCurrentUserAdmin();
if (!isAdmin) {
base = base.and((root, query, cb) -> cb.equal(root.get("user").get("id"), Utils.currentUserId(principal)));
}
Long count = repo.count(base);
List<String> orderable = List.of(
"id", "titulo", "user.fullName", "tipoEncuadernacion", "tipoCubierta", "tipoImpresion",
@ -74,6 +88,7 @@ public class PresupuestoDatatableService {
.add("updatedAt", p -> formatDate(p.getUpdatedAt(), locale))
.addIf(!publico, "user", p -> p.getUser() != null ? p.getUser().getFullName() : "")
.add("actions", this::generarBotones)
.where(base)
.toJson(count);
}

View File

@ -1,6 +1,9 @@
package com.imprimelibros.erp.users;
import org.springframework.security.core.userdetails.UserDetailsService;
import java.util.Map;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

View File

@ -2,10 +2,21 @@ package com.imprimelibros.erp.users;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import java.text.Collator;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import com.imprimelibros.erp.direcciones.Direccion;
@Service
public class UserServiceImpl implements UserService {
@ -29,5 +40,4 @@ public class UserServiceImpl implements UserService {
if (query == null || query.isBlank()) query = null;
return userDao.searchUsers(role, query, pageable);
}
}