a falta del pago

This commit is contained in:
2025-11-02 11:57:05 +01:00
parent 51d22515e8
commit 4d451cc85e
17 changed files with 429 additions and 208 deletions

View File

@ -291,6 +291,7 @@ public class CartService {
summary.put("fidelizacion", fidelizacion + "%");
summary.put("descuento", Utils.formatCurrency(-descuento, locale));
summary.put("total", Utils.formatCurrency(total, locale));
summary.put("amountCents", Math.round(total * 100));
summary.put("errorShipmentCost", errorShipementCost);
return summary;

View File

@ -6,17 +6,20 @@ import java.util.Locale;
import java.util.Map;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.server.ResponseStatusException;
import com.imprimelibros.erp.common.Utils;
import com.imprimelibros.erp.i18n.TranslationService;
import com.imprimelibros.erp.paises.PaisesService;
import com.imprimelibros.erp.direcciones.Direccion;
import com.imprimelibros.erp.direcciones.DireccionService;
import com.imprimelibros.erp.cart.Cart;
import com.imprimelibros.erp.cart.CartService;
@Controller
@ -44,23 +47,29 @@ public class CheckoutController {
List<String> keys = List.of(
"app.cancelar",
"app.seleccionar",
"checkout.shipping.add.title",
"checkout.shipping.select-placeholder",
"checkout.shipping.new-address",
"app.yes",
"app.cancelar");
"checkout.billing-address.title",
"checkout.billing-address.new-address",
"checkout.billing-address.select-placeholder",
"checkout.billing-address.errors.noAddressSelected");
Map<String, String> translations = translationService.getTranslations(locale, keys);
model.addAttribute("languageBundle", translations);
var items = this.cartService.listItems(Utils.currentUserId(principal), locale);
for (var item : items) {
if (item.get("hasSample") != null && (Boolean) item.get("hasSample")) {
model.addAttribute("hasSample", true);
break;
}
}
model.addAttribute("items", items);
Long userId = Utils.currentUserId(principal);
Cart cart = cartService.getOrCreateActiveCart(userId);
model.addAttribute("summary", cartService.getCartSummary(cart, locale));
return "imprimelibros/checkout/checkout"; // crea esta vista si quieres (tabla simple)
}
@GetMapping("/get-address/{id}")
public String getDireccionCard(@PathVariable Long id, Model model, Locale locale) {
Direccion dir = direccionService.findById(id)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
model.addAttribute("pais", messageSource.getMessage("paises." + dir.getPais().getKeyword(), null,
dir.getPais().getKeyword(), locale));
model.addAttribute("direccion", dir);
return "imprimelibros/direcciones/direccionBillingCard :: direccionBillingCard(direccion=${direccion}, pais=${pais})";
}
}

View File

@ -506,6 +506,29 @@ public class DireccionController {
}
@GetMapping(value = "/facturacion/select2", produces = "application/json")
@ResponseBody
public Map<String, Object> getSelect2Facturacion(
@RequestParam(value = "q", required = false) String q1,
@RequestParam(value = "term", required = false) String q2,
Authentication auth) {
boolean isAdmin = auth.getAuthorities().stream()
.anyMatch(a -> a.getAuthority().equals("ROLE_ADMIN") || a.getAuthority().equals("ROLE_SUPERADMIN"));
Long currentUserId = null;
if (!isAdmin) {
if (auth != null && auth.getPrincipal() instanceof UserDetailsImpl udi) {
currentUserId = udi.getId();
} else if (auth != null) {
currentUserId = userRepo.findIdByUserNameIgnoreCase(auth.getName()).orElse(null);
}
}
return direccionService.getForSelectFacturacion(q1, q2, isAdmin ? null : currentUserId);
}
private boolean isOwnerOrAdmin(Authentication auth, Long ownerId) {
if (auth == null) {
return false;

View File

@ -38,6 +38,10 @@ public interface DireccionRepository
// find by user_id
List<Direccion> findByUserId(Long userId);
// find by user_id and direccion_facturacion = true
@Query("SELECT d FROM Direccion d WHERE (:userId IS NULL OR d.user.id = :userId) AND d.direccionFacturacion = true")
List<Direccion> findByUserIdAndDireccionFacturacion(@Param("userId") Long userId);
// find by user_id with deleted
@Query(value = "SELECT * FROM direcciones WHERE user_id = :userId", nativeQuery = true)
List<Direccion> findByUserIdWithDeleted(@Param("userId") Long userId);

View File

@ -77,6 +77,65 @@ public class DireccionService {
}
}
public Map<String, Object> getForSelectFacturacion(String q1, String q2, Long userId) {
try {
// Termino de búsqueda (Select2 usa 'q' o 'term' según versión/config)
String search = Optional.ofNullable(q1).orElse(q2);
if (search != null) {
search = search.trim();
}
final String q = (search == null || search.isEmpty())
? null
: search.toLowerCase();
List<Direccion> all = repo.findByUserIdAndDireccionFacturacion(userId);
// Mapear a opciones id/text con i18n y filtrar por búsqueda si llega
List<Map<String, String>> options = all.stream()
.map(cc -> {
String id = cc.getId().toString();
String alias = cc.getAlias();
String direccion = cc.getDireccion();
String cp = String.valueOf(cc.getCp());
String ciudad = cc.getCiudad();
String att = cc.getAtt();
Map<String, String> m = new HashMap<>();
m.put("id", id); // lo normal en Select2: id = valor que guardarás (code3)
m.put("text", alias); // texto mostrado, i18n con fallback a keyword
m.put("cp", cp);
m.put("ciudad", ciudad);
m.put("att", att);
m.put("alias", alias);
m.put("direccion", direccion);
return m;
})
.filter(opt -> {
if (q == null || q.isEmpty())
return true;
String cp = opt.get("cp");
String ciudad = opt.get("ciudad").toLowerCase();
String att = opt.get("att").toLowerCase();
String alias = opt.get("alias").toLowerCase();
String text = opt.get("text").toLowerCase();
String direccion = opt.get("direccion").toLowerCase();
return text.contains(q) || cp.contains(q) || ciudad.contains(q) || att.contains(q)
|| alias.contains(q) || direccion.contains(q);
})
.sorted(Comparator.comparing(m -> m.get("text"), Collator.getInstance()))
.collect(Collectors.toList());
// Estructura Select2
Map<String, Object> resp = new HashMap<>();
resp.put("results", options);
return resp;
} catch (Exception e) {
e.printStackTrace();
return Map.of("results", List.of());
}
}
public Optional<Direccion> findById(Long id) {
return repo.findById(id);
}