mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-13 00:48:49 +00:00
haciendo pagos pendientes
This commit is contained in:
@ -5,6 +5,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -20,15 +21,17 @@ import com.imprimelibros.erp.cart.dto.DireccionCardDTO;
|
||||
import com.imprimelibros.erp.cart.dto.DireccionShipment;
|
||||
import com.imprimelibros.erp.cart.dto.UpdateCartRequest;
|
||||
import com.imprimelibros.erp.common.Utils;
|
||||
import com.imprimelibros.erp.common.email.EmailService;
|
||||
import com.imprimelibros.erp.direcciones.DireccionService;
|
||||
import com.imprimelibros.erp.externalApi.skApiClient;
|
||||
import com.imprimelibros.erp.pedidos.Pedido;
|
||||
import com.imprimelibros.erp.pedidos.PedidoService;
|
||||
import com.imprimelibros.erp.pedidos.PedidoRepository;
|
||||
import com.imprimelibros.erp.presupuesto.PresupuestoRepository;
|
||||
|
||||
@Service
|
||||
public class CartService {
|
||||
|
||||
private final EmailService emailService;
|
||||
|
||||
private final CartRepository cartRepo;
|
||||
private final CartDireccionRepository cartDireccionRepo;
|
||||
private final CartItemRepository itemRepo;
|
||||
@ -36,14 +39,13 @@ public class CartService {
|
||||
private final PresupuestoRepository presupuestoRepo;
|
||||
private final DireccionService direccionService;
|
||||
private final skApiClient skApiClient;
|
||||
private final PedidoService pedidoService;
|
||||
private final PresupuestoService presupuestoService;
|
||||
private final PedidoRepository pedidoRepository;
|
||||
|
||||
public CartService(CartRepository cartRepo, CartItemRepository itemRepo,
|
||||
CartDireccionRepository cartDireccionRepo, MessageSource messageSource,
|
||||
PresupuestoFormatter presupuestoFormatter, PresupuestoRepository presupuestoRepo,
|
||||
DireccionService direccionService, skApiClient skApiClient,
|
||||
PedidoService pedidoService, PresupuestoService presupuestoService) {
|
||||
PresupuestoFormatter presupuestoFormatter, PresupuestoRepository presupuestoRepo, PedidoRepository pedidoRepository,
|
||||
DireccionService direccionService, skApiClient skApiClient,PresupuestoService presupuestoService, EmailService emailService) {
|
||||
this.cartRepo = cartRepo;
|
||||
this.itemRepo = itemRepo;
|
||||
this.cartDireccionRepo = cartDireccionRepo;
|
||||
@ -51,8 +53,9 @@ public class CartService {
|
||||
this.presupuestoRepo = presupuestoRepo;
|
||||
this.direccionService = direccionService;
|
||||
this.skApiClient = skApiClient;
|
||||
this.pedidoService = pedidoService;
|
||||
this.presupuestoService = presupuestoService;
|
||||
this.emailService = emailService;
|
||||
this.pedidoRepository = pedidoRepository;
|
||||
}
|
||||
|
||||
public Cart findById(Long cartId) {
|
||||
@ -264,7 +267,7 @@ public class CartService {
|
||||
}
|
||||
|
||||
double totalBeforeDiscount = base + iva4 + iva21 + shipment;
|
||||
int fidelizacion = pedidoService.getDescuentoFidelizacion(cart.getUserId());
|
||||
int fidelizacion = this.getDescuentoFidelizacion(cart.getUserId());
|
||||
double descuento = totalBeforeDiscount * fidelizacion / 100.0;
|
||||
double total = totalBeforeDiscount - descuento;
|
||||
|
||||
@ -291,6 +294,27 @@ public class CartService {
|
||||
return summary;
|
||||
}
|
||||
|
||||
public int getDescuentoFidelizacion(Long userId) {
|
||||
// descuento entre el 1% y el 6% para clientes fidelidad (mas de 1500€ en el
|
||||
// ultimo año)
|
||||
Instant haceUnAno = Instant.now().minusSeconds(365 * 24 * 60 * 60);
|
||||
double totalGastado = pedidoRepository.sumTotalByCreatedByAndCreatedAtAfter(userId, haceUnAno);
|
||||
if (totalGastado < 1200) {
|
||||
return 0;
|
||||
} else if (totalGastado >= 1200 && totalGastado < 1999) {
|
||||
return 1;
|
||||
} else if (totalGastado >= 2000 && totalGastado < 2999) {
|
||||
return 2;
|
||||
} else if (totalGastado >= 3000 && totalGastado < 3999) {
|
||||
return 3;
|
||||
} else if (totalGastado >= 4000 && totalGastado < 4999) {
|
||||
return 4;
|
||||
} else if (totalGastado >= 5000) {
|
||||
return 5;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Map<String, Object> getCartSummary(Cart cart, Locale locale) {
|
||||
Map<String, Object> raw = getCartSummaryRaw(cart, locale);
|
||||
|
||||
@ -411,184 +435,6 @@ public class CartService {
|
||||
cartDireccionRepo.deleteByDireccionIdAndCartStatus(direccionId, Cart.Status.ACTIVE);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long crearPedido(Long cartId, Long dirFactId, Locale locale) {
|
||||
|
||||
Cart cart = this.getCartById(cartId);
|
||||
List<CartItem> items = cart.getItems();
|
||||
|
||||
List<Map<String, Object>> presupuestoRequests = new ArrayList<>();
|
||||
Map<String, Object> presupuestoDireccionesRequest = new HashMap<>();
|
||||
List<Long> presupuestoIds = new ArrayList<>();
|
||||
|
||||
for (Integer i = 0; i < items.size(); i++) {
|
||||
CartItem item = items.get(i);
|
||||
Presupuesto pCart = item.getPresupuesto();
|
||||
|
||||
// Asegurarnos de trabajar con la entidad gestionada por JPA
|
||||
Presupuesto p = presupuestoRepo.findById(pCart.getId())
|
||||
.orElseThrow(() -> new IllegalStateException("Presupuesto no encontrado: " + pCart.getId()));
|
||||
|
||||
Map<String, Object> data_to_send = presupuestoService.toSkApiRequest(p, true);
|
||||
data_to_send.put("createPedido", 0);
|
||||
|
||||
// Recuperar el mapa anidado datosCabecera
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> datosCabecera = (Map<String, Object>) data_to_send.get("datosCabecera");
|
||||
if (datosCabecera != null) {
|
||||
Object tituloOriginal = datosCabecera.get("titulo");
|
||||
datosCabecera.put(
|
||||
"titulo",
|
||||
"[" + (i + 1) + "/" + items.size() + "] " + (tituloOriginal != null ? tituloOriginal : ""));
|
||||
}
|
||||
|
||||
Map<String, Object> direcciones_presupuesto = this.getDireccionesPresupuesto(cart, p);
|
||||
data_to_send.put("direcciones", direcciones_presupuesto.get("direcciones"));
|
||||
data_to_send.put("direccionesFP1", direcciones_presupuesto.get("direccionesFP1"));
|
||||
|
||||
presupuestoDireccionesRequest.put(p.getId().toString(), direcciones_presupuesto);
|
||||
|
||||
Map<String, Object> result = skApiClient.savePresupuesto(data_to_send);
|
||||
|
||||
if (result.containsKey("error")) {
|
||||
System.out.println("Error al guardar presupuesto en SK");
|
||||
System.out.println("-------------------------");
|
||||
System.out.println(result.get("error"));
|
||||
// decide si seguir con otros items o abortar:
|
||||
// continue; o bien throw ...
|
||||
continue;
|
||||
}
|
||||
|
||||
Object dataObj = result.get("data");
|
||||
if (!(dataObj instanceof Map<?, ?> dataRaw)) {
|
||||
System.out.println("Formato inesperado de 'data' en savePresupuesto: " + result);
|
||||
continue;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> dataMap = (Map<String, Object>) dataRaw;
|
||||
Long presId = ((Number) dataMap.get("id")).longValue();
|
||||
String skin = ((String) dataMap.get("iskn")).toString();
|
||||
p.setProveedor("Safekat");
|
||||
p.setProveedorRef1(skin);
|
||||
p.setProveedorRef2(presId);
|
||||
p.setEstado(Presupuesto.Estado.aceptado);
|
||||
presupuestoRepo.save(p);
|
||||
|
||||
presupuestoIds.add(p.getId());
|
||||
|
||||
presupuestoRequests.add(dataMap);
|
||||
}
|
||||
|
||||
// Crear el pedido en base a los presupuestos guardados
|
||||
if (presupuestoRequests.isEmpty()) {
|
||||
throw new IllegalStateException("No se pudieron guardar los presupuestos en SK.");
|
||||
} else {
|
||||
ArrayList<Long> presupuestoSkIds = new ArrayList<>();
|
||||
for (Map<String, Object> presData : presupuestoRequests) {
|
||||
Long presId = ((Number) presData.get("id")).longValue();
|
||||
presupuestoSkIds.add(presId);
|
||||
}
|
||||
Map<String, Object> ids = new HashMap<>();
|
||||
ids.put("presupuesto_ids", presupuestoSkIds);
|
||||
Long pedidoId = skApiClient.crearPedido(ids);
|
||||
if (pedidoId == null) {
|
||||
throw new IllegalStateException("No se pudo crear el pedido en SK.");
|
||||
}
|
||||
Pedido pedidoInterno = pedidoService.crearPedido(
|
||||
presupuestoIds,
|
||||
presupuestoDireccionesRequest,
|
||||
dirFactId,
|
||||
this.getCartSummaryRaw(cart, locale),
|
||||
"Safekat",
|
||||
String.valueOf(pedidoId),
|
||||
cart.getUserId());
|
||||
return pedidoInterno.getId();
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Object> getDireccionesPresupuesto(Cart cart, Presupuesto presupuesto) {
|
||||
|
||||
List<Map<String, Object>> direccionesPresupuesto = new ArrayList<>();
|
||||
List<Map<String, Object>> direccionesPrueba = new ArrayList<>();
|
||||
if (cart.getOnlyOneShipment()) {
|
||||
List<CartDireccion> direcciones = cart.getDirecciones().stream().limit(1).toList();
|
||||
if (!direcciones.isEmpty()) {
|
||||
if (presupuesto.getServiciosJson() != null
|
||||
&& presupuesto.getServiciosJson().contains("deposito-legal")) {
|
||||
direccionesPresupuesto.add(direcciones.get(0).toSkMap(
|
||||
presupuesto.getSelectedTirada(),
|
||||
presupuesto.getPeso(),
|
||||
direcciones.get(0).getIsPalets(),
|
||||
false));
|
||||
|
||||
direccionesPresupuesto.add(direcciones.get(0).toSkMapDepositoLegal());
|
||||
}
|
||||
else {
|
||||
direccionesPresupuesto.add(direcciones.get(0).toSkMap(
|
||||
presupuesto.getSelectedTirada(),
|
||||
presupuesto.getPeso(),
|
||||
direcciones.get(0).getIsPalets(),
|
||||
false));
|
||||
}
|
||||
if (presupuesto.getServiciosJson() != null
|
||||
&& presupuesto.getServiciosJson().contains("ejemplar-prueba")) {
|
||||
direccionesPrueba.add(direcciones.get(0).toSkMap(
|
||||
1,
|
||||
presupuesto.getPeso(),
|
||||
false,
|
||||
true));
|
||||
}
|
||||
|
||||
Map<String, Object> direccionesRet = new HashMap<>();
|
||||
direccionesRet.put("direcciones", direccionesPresupuesto);
|
||||
if (!direccionesPrueba.isEmpty())
|
||||
direccionesRet.put("direccionesFP1", direccionesPrueba.get(0));
|
||||
else {
|
||||
direccionesRet.put("direccionesFP1", new ArrayList<>());
|
||||
}
|
||||
return direccionesRet;
|
||||
}
|
||||
} else {
|
||||
List<CartDireccion> direcciones = cart.getDirecciones().stream()
|
||||
.filter(d -> d.getPresupuesto() != null && d.getPresupuesto().getId().equals(presupuesto.getId()))
|
||||
.toList();
|
||||
|
||||
for (CartDireccion cd : direcciones) {
|
||||
|
||||
// direccion de ejemplar de prueba
|
||||
if (cd.getPresupuesto() == null || !cd.getPresupuesto().getId().equals(presupuesto.getId())) {
|
||||
continue;
|
||||
}
|
||||
if (cd.getUnidades() == null || cd.getUnidades() <= 0) {
|
||||
direccionesPrueba.add(cd.toSkMap(
|
||||
1,
|
||||
presupuesto.getPeso(),
|
||||
false,
|
||||
true));
|
||||
} else {
|
||||
direccionesPresupuesto.add(cd.toSkMap(
|
||||
cd.getUnidades(),
|
||||
presupuesto.getPeso(),
|
||||
cd.getIsPalets(),
|
||||
false));
|
||||
}
|
||||
}
|
||||
if (presupuesto.getServiciosJson() != null
|
||||
&& presupuesto.getServiciosJson().contains("deposito-legal")) {
|
||||
CartDireccion cd = new CartDireccion();
|
||||
direccionesPresupuesto.add(cd.toSkMapDepositoLegal());
|
||||
}
|
||||
}
|
||||
Map<String, Object> direccionesRet = new HashMap<>();
|
||||
direccionesRet.put("direcciones", direccionesPresupuesto);
|
||||
if (!direccionesPrueba.isEmpty())
|
||||
direccionesRet.put("direccionesFP1", direccionesPrueba.get(0));
|
||||
else {
|
||||
direccionesRet.put("direccionesFP1", new ArrayList<>());
|
||||
}
|
||||
return direccionesRet;
|
||||
}
|
||||
|
||||
/***************************************
|
||||
* MÉTODOS PRIVADOS
|
||||
|
||||
@ -13,9 +13,13 @@ import com.imprimelibros.erp.redsys.RedsysService.RedsysNotification;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import com.imprimelibros.erp.payments.repo.WebhookEventRepository;
|
||||
import com.imprimelibros.erp.pedidos.Pedido;
|
||||
import com.imprimelibros.erp.pedidos.PedidoLinea;
|
||||
import com.imprimelibros.erp.pedidos.PedidoService;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
@ -28,18 +32,55 @@ public class PaymentService {
|
||||
private final WebhookEventRepository webhookEventRepo;
|
||||
private final ObjectMapper om = new ObjectMapper();
|
||||
private final CartService cartService;
|
||||
private final PedidoService pedidoService;
|
||||
|
||||
public PaymentService(PaymentRepository payRepo,
|
||||
PaymentTransactionRepository txRepo,
|
||||
RefundRepository refundRepo,
|
||||
RedsysService redsysService,
|
||||
WebhookEventRepository webhookEventRepo, CartService cartService) {
|
||||
WebhookEventRepository webhookEventRepo,
|
||||
CartService cartService,
|
||||
PedidoService pedidoService) {
|
||||
this.payRepo = payRepo;
|
||||
this.txRepo = txRepo;
|
||||
this.refundRepo = refundRepo;
|
||||
this.redsysService = redsysService;
|
||||
this.webhookEventRepo = webhookEventRepo;
|
||||
this.cartService = cartService;
|
||||
this.pedidoService = pedidoService;
|
||||
}
|
||||
|
||||
public Payment findFailedPaymentByOrderId(Long orderId) {
|
||||
return payRepo.findByOrderIdAndStatus(orderId, PaymentStatus.failed)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public Map<String, Long> getPaymentTransactionData(Long paymentId) {
|
||||
PaymentTransaction tx = txRepo.findByPaymentIdAndType(
|
||||
paymentId,
|
||||
PaymentTransactionType.CAPTURE)
|
||||
.orElse(null);
|
||||
if (tx == null) {
|
||||
return null;
|
||||
}
|
||||
String resp_payload = tx.getResponsePayload();
|
||||
try {
|
||||
ObjectMapper om = new ObjectMapper();
|
||||
var node = om.readTree(resp_payload);
|
||||
Long cartId = null;
|
||||
Long dirFactId = null;
|
||||
if (node.has("cartId")) {
|
||||
cartId = node.get("cartId").asLong();
|
||||
}
|
||||
if (node.has("dirFactId")) {
|
||||
dirFactId = node.get("dirFactId").asLong();
|
||||
}
|
||||
return Map.of(
|
||||
"cartId", cartId,
|
||||
"dirFactId", dirFactId);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,14 +88,15 @@ public class PaymentService {
|
||||
* oficial (ApiMacSha256).
|
||||
*/
|
||||
@Transactional
|
||||
public FormPayload createRedsysPayment(Long cartId, Long dirFactId, Long amountCents, String currency, String method)
|
||||
public FormPayload createRedsysPayment(Long cartId, Long dirFactId, Long amountCents, String currency, String method, Long orderId)
|
||||
throws Exception {
|
||||
Payment p = new Payment();
|
||||
p.setOrderId(null);
|
||||
p.setOrderId(orderId);
|
||||
|
||||
Cart cart = this.cartService.findById(cartId);
|
||||
if (cart != null && cart.getUserId() != null) {
|
||||
p.setUserId(cart.getUserId());
|
||||
this.cartService.lockCartById(cartId);
|
||||
}
|
||||
p.setCurrency(currency);
|
||||
p.setAmountTotalCents(amountCents);
|
||||
@ -62,10 +104,6 @@ public class PaymentService {
|
||||
p.setStatus(PaymentStatus.requires_payment_method);
|
||||
p = payRepo.saveAndFlush(p);
|
||||
|
||||
// ANTES:
|
||||
// String dsOrder = String.format("%012d", p.getId());
|
||||
|
||||
// AHORA: timestamp
|
||||
long now = System.currentTimeMillis();
|
||||
String dsOrder = String.format("%012d", now % 1_000_000_000_000L);
|
||||
|
||||
@ -207,16 +245,12 @@ public class PaymentService {
|
||||
p.setAmountCapturedCents(p.getAmountCapturedCents() + notif.amountCents);
|
||||
p.setAuthorizedAt(LocalDateTime.now());
|
||||
p.setCapturedAt(LocalDateTime.now());
|
||||
pedidoService.setOrderAsPaid(p.getOrderId());
|
||||
|
||||
} else {
|
||||
p.setStatus(PaymentStatus.failed);
|
||||
p.setFailedAt(LocalDateTime.now());
|
||||
}
|
||||
|
||||
if (authorized) {
|
||||
Long orderId = processOrder(notif.cartId, notif.dirFactId, locale);
|
||||
if (orderId != null) {
|
||||
p.setOrderId(orderId);
|
||||
}
|
||||
pedidoService.markPedidoAsPaymentDenied(p.getOrderId());
|
||||
}
|
||||
|
||||
payRepo.save(p);
|
||||
@ -311,7 +345,7 @@ public class PaymentService {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Payment createBankTransferPayment(Long cartId, Long dirFactId, long amountCents, String currency) {
|
||||
public Payment createBankTransferPayment(Long cartId, Long dirFactId, long amountCents, String currency, Locale locale, Long orderId) {
|
||||
Payment p = new Payment();
|
||||
p.setOrderId(null);
|
||||
|
||||
@ -326,6 +360,9 @@ public class PaymentService {
|
||||
p.setAmountTotalCents(amountCents);
|
||||
p.setGateway("bank_transfer");
|
||||
p.setStatus(PaymentStatus.requires_action); // pendiente de ingreso
|
||||
if (orderId != null) {
|
||||
p.setOrderId(orderId);
|
||||
}
|
||||
p = payRepo.save(p);
|
||||
|
||||
// Crear transacción pendiente
|
||||
@ -406,13 +443,17 @@ public class PaymentService {
|
||||
// ignorar
|
||||
}
|
||||
|
||||
// 4) Procesar el pedido asociado al carrito (si existe)
|
||||
if (cartId != null) {
|
||||
Long orderId = processOrder(cartId, dirFactId, locale);
|
||||
// 4) Procesar el pedido asociado al carrito (si existe) o marcar el pedido como pagado
|
||||
if(p.getOrderId() != null) {
|
||||
pedidoService.setOrderAsPaid(p.getOrderId());
|
||||
}
|
||||
/*else if (cartId != null) {
|
||||
// Se procesa el pedido dejando el estado calculado en processOrder
|
||||
Long orderId = processOrder(cartId, dirFactId, locale, null);
|
||||
if (orderId != null) {
|
||||
p.setOrderId(orderId);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
payRepo.save(p);
|
||||
}
|
||||
|
||||
@ -508,30 +549,5 @@ public class PaymentService {
|
||||
return code >= 0 && code <= 99;
|
||||
}
|
||||
|
||||
/**
|
||||
* Procesa el pedido asociado al carrito:
|
||||
* - bloquea el carrito
|
||||
* - crea el pedido a partir del carrito
|
||||
*
|
||||
*/
|
||||
@Transactional
|
||||
private Long processOrder(Long cartId, Long dirFactId, Locale locale) {
|
||||
|
||||
Cart cart = this.cartService.findById(cartId);
|
||||
if (cart != null) {
|
||||
// Bloqueamos el carrito
|
||||
this.cartService.lockCartById(cart.getId());
|
||||
// Creamos el pedido
|
||||
Long orderId = this.cartService.crearPedido(cart.getId(), dirFactId, locale);
|
||||
if (orderId == null) {
|
||||
return null;
|
||||
} else {
|
||||
// envio de correo de confirmacion de pedido podria ir aqui
|
||||
return orderId;
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -2,10 +2,13 @@
|
||||
package com.imprimelibros.erp.payments.repo;
|
||||
|
||||
import com.imprimelibros.erp.payments.model.Payment;
|
||||
import com.imprimelibros.erp.payments.model.PaymentStatus;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface PaymentRepository extends JpaRepository<Payment, Long> {
|
||||
Optional<Payment> findByGatewayAndGatewayOrderId(String gateway, String gatewayOrderId);
|
||||
Optional<Payment> findByOrderIdAndStatus(Long orderId, PaymentStatus status);
|
||||
}
|
||||
|
||||
@ -14,6 +14,10 @@ import java.util.Optional;
|
||||
public interface PaymentTransactionRepository extends JpaRepository<PaymentTransaction, Long>, JpaSpecificationExecutor<PaymentTransaction> {
|
||||
List<PaymentTransaction> findByGatewayTransactionId(String gatewayTransactionId);
|
||||
Optional<PaymentTransaction> findByIdempotencyKey(String idempotencyKey);
|
||||
Optional<PaymentTransaction> findByPaymentIdAndType(
|
||||
Long paymentId,
|
||||
PaymentTransactionType type
|
||||
);
|
||||
Optional<PaymentTransaction> findFirstByPaymentIdAndTypeAndStatusOrderByIdDesc(
|
||||
Long paymentId,
|
||||
PaymentTransactionType type,
|
||||
|
||||
@ -10,12 +10,15 @@ import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
|
||||
public class PedidoLinea {
|
||||
|
||||
public enum Estado {
|
||||
aprobado("pedido.estado.aprobado", 1),
|
||||
maquetacion("pedido.estado.maquetacion", 2),
|
||||
haciendo_ferro("pedido.estado.haciendo_ferro", 3),
|
||||
ferro_cliente("pedido.estado.ferro_cliente", 4),
|
||||
produccion("pedido.estado.produccion", 5),
|
||||
cancelado("pedido.estado.cancelado", 6);
|
||||
pendiente_pago("pedido.estado.pendiente_pago", 1),
|
||||
procesando_pago("pedido.estado.procesando_pago", 2),
|
||||
denegado_pago("pedido.estado.denegado_pago", 3),
|
||||
aprobado("pedido.estado.aprobado", 4),
|
||||
maquetacion("pedido.estado.maquetacion", 5),
|
||||
haciendo_ferro("pedido.estado.haciendo_ferro", 6),
|
||||
ferro_cliente("pedido.estado.ferro_cliente", 7),
|
||||
produccion("pedido.estado.produccion", 8),
|
||||
cancelado("pedido.estado.cancelado", 9);
|
||||
|
||||
private final String messageKey;
|
||||
private final int priority;
|
||||
|
||||
@ -11,6 +11,10 @@ import java.util.Map;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.imprimelibros.erp.cart.Cart;
|
||||
import com.imprimelibros.erp.cart.CartDireccion;
|
||||
import com.imprimelibros.erp.cart.CartItem;
|
||||
import com.imprimelibros.erp.cart.CartService;
|
||||
import com.imprimelibros.erp.common.Utils;
|
||||
import com.imprimelibros.erp.direcciones.Direccion;
|
||||
import com.imprimelibros.erp.presupuesto.PresupuestoRepository;
|
||||
@ -30,10 +34,11 @@ public class PedidoService {
|
||||
private final DireccionService direccionService;
|
||||
private final UserService userService;
|
||||
private final PresupuestoService presupuestoService;
|
||||
private final CartService cartService;
|
||||
|
||||
public PedidoService(PedidoRepository pedidoRepository, PedidoLineaRepository pedidoLineaRepository,
|
||||
PresupuestoRepository presupuestoRepository, PedidoDireccionRepository pedidoDireccionRepository,
|
||||
DireccionService direccionService, UserService userService, PresupuestoService presupuestoService) {
|
||||
DireccionService direccionService, UserService userService, PresupuestoService presupuestoService, CartService cartService) {
|
||||
this.pedidoRepository = pedidoRepository;
|
||||
this.pedidoLineaRepository = pedidoLineaRepository;
|
||||
this.presupuestoRepository = presupuestoRepository;
|
||||
@ -41,48 +46,22 @@ public class PedidoService {
|
||||
this.direccionService = direccionService;
|
||||
this.userService = userService;
|
||||
this.presupuestoService = presupuestoService;
|
||||
this.cartService = cartService;
|
||||
}
|
||||
|
||||
public int getDescuentoFidelizacion(Long userId) {
|
||||
// descuento entre el 1% y el 6% para clientes fidelidad (mas de 1500€ en el
|
||||
// ultimo año)
|
||||
Instant haceUnAno = Instant.now().minusSeconds(365 * 24 * 60 * 60);
|
||||
double totalGastado = pedidoRepository.sumTotalByCreatedByAndCreatedAtAfter(userId, haceUnAno);
|
||||
if (totalGastado < 1200) {
|
||||
return 0;
|
||||
} else if (totalGastado >= 1200 && totalGastado < 1999) {
|
||||
return 1;
|
||||
} else if (totalGastado >= 2000 && totalGastado < 2999) {
|
||||
return 2;
|
||||
} else if (totalGastado >= 3000 && totalGastado < 3999) {
|
||||
return 3;
|
||||
} else if (totalGastado >= 4000 && totalGastado < 4999) {
|
||||
return 4;
|
||||
} else if (totalGastado >= 5000) {
|
||||
return 5;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crea un pedido a partir de:
|
||||
* - lista de IDs de presupuesto
|
||||
* - resumen numérico del carrito (getCartSummaryRaw)
|
||||
* - datos de proveedor
|
||||
* - usuario que crea el pedido
|
||||
*/
|
||||
@Transactional
|
||||
public Pedido crearPedido(
|
||||
List<Long> presupuestoIds,
|
||||
Map<String, Object> presupuestoDirecciones,
|
||||
Long cartId,
|
||||
Long direccionFacturacionId,
|
||||
Map<String, Object> cartSummaryRaw,
|
||||
String proveedor,
|
||||
String proveedorRef,
|
||||
Long userId) {
|
||||
String proveedorRef) {
|
||||
|
||||
Pedido pedido = new Pedido();
|
||||
|
||||
Cart cart = cartService.getCartById(cartId);
|
||||
Map<String, Object> cartSummaryRaw = cartService.getCartSummaryRaw(cart, Locale.getDefault());
|
||||
|
||||
// Datos económicos (ojo con las claves, son las del summaryRaw)
|
||||
pedido.setBase((Double) cartSummaryRaw.getOrDefault("base", 0.0d));
|
||||
pedido.setEnvio((Double) cartSummaryRaw.getOrDefault("shipment", 0.0d));
|
||||
@ -92,10 +71,13 @@ public class PedidoService {
|
||||
pedido.setTotal((Double) cartSummaryRaw.getOrDefault("total", 0.0d));
|
||||
|
||||
// Proveedor
|
||||
pedido.setProveedor(proveedor);
|
||||
pedido.setProveedorRef(proveedorRef);
|
||||
if(proveedor != null && proveedorRef != null) {
|
||||
pedido.setProveedor(proveedor);
|
||||
pedido.setProveedorRef(proveedorRef);
|
||||
}
|
||||
|
||||
// Auditoría mínima
|
||||
Long userId = cart.getUserId();
|
||||
pedido.setCreatedBy(userService.findById(userId));
|
||||
pedido.setCreatedAt(Instant.now());
|
||||
pedido.setDeleted(false);
|
||||
@ -103,8 +85,36 @@ public class PedidoService {
|
||||
pedido.setUpdatedBy(userService.findById(userId));
|
||||
|
||||
// Guardamos el pedido
|
||||
Pedido saved = pedidoRepository.save(pedido);
|
||||
Pedido pedidoGuardado = pedidoRepository.save(pedido);
|
||||
|
||||
List<CartItem> items = cart.getItems();
|
||||
|
||||
for (Integer i = 0; i < items.size(); i++) {
|
||||
CartItem item = items.get(i);
|
||||
Presupuesto pCart = item.getPresupuesto();
|
||||
|
||||
// Asegurarnos de trabajar con la entidad gestionada por JPA
|
||||
Presupuesto p = presupuestoRepository.findById(pCart.getId())
|
||||
.orElseThrow(() -> new IllegalStateException("Presupuesto no encontrado: " + pCart.getId()));
|
||||
p.setEstado(Presupuesto.Estado.aceptado);
|
||||
presupuestoRepository.save(p);
|
||||
|
||||
PedidoLinea linea = new PedidoLinea();
|
||||
linea.setPedido(pedidoGuardado);
|
||||
linea.setPresupuesto(p);
|
||||
linea.setCreatedBy(userId);
|
||||
linea.setCreatedAt(LocalDateTime.now());
|
||||
linea.setEstado(PedidoLinea.Estado.pendiente_pago);
|
||||
linea.setEstadoManual(false);
|
||||
pedidoLineaRepository.save(linea);
|
||||
|
||||
// Guardar las direcciones asociadas a la línea del pedido
|
||||
Map<String, Object> direcciones_presupuesto = this.getDireccionesPresupuesto(cart, p);
|
||||
saveDireccionesPedidoLinea(direcciones_presupuesto, pedidoGuardado, linea, direccionFacturacionId);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
// Crear líneas del pedido
|
||||
for (Long presupuestoId : presupuestoIds) {
|
||||
Presupuesto presupuesto = presupuestoRepository.getReferenceById(presupuestoId);
|
||||
@ -114,7 +124,11 @@ public class PedidoService {
|
||||
linea.setPresupuesto(presupuesto);
|
||||
linea.setCreatedBy(userId);
|
||||
linea.setCreatedAt(LocalDateTime.now());
|
||||
linea.setEstado(getEstadoInicial(presupuesto));
|
||||
if(estadoInicial != null){
|
||||
linea.setEstado(estadoInicial);
|
||||
} else {
|
||||
linea.setEstado(getEstadoInicial(presupuesto));
|
||||
}
|
||||
linea.setEstadoManual(false);
|
||||
pedidoLineaRepository.save(linea);
|
||||
|
||||
@ -125,10 +139,175 @@ public class PedidoService {
|
||||
saveDireccionesPedidoLinea(direcciones, saved, linea, direccionFacturacionId);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return saved;
|
||||
return pedidoGuardado;
|
||||
}
|
||||
|
||||
public Boolean markPedidoAsProcesingPayment(Long pedidoId){
|
||||
Pedido pedido = pedidoRepository.findById(pedidoId).orElse(null);
|
||||
if(pedido == null){
|
||||
return false;
|
||||
}
|
||||
List<PedidoLinea> lineas = pedidoLineaRepository.findByPedidoId(pedidoId);
|
||||
for (PedidoLinea linea : lineas) {
|
||||
linea.setEstado(PedidoLinea.Estado.procesando_pago);
|
||||
pedidoLineaRepository.save(linea);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public Boolean markPedidoAsPaymentDenied(Long pedidoId){
|
||||
Pedido pedido = pedidoRepository.findById(pedidoId).orElse(null);
|
||||
if(pedido == null){
|
||||
return false;
|
||||
}
|
||||
List<PedidoLinea> lineas = pedidoLineaRepository.findByPedidoId(pedidoId);
|
||||
for (PedidoLinea linea : lineas) {
|
||||
linea.setEstado(PedidoLinea.Estado.denegado_pago);
|
||||
pedidoLineaRepository.save(linea);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Boolean markPedidoAsPaid(Long pedidoId){
|
||||
Pedido pedido = pedidoRepository.findById(pedidoId).orElse(null);
|
||||
if(pedido == null){
|
||||
return false;
|
||||
}
|
||||
List<PedidoLinea> lineas = pedidoLineaRepository.findByPedidoId(pedidoId);
|
||||
for (PedidoLinea linea : lineas) {
|
||||
linea.setEstado(this.getEstadoInicial(linea.getPresupuesto()));
|
||||
pedidoLineaRepository.save(linea);
|
||||
|
||||
// Save presupuesto in SK
|
||||
}
|
||||
|
||||
// Save pedido in SK
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Pedido findById(Long pedidoId){
|
||||
return pedidoRepository.findById(pedidoId).orElse(null);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@Transactional
|
||||
public Long crearPedido(Long cartId, Long dirFactId, Locale locale) {
|
||||
|
||||
return crearPedido(cartId, dirFactId, locale, null);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
// Crear pedido interno (no en el proveedor) a partir del carrito
|
||||
public Long crearPedido(Long cartId, Long dirFactId, Locale locale, PedidoLinea.Estado estadoInicial) {
|
||||
|
||||
Cart cart = cartService.getCartById(cartId);
|
||||
List<CartItem> items = cart.getItems();
|
||||
|
||||
List<Map<String, Object>> presupuestoRequests = new ArrayList<>();
|
||||
Map<String, Object> presupuestoDireccionesRequest = new HashMap<>();
|
||||
List<Long> presupuestoIds = new ArrayList<>();
|
||||
|
||||
for (Integer i = 0; i < items.size(); i++) {
|
||||
CartItem item = items.get(i);
|
||||
Presupuesto pCart = item.getPresupuesto();
|
||||
|
||||
// Asegurarnos de trabajar con la entidad gestionada por JPA
|
||||
Presupuesto p = presupuestoRepository.findById(pCart.getId())
|
||||
.orElseThrow(() -> new IllegalStateException("Presupuesto no encontrado: " + pCart.getId()));
|
||||
|
||||
/*Map<String, Object> data_to_send = presupuestoService.toSkApiRequest(p, true);
|
||||
data_to_send.put("createPedido", 0);
|
||||
|
||||
// Recuperar el mapa anidado datosCabecera
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> datosCabecera = (Map<String, Object>) data_to_send.get("datosCabecera");
|
||||
if (datosCabecera != null) {
|
||||
Object tituloOriginal = datosCabecera.get("titulo");
|
||||
datosCabecera.put(
|
||||
"titulo",
|
||||
"[" + (i + 1) + "/" + items.size() + "] " + (tituloOriginal != null ? tituloOriginal : ""));
|
||||
}
|
||||
|
||||
Map<String, Object> direcciones_presupuesto = this.getDireccionesPresupuesto(cart, p);
|
||||
data_to_send.put("direcciones", direcciones_presupuesto.get("direcciones"));
|
||||
data_to_send.put("direccionesFP1", direcciones_presupuesto.get("direccionesFP1"));
|
||||
|
||||
presupuestoDireccionesRequest.put(p.getId().toString(), direcciones_presupuesto);
|
||||
|
||||
|
||||
Map<String, Object> result = skApiClient.savePresupuesto(data_to_send);
|
||||
|
||||
if (result.containsKey("error")) {
|
||||
System.out.println("Error al guardar presupuesto en SK");
|
||||
System.out.println("-------------------------");
|
||||
System.out.println(result.get("error"));
|
||||
// decide si seguir con otros items o abortar:
|
||||
// continue; o bien throw ...
|
||||
continue;
|
||||
}
|
||||
|
||||
Object dataObj = result.get("data");
|
||||
if (!(dataObj instanceof Map<?, ?> dataRaw)) {
|
||||
System.out.println("Formato inesperado de 'data' en savePresupuesto: " + result);
|
||||
continue;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> dataMap = (Map<String, Object>) dataRaw;
|
||||
Long presId = ((Number) dataMap.get("id")).longValue();
|
||||
String skin = ((String) dataMap.get("iskn")).toString();
|
||||
p.setProveedor("Safekat");
|
||||
p.setProveedorRef1(skin);
|
||||
p.setProveedorRef2(presId);
|
||||
p.setEstado(Presupuesto.Estado.aceptado);
|
||||
presupuestoRepo.save(p);
|
||||
|
||||
presupuestoIds.add(p.getId());
|
||||
|
||||
presupuestoRequests.add(dataMap);
|
||||
}
|
||||
|
||||
// Crear el pedido en base a los presupuestos guardados
|
||||
if (presupuestoRequests.isEmpty()) {
|
||||
throw new IllegalStateException("No se pudieron guardar los presupuestos en SK.");
|
||||
} else {
|
||||
ArrayList<Long> presupuestoSkIds = new ArrayList<>();
|
||||
for (Map<String, Object> presData : presupuestoRequests) {
|
||||
Long presId = ((Number) presData.get("id")).longValue();
|
||||
presupuestoSkIds.add(presId);
|
||||
}
|
||||
Map<String, Object> ids = new HashMap<>();
|
||||
ids.put("presupuesto_ids", presupuestoSkIds);
|
||||
Long pedidoId = skApiClient.crearPedido(ids);
|
||||
if (pedidoId == null) {
|
||||
throw new IllegalStateException("No se pudo crear el pedido en SK.");
|
||||
}
|
||||
Pedido pedidoInterno = pedidoService.crearPedido(
|
||||
presupuestoIds,
|
||||
presupuestoDireccionesRequest,
|
||||
dirFactId,
|
||||
this.getCartSummaryRaw(cart, locale),
|
||||
"Safekat",
|
||||
String.valueOf(pedidoId),
|
||||
cart.getUserId(),
|
||||
estadoInicial);
|
||||
|
||||
return pedidoInterno.getId();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/** Lista de los items del pedido preparados para la vista*/
|
||||
@Transactional
|
||||
public List<Map<String, Object>> getLineas(Long pedidoId, Locale locale) {
|
||||
@ -160,17 +339,119 @@ public class PedidoService {
|
||||
return pedidoDireccionRepository.findByPedidoLinea_Id(pedidoLineaId);
|
||||
}
|
||||
|
||||
public Boolean setOrderAsPaid(Long pedidoId) {
|
||||
Pedido pedido = pedidoRepository.findById(pedidoId).orElse(null);
|
||||
if (pedido == null) {
|
||||
return false;
|
||||
}
|
||||
List<PedidoLinea> lineas = pedidoLineaRepository.findByPedidoId(pedidoId);
|
||||
for (PedidoLinea linea : lineas) {
|
||||
if (linea.getEstado() == Estado.pendiente_pago) {
|
||||
Presupuesto presupuesto = linea.getPresupuesto();
|
||||
linea.setEstado(getEstadoInicial(presupuesto));
|
||||
pedidoLineaRepository.save(linea);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/***************************
|
||||
* MÉTODOS PRIVADOS
|
||||
***************************/
|
||||
// Obtener las direcciones de envío asociadas a un presupuesto en el carrito
|
||||
private Map<String, Object> getDireccionesPresupuesto(Cart cart, Presupuesto presupuesto) {
|
||||
|
||||
List<Map<String, Object>> direccionesPresupuesto = new ArrayList<>();
|
||||
List<Map<String, Object>> direccionesPrueba = new ArrayList<>();
|
||||
if (cart.getOnlyOneShipment()) {
|
||||
List<CartDireccion> direcciones = cart.getDirecciones().stream().limit(1).toList();
|
||||
if (!direcciones.isEmpty()) {
|
||||
if (presupuesto.getServiciosJson() != null
|
||||
&& presupuesto.getServiciosJson().contains("deposito-legal")) {
|
||||
direccionesPresupuesto.add(direcciones.get(0).toSkMap(
|
||||
presupuesto.getSelectedTirada(),
|
||||
presupuesto.getPeso(),
|
||||
direcciones.get(0).getIsPalets(),
|
||||
false));
|
||||
|
||||
direccionesPresupuesto.add(direcciones.get(0).toSkMapDepositoLegal());
|
||||
}
|
||||
else {
|
||||
direccionesPresupuesto.add(direcciones.get(0).toSkMap(
|
||||
presupuesto.getSelectedTirada(),
|
||||
presupuesto.getPeso(),
|
||||
direcciones.get(0).getIsPalets(),
|
||||
false));
|
||||
}
|
||||
if (presupuesto.getServiciosJson() != null
|
||||
&& presupuesto.getServiciosJson().contains("ejemplar-prueba")) {
|
||||
direccionesPrueba.add(direcciones.get(0).toSkMap(
|
||||
1,
|
||||
presupuesto.getPeso(),
|
||||
false,
|
||||
true));
|
||||
}
|
||||
|
||||
Map<String, Object> direccionesRet = new HashMap<>();
|
||||
direccionesRet.put("direcciones", direccionesPresupuesto);
|
||||
if (!direccionesPrueba.isEmpty())
|
||||
direccionesRet.put("direccionesFP1", direccionesPrueba.get(0));
|
||||
else {
|
||||
direccionesRet.put("direccionesFP1", new ArrayList<>());
|
||||
}
|
||||
return direccionesRet;
|
||||
}
|
||||
} else {
|
||||
List<CartDireccion> direcciones = cart.getDirecciones().stream()
|
||||
.filter(d -> d.getPresupuesto() != null && d.getPresupuesto().getId().equals(presupuesto.getId()))
|
||||
.toList();
|
||||
|
||||
for (CartDireccion cd : direcciones) {
|
||||
|
||||
// direccion de ejemplar de prueba
|
||||
if (cd.getPresupuesto() == null || !cd.getPresupuesto().getId().equals(presupuesto.getId())) {
|
||||
continue;
|
||||
}
|
||||
if (cd.getUnidades() == null || cd.getUnidades() <= 0) {
|
||||
direccionesPrueba.add(cd.toSkMap(
|
||||
1,
|
||||
presupuesto.getPeso(),
|
||||
false,
|
||||
true));
|
||||
} else {
|
||||
direccionesPresupuesto.add(cd.toSkMap(
|
||||
cd.getUnidades(),
|
||||
presupuesto.getPeso(),
|
||||
cd.getIsPalets(),
|
||||
false));
|
||||
}
|
||||
}
|
||||
if (presupuesto.getServiciosJson() != null
|
||||
&& presupuesto.getServiciosJson().contains("deposito-legal")) {
|
||||
CartDireccion cd = new CartDireccion();
|
||||
direccionesPresupuesto.add(cd.toSkMapDepositoLegal());
|
||||
}
|
||||
}
|
||||
Map<String, Object> direccionesRet = new HashMap<>();
|
||||
direccionesRet.put("direcciones", direccionesPresupuesto);
|
||||
if (!direccionesPrueba.isEmpty())
|
||||
direccionesRet.put("direccionesFP1", direccionesPrueba.get(0));
|
||||
else {
|
||||
direccionesRet.put("direccionesFP1", new ArrayList<>());
|
||||
}
|
||||
return direccionesRet;
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
private void saveDireccionesPedidoLinea(
|
||||
Map<String, Map<String, Object>> direcciones,
|
||||
Map<String, Object> direcciones,
|
||||
Pedido pedido,
|
||||
PedidoLinea linea, Long direccionFacturacionId) {
|
||||
// direccion prueba
|
||||
if (direcciones.containsKey("direccionesFP1")) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> fp1 = (Map<String, Object>) direcciones.get("direccionesFP1");
|
||||
@SuppressWarnings("unchecked")
|
||||
PedidoDireccion direccion = saveDireccion(
|
||||
|
||||
@ -166,9 +166,16 @@ public class PedidosController {
|
||||
return text;
|
||||
})
|
||||
.add("actions", pedido -> {
|
||||
return "<span class=\'badge bg-success btn-view \' data-id=\'" + pedido.getId()
|
||||
String data = "<span class=\'badge bg-success btn-view \' data-id=\'" + pedido.getId()
|
||||
+ "\' style=\'cursor: pointer;\'>"
|
||||
+ messageSource.getMessage("app.view", null, locale) + "</span>";
|
||||
List<PedidoLinea> lineas = repoPedidoLinea.findByPedidoId(pedido.getId());
|
||||
boolean hasDenegadoPago = lineas.stream()
|
||||
.anyMatch(linea -> PedidoLinea.Estado.denegado_pago.equals(linea.getEstado()));
|
||||
if (hasDenegadoPago) {
|
||||
data += " <span class='badge bg-danger btn-pay' data-amount='" + pedido.getTotal() + "' data-id=\\'" + pedido.getId() + "\\' style='cursor: pointer;'>" + messageSource.getMessage("app.pay", null, locale) + "</span>";
|
||||
}
|
||||
return data;
|
||||
})
|
||||
.where(base)
|
||||
.toJson(total);
|
||||
|
||||
@ -1,10 +1,15 @@
|
||||
package com.imprimelibros.erp.redsys;
|
||||
|
||||
import com.imprimelibros.erp.cart.Cart;
|
||||
import com.imprimelibros.erp.common.Utils;
|
||||
import com.imprimelibros.erp.payments.PaymentService;
|
||||
import com.imprimelibros.erp.payments.model.Payment;
|
||||
import com.imprimelibros.erp.payments.repo.PaymentTransactionRepository;
|
||||
import com.imprimelibros.erp.pedidos.Pedido;
|
||||
import com.imprimelibros.erp.pedidos.PedidoService;
|
||||
import com.imprimelibros.erp.redsys.RedsysService.FormPayload;
|
||||
|
||||
import groovy.util.logging.Log;
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
@ -27,6 +32,7 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@Controller
|
||||
@ -37,13 +43,16 @@ public class RedsysController {
|
||||
private final MessageSource messageSource;
|
||||
private final SpringTemplateEngine templateEngine;
|
||||
private final ServletContext servletContext;
|
||||
private final PedidoService pedidoService;
|
||||
|
||||
public RedsysController(PaymentService paymentService, MessageSource messageSource,
|
||||
SpringTemplateEngine templateEngine, ServletContext servletContext) {
|
||||
SpringTemplateEngine templateEngine, ServletContext servletContext,
|
||||
PedidoService pedidoService) {
|
||||
this.paymentService = paymentService;
|
||||
this.messageSource = messageSource;
|
||||
this.templateEngine = templateEngine;
|
||||
this.servletContext = servletContext;
|
||||
this.pedidoService = pedidoService;
|
||||
}
|
||||
|
||||
@PostMapping(value = "/crear", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||
@ -55,9 +64,15 @@ public class RedsysController {
|
||||
HttpServletResponse response, Locale locale)
|
||||
throws Exception {
|
||||
|
||||
// Creamos el pedido inteno
|
||||
Pedido order = pedidoService.crearPedido(cartId, dirFactId, null, null);
|
||||
|
||||
if ("bank-transfer".equalsIgnoreCase(method)) {
|
||||
|
||||
// 1) Creamos el Payment interno SIN orderId (null)
|
||||
Payment p = paymentService.createBankTransferPayment(cartId, dirFactId, amountCents, "EUR");
|
||||
Payment p = paymentService.createBankTransferPayment(cartId, dirFactId, amountCents, "EUR", locale, order.getId());
|
||||
|
||||
pedidoService.markPedidoAsProcesingPayment(order.getId());
|
||||
|
||||
// 1️⃣ Crear la "aplicación" web de Thymeleaf (Jakarta)
|
||||
JakartaServletWebApplication app = JakartaServletWebApplication.buildApplication(servletContext);
|
||||
@ -89,7 +104,102 @@ public class RedsysController {
|
||||
}
|
||||
|
||||
// Tarjeta o Bizum (Redsys)
|
||||
FormPayload form = paymentService.createRedsysPayment(cartId, dirFactId, amountCents, "EUR", method);
|
||||
FormPayload form = paymentService.createRedsysPayment(cartId, dirFactId, amountCents, "EUR", method, order.getId());
|
||||
|
||||
String html = """
|
||||
<html><head><meta charset="utf-8"><title>Redirigiendo a Redsys…</title></head>
|
||||
<body onload="document.forms[0].submit()">
|
||||
<form action="%s" method="post">
|
||||
<input type="hidden" name="Ds_SignatureVersion" value="%s"/>
|
||||
<input type="hidden" name="Ds_MerchantParameters" value="%s"/>
|
||||
<input type="hidden" name="Ds_Signature" value="%s"/>
|
||||
<input type="hidden" name="cartId" value="%d"/>
|
||||
<noscript>
|
||||
<p>Haz clic en pagar para continuar</p>
|
||||
<button type="submit">Pagar</button>
|
||||
</noscript>
|
||||
</form>
|
||||
</body></html>
|
||||
""".formatted(
|
||||
form.action(),
|
||||
form.signatureVersion(),
|
||||
form.merchantParameters(),
|
||||
form.signature(), cartId);
|
||||
|
||||
byte[] body = html.getBytes(StandardCharsets.UTF_8);
|
||||
return ResponseEntity.ok()
|
||||
.contentType(MediaType.TEXT_HTML)
|
||||
.body(body);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping(value = "/reintentar", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||
@ResponseBody
|
||||
public ResponseEntity<byte[]> reintentarPago(@RequestParam("amountCents") Long amountCents,
|
||||
@RequestParam("method") String method, @RequestParam("orderId") Long orderId,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response, Locale locale)
|
||||
throws Exception {
|
||||
|
||||
// Creamos el pedido inteno
|
||||
Pedido order = pedidoService.findById(orderId);
|
||||
|
||||
// Find the payment with orderId = order.getId() and status = failed
|
||||
Payment failedPayment = paymentService.findFailedPaymentByOrderId(order.getId());
|
||||
if (failedPayment == null) {
|
||||
throw new Exception("No se encontró un pago fallido para el pedido " + order.getId());
|
||||
}
|
||||
|
||||
Long cartId = null;
|
||||
Long dirFactId = null;
|
||||
// Find payment transaction details from failedPayment if needed
|
||||
try{
|
||||
Map<String, Long> transactionDetails = paymentService.getPaymentTransactionData(failedPayment.getId());
|
||||
cartId = transactionDetails.get("cartId");
|
||||
dirFactId = transactionDetails.get("dirFactId");
|
||||
} catch (Exception e) {
|
||||
throw new Exception("No se pudieron obtener los detalles de la transacción para el pago " + failedPayment.getId());
|
||||
}
|
||||
|
||||
|
||||
if ("bank-transfer".equalsIgnoreCase(method)) {
|
||||
|
||||
// 1) Creamos el Payment interno SIN orderId (null)
|
||||
Payment p = paymentService.createBankTransferPayment(cartId, dirFactId, amountCents, "EUR", locale, order.getId());
|
||||
|
||||
pedidoService.markPedidoAsProcesingPayment(order.getId());
|
||||
|
||||
// 1️⃣ Crear la "aplicación" web de Thymeleaf (Jakarta)
|
||||
JakartaServletWebApplication app = JakartaServletWebApplication.buildApplication(servletContext);
|
||||
|
||||
// 2️⃣ Construir el intercambio web desde request/response
|
||||
response.setContentType("text/html;charset=UTF-8");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
IWebExchange exchange = app.buildExchange(request, response);
|
||||
|
||||
// 3️⃣ Crear el contexto WebContext con Locale
|
||||
WebContext ctx = new WebContext(exchange, locale);
|
||||
|
||||
String importeFormateado = Utils.formatCurrency(amountCents / 100.0, locale);
|
||||
ctx.setVariable("importe", importeFormateado);
|
||||
ctx.setVariable("concepto", "TRANSF-" + p.getOrderId());
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
boolean isAuth = auth != null
|
||||
&& auth.isAuthenticated()
|
||||
&& !(auth instanceof AnonymousAuthenticationToken);
|
||||
ctx.setVariable("isAuth", isAuth);
|
||||
|
||||
// 3) Renderizamos la plantilla a HTML
|
||||
String html = templateEngine.process("imprimelibros/pagos/transfer", ctx);
|
||||
|
||||
byte[] body = html.getBytes(StandardCharsets.UTF_8);
|
||||
return ResponseEntity.ok()
|
||||
.contentType(MediaType.TEXT_HTML)
|
||||
.body(body);
|
||||
}
|
||||
|
||||
// Tarjeta o Bizum (Redsys)
|
||||
FormPayload form = paymentService.createRedsysPayment(cartId, dirFactId, amountCents, "EUR", method, order.getId());
|
||||
|
||||
String html = """
|
||||
<html><head><meta charset="utf-8"><title>Redirigiendo a Redsys…</title></head>
|
||||
|
||||
Reference in New Issue
Block a user