mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-24 09:40:21 +00:00
haciendo pagos pendientes
This commit is contained in:
933
logs/erp.log
933
logs/erp.log
File diff suppressed because it is too large
Load Diff
2
pom.xml
2
pom.xml
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>3.5.8</version>
|
<version>3.5.9</version>
|
||||||
<relativePath /> <!-- lookup parent from repository -->
|
<relativePath /> <!-- lookup parent from repository -->
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>com.imprimelibros</groupId>
|
<groupId>com.imprimelibros</groupId>
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
import org.springframework.context.MessageSource;
|
import org.springframework.context.MessageSource;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
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.DireccionShipment;
|
||||||
import com.imprimelibros.erp.cart.dto.UpdateCartRequest;
|
import com.imprimelibros.erp.cart.dto.UpdateCartRequest;
|
||||||
import com.imprimelibros.erp.common.Utils;
|
import com.imprimelibros.erp.common.Utils;
|
||||||
|
import com.imprimelibros.erp.common.email.EmailService;
|
||||||
import com.imprimelibros.erp.direcciones.DireccionService;
|
import com.imprimelibros.erp.direcciones.DireccionService;
|
||||||
import com.imprimelibros.erp.externalApi.skApiClient;
|
import com.imprimelibros.erp.externalApi.skApiClient;
|
||||||
import com.imprimelibros.erp.pedidos.Pedido;
|
import com.imprimelibros.erp.pedidos.PedidoRepository;
|
||||||
import com.imprimelibros.erp.pedidos.PedidoService;
|
|
||||||
import com.imprimelibros.erp.presupuesto.PresupuestoRepository;
|
import com.imprimelibros.erp.presupuesto.PresupuestoRepository;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class CartService {
|
public class CartService {
|
||||||
|
|
||||||
|
private final EmailService emailService;
|
||||||
|
|
||||||
private final CartRepository cartRepo;
|
private final CartRepository cartRepo;
|
||||||
private final CartDireccionRepository cartDireccionRepo;
|
private final CartDireccionRepository cartDireccionRepo;
|
||||||
private final CartItemRepository itemRepo;
|
private final CartItemRepository itemRepo;
|
||||||
@ -36,14 +39,13 @@ public class CartService {
|
|||||||
private final PresupuestoRepository presupuestoRepo;
|
private final PresupuestoRepository presupuestoRepo;
|
||||||
private final DireccionService direccionService;
|
private final DireccionService direccionService;
|
||||||
private final skApiClient skApiClient;
|
private final skApiClient skApiClient;
|
||||||
private final PedidoService pedidoService;
|
|
||||||
private final PresupuestoService presupuestoService;
|
private final PresupuestoService presupuestoService;
|
||||||
|
private final PedidoRepository pedidoRepository;
|
||||||
|
|
||||||
public CartService(CartRepository cartRepo, CartItemRepository itemRepo,
|
public CartService(CartRepository cartRepo, CartItemRepository itemRepo,
|
||||||
CartDireccionRepository cartDireccionRepo, MessageSource messageSource,
|
CartDireccionRepository cartDireccionRepo, MessageSource messageSource,
|
||||||
PresupuestoFormatter presupuestoFormatter, PresupuestoRepository presupuestoRepo,
|
PresupuestoFormatter presupuestoFormatter, PresupuestoRepository presupuestoRepo, PedidoRepository pedidoRepository,
|
||||||
DireccionService direccionService, skApiClient skApiClient,
|
DireccionService direccionService, skApiClient skApiClient,PresupuestoService presupuestoService, EmailService emailService) {
|
||||||
PedidoService pedidoService, PresupuestoService presupuestoService) {
|
|
||||||
this.cartRepo = cartRepo;
|
this.cartRepo = cartRepo;
|
||||||
this.itemRepo = itemRepo;
|
this.itemRepo = itemRepo;
|
||||||
this.cartDireccionRepo = cartDireccionRepo;
|
this.cartDireccionRepo = cartDireccionRepo;
|
||||||
@ -51,8 +53,9 @@ public class CartService {
|
|||||||
this.presupuestoRepo = presupuestoRepo;
|
this.presupuestoRepo = presupuestoRepo;
|
||||||
this.direccionService = direccionService;
|
this.direccionService = direccionService;
|
||||||
this.skApiClient = skApiClient;
|
this.skApiClient = skApiClient;
|
||||||
this.pedidoService = pedidoService;
|
|
||||||
this.presupuestoService = presupuestoService;
|
this.presupuestoService = presupuestoService;
|
||||||
|
this.emailService = emailService;
|
||||||
|
this.pedidoRepository = pedidoRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Cart findById(Long cartId) {
|
public Cart findById(Long cartId) {
|
||||||
@ -264,7 +267,7 @@ public class CartService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
double totalBeforeDiscount = base + iva4 + iva21 + shipment;
|
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 descuento = totalBeforeDiscount * fidelizacion / 100.0;
|
||||||
double total = totalBeforeDiscount - descuento;
|
double total = totalBeforeDiscount - descuento;
|
||||||
|
|
||||||
@ -291,6 +294,27 @@ public class CartService {
|
|||||||
return summary;
|
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) {
|
public Map<String, Object> getCartSummary(Cart cart, Locale locale) {
|
||||||
Map<String, Object> raw = getCartSummaryRaw(cart, locale);
|
Map<String, Object> raw = getCartSummaryRaw(cart, locale);
|
||||||
|
|
||||||
@ -411,184 +435,6 @@ public class CartService {
|
|||||||
cartDireccionRepo.deleteByDireccionIdAndCartStatus(direccionId, Cart.Status.ACTIVE);
|
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
|
* MÉTODOS PRIVADOS
|
||||||
|
|||||||
@ -13,9 +13,13 @@ import com.imprimelibros.erp.redsys.RedsysService.RedsysNotification;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import com.imprimelibros.erp.payments.repo.WebhookEventRepository;
|
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.time.LocalDateTime;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@ -28,18 +32,55 @@ public class PaymentService {
|
|||||||
private final WebhookEventRepository webhookEventRepo;
|
private final WebhookEventRepository webhookEventRepo;
|
||||||
private final ObjectMapper om = new ObjectMapper();
|
private final ObjectMapper om = new ObjectMapper();
|
||||||
private final CartService cartService;
|
private final CartService cartService;
|
||||||
|
private final PedidoService pedidoService;
|
||||||
|
|
||||||
public PaymentService(PaymentRepository payRepo,
|
public PaymentService(PaymentRepository payRepo,
|
||||||
PaymentTransactionRepository txRepo,
|
PaymentTransactionRepository txRepo,
|
||||||
RefundRepository refundRepo,
|
RefundRepository refundRepo,
|
||||||
RedsysService redsysService,
|
RedsysService redsysService,
|
||||||
WebhookEventRepository webhookEventRepo, CartService cartService) {
|
WebhookEventRepository webhookEventRepo,
|
||||||
|
CartService cartService,
|
||||||
|
PedidoService pedidoService) {
|
||||||
this.payRepo = payRepo;
|
this.payRepo = payRepo;
|
||||||
this.txRepo = txRepo;
|
this.txRepo = txRepo;
|
||||||
this.refundRepo = refundRepo;
|
this.refundRepo = refundRepo;
|
||||||
this.redsysService = redsysService;
|
this.redsysService = redsysService;
|
||||||
this.webhookEventRepo = webhookEventRepo;
|
this.webhookEventRepo = webhookEventRepo;
|
||||||
this.cartService = cartService;
|
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).
|
* oficial (ApiMacSha256).
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@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 {
|
throws Exception {
|
||||||
Payment p = new Payment();
|
Payment p = new Payment();
|
||||||
p.setOrderId(null);
|
p.setOrderId(orderId);
|
||||||
|
|
||||||
Cart cart = this.cartService.findById(cartId);
|
Cart cart = this.cartService.findById(cartId);
|
||||||
if (cart != null && cart.getUserId() != null) {
|
if (cart != null && cart.getUserId() != null) {
|
||||||
p.setUserId(cart.getUserId());
|
p.setUserId(cart.getUserId());
|
||||||
|
this.cartService.lockCartById(cartId);
|
||||||
}
|
}
|
||||||
p.setCurrency(currency);
|
p.setCurrency(currency);
|
||||||
p.setAmountTotalCents(amountCents);
|
p.setAmountTotalCents(amountCents);
|
||||||
@ -62,10 +104,6 @@ public class PaymentService {
|
|||||||
p.setStatus(PaymentStatus.requires_payment_method);
|
p.setStatus(PaymentStatus.requires_payment_method);
|
||||||
p = payRepo.saveAndFlush(p);
|
p = payRepo.saveAndFlush(p);
|
||||||
|
|
||||||
// ANTES:
|
|
||||||
// String dsOrder = String.format("%012d", p.getId());
|
|
||||||
|
|
||||||
// AHORA: timestamp
|
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
String dsOrder = String.format("%012d", now % 1_000_000_000_000L);
|
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.setAmountCapturedCents(p.getAmountCapturedCents() + notif.amountCents);
|
||||||
p.setAuthorizedAt(LocalDateTime.now());
|
p.setAuthorizedAt(LocalDateTime.now());
|
||||||
p.setCapturedAt(LocalDateTime.now());
|
p.setCapturedAt(LocalDateTime.now());
|
||||||
|
pedidoService.setOrderAsPaid(p.getOrderId());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
p.setStatus(PaymentStatus.failed);
|
p.setStatus(PaymentStatus.failed);
|
||||||
p.setFailedAt(LocalDateTime.now());
|
p.setFailedAt(LocalDateTime.now());
|
||||||
}
|
pedidoService.markPedidoAsPaymentDenied(p.getOrderId());
|
||||||
|
|
||||||
if (authorized) {
|
|
||||||
Long orderId = processOrder(notif.cartId, notif.dirFactId, locale);
|
|
||||||
if (orderId != null) {
|
|
||||||
p.setOrderId(orderId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
payRepo.save(p);
|
payRepo.save(p);
|
||||||
@ -311,7 +345,7 @@ public class PaymentService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@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();
|
Payment p = new Payment();
|
||||||
p.setOrderId(null);
|
p.setOrderId(null);
|
||||||
|
|
||||||
@ -326,6 +360,9 @@ public class PaymentService {
|
|||||||
p.setAmountTotalCents(amountCents);
|
p.setAmountTotalCents(amountCents);
|
||||||
p.setGateway("bank_transfer");
|
p.setGateway("bank_transfer");
|
||||||
p.setStatus(PaymentStatus.requires_action); // pendiente de ingreso
|
p.setStatus(PaymentStatus.requires_action); // pendiente de ingreso
|
||||||
|
if (orderId != null) {
|
||||||
|
p.setOrderId(orderId);
|
||||||
|
}
|
||||||
p = payRepo.save(p);
|
p = payRepo.save(p);
|
||||||
|
|
||||||
// Crear transacción pendiente
|
// Crear transacción pendiente
|
||||||
@ -406,13 +443,17 @@ public class PaymentService {
|
|||||||
// ignorar
|
// ignorar
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4) Procesar el pedido asociado al carrito (si existe)
|
// 4) Procesar el pedido asociado al carrito (si existe) o marcar el pedido como pagado
|
||||||
if (cartId != null) {
|
if(p.getOrderId() != null) {
|
||||||
Long orderId = processOrder(cartId, dirFactId, locale);
|
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) {
|
if (orderId != null) {
|
||||||
p.setOrderId(orderId);
|
p.setOrderId(orderId);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
payRepo.save(p);
|
payRepo.save(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,30 +549,5 @@ public class PaymentService {
|
|||||||
return code >= 0 && code <= 99;
|
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;
|
package com.imprimelibros.erp.payments.repo;
|
||||||
|
|
||||||
import com.imprimelibros.erp.payments.model.Payment;
|
import com.imprimelibros.erp.payments.model.Payment;
|
||||||
|
import com.imprimelibros.erp.payments.model.PaymentStatus;
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface PaymentRepository extends JpaRepository<Payment, Long> {
|
public interface PaymentRepository extends JpaRepository<Payment, Long> {
|
||||||
Optional<Payment> findByGatewayAndGatewayOrderId(String gateway, String gatewayOrderId);
|
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> {
|
public interface PaymentTransactionRepository extends JpaRepository<PaymentTransaction, Long>, JpaSpecificationExecutor<PaymentTransaction> {
|
||||||
List<PaymentTransaction> findByGatewayTransactionId(String gatewayTransactionId);
|
List<PaymentTransaction> findByGatewayTransactionId(String gatewayTransactionId);
|
||||||
Optional<PaymentTransaction> findByIdempotencyKey(String idempotencyKey);
|
Optional<PaymentTransaction> findByIdempotencyKey(String idempotencyKey);
|
||||||
|
Optional<PaymentTransaction> findByPaymentIdAndType(
|
||||||
|
Long paymentId,
|
||||||
|
PaymentTransactionType type
|
||||||
|
);
|
||||||
Optional<PaymentTransaction> findFirstByPaymentIdAndTypeAndStatusOrderByIdDesc(
|
Optional<PaymentTransaction> findFirstByPaymentIdAndTypeAndStatusOrderByIdDesc(
|
||||||
Long paymentId,
|
Long paymentId,
|
||||||
PaymentTransactionType type,
|
PaymentTransactionType type,
|
||||||
|
|||||||
@ -10,12 +10,15 @@ import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
|
|||||||
public class PedidoLinea {
|
public class PedidoLinea {
|
||||||
|
|
||||||
public enum Estado {
|
public enum Estado {
|
||||||
aprobado("pedido.estado.aprobado", 1),
|
pendiente_pago("pedido.estado.pendiente_pago", 1),
|
||||||
maquetacion("pedido.estado.maquetacion", 2),
|
procesando_pago("pedido.estado.procesando_pago", 2),
|
||||||
haciendo_ferro("pedido.estado.haciendo_ferro", 3),
|
denegado_pago("pedido.estado.denegado_pago", 3),
|
||||||
ferro_cliente("pedido.estado.ferro_cliente", 4),
|
aprobado("pedido.estado.aprobado", 4),
|
||||||
produccion("pedido.estado.produccion", 5),
|
maquetacion("pedido.estado.maquetacion", 5),
|
||||||
cancelado("pedido.estado.cancelado", 6);
|
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 String messageKey;
|
||||||
private final int priority;
|
private final int priority;
|
||||||
|
|||||||
@ -11,6 +11,10 @@ import java.util.Map;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
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.common.Utils;
|
||||||
import com.imprimelibros.erp.direcciones.Direccion;
|
import com.imprimelibros.erp.direcciones.Direccion;
|
||||||
import com.imprimelibros.erp.presupuesto.PresupuestoRepository;
|
import com.imprimelibros.erp.presupuesto.PresupuestoRepository;
|
||||||
@ -30,10 +34,11 @@ public class PedidoService {
|
|||||||
private final DireccionService direccionService;
|
private final DireccionService direccionService;
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
private final PresupuestoService presupuestoService;
|
private final PresupuestoService presupuestoService;
|
||||||
|
private final CartService cartService;
|
||||||
|
|
||||||
public PedidoService(PedidoRepository pedidoRepository, PedidoLineaRepository pedidoLineaRepository,
|
public PedidoService(PedidoRepository pedidoRepository, PedidoLineaRepository pedidoLineaRepository,
|
||||||
PresupuestoRepository presupuestoRepository, PedidoDireccionRepository pedidoDireccionRepository,
|
PresupuestoRepository presupuestoRepository, PedidoDireccionRepository pedidoDireccionRepository,
|
||||||
DireccionService direccionService, UserService userService, PresupuestoService presupuestoService) {
|
DireccionService direccionService, UserService userService, PresupuestoService presupuestoService, CartService cartService) {
|
||||||
this.pedidoRepository = pedidoRepository;
|
this.pedidoRepository = pedidoRepository;
|
||||||
this.pedidoLineaRepository = pedidoLineaRepository;
|
this.pedidoLineaRepository = pedidoLineaRepository;
|
||||||
this.presupuestoRepository = presupuestoRepository;
|
this.presupuestoRepository = presupuestoRepository;
|
||||||
@ -41,48 +46,22 @@ public class PedidoService {
|
|||||||
this.direccionService = direccionService;
|
this.direccionService = direccionService;
|
||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
this.presupuestoService = presupuestoService;
|
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
|
@Transactional
|
||||||
public Pedido crearPedido(
|
public Pedido crearPedido(
|
||||||
List<Long> presupuestoIds,
|
Long cartId,
|
||||||
Map<String, Object> presupuestoDirecciones,
|
|
||||||
Long direccionFacturacionId,
|
Long direccionFacturacionId,
|
||||||
Map<String, Object> cartSummaryRaw,
|
|
||||||
String proveedor,
|
String proveedor,
|
||||||
String proveedorRef,
|
String proveedorRef) {
|
||||||
Long userId) {
|
|
||||||
|
|
||||||
Pedido pedido = new Pedido();
|
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)
|
// Datos económicos (ojo con las claves, son las del summaryRaw)
|
||||||
pedido.setBase((Double) cartSummaryRaw.getOrDefault("base", 0.0d));
|
pedido.setBase((Double) cartSummaryRaw.getOrDefault("base", 0.0d));
|
||||||
pedido.setEnvio((Double) cartSummaryRaw.getOrDefault("shipment", 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));
|
pedido.setTotal((Double) cartSummaryRaw.getOrDefault("total", 0.0d));
|
||||||
|
|
||||||
// Proveedor
|
// Proveedor
|
||||||
pedido.setProveedor(proveedor);
|
if(proveedor != null && proveedorRef != null) {
|
||||||
pedido.setProveedorRef(proveedorRef);
|
pedido.setProveedor(proveedor);
|
||||||
|
pedido.setProveedorRef(proveedorRef);
|
||||||
|
}
|
||||||
|
|
||||||
// Auditoría mínima
|
// Auditoría mínima
|
||||||
|
Long userId = cart.getUserId();
|
||||||
pedido.setCreatedBy(userService.findById(userId));
|
pedido.setCreatedBy(userService.findById(userId));
|
||||||
pedido.setCreatedAt(Instant.now());
|
pedido.setCreatedAt(Instant.now());
|
||||||
pedido.setDeleted(false);
|
pedido.setDeleted(false);
|
||||||
@ -103,8 +85,36 @@ public class PedidoService {
|
|||||||
pedido.setUpdatedBy(userService.findById(userId));
|
pedido.setUpdatedBy(userService.findById(userId));
|
||||||
|
|
||||||
// Guardamos el pedido
|
// 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
|
// Crear líneas del pedido
|
||||||
for (Long presupuestoId : presupuestoIds) {
|
for (Long presupuestoId : presupuestoIds) {
|
||||||
Presupuesto presupuesto = presupuestoRepository.getReferenceById(presupuestoId);
|
Presupuesto presupuesto = presupuestoRepository.getReferenceById(presupuestoId);
|
||||||
@ -114,7 +124,11 @@ public class PedidoService {
|
|||||||
linea.setPresupuesto(presupuesto);
|
linea.setPresupuesto(presupuesto);
|
||||||
linea.setCreatedBy(userId);
|
linea.setCreatedBy(userId);
|
||||||
linea.setCreatedAt(LocalDateTime.now());
|
linea.setCreatedAt(LocalDateTime.now());
|
||||||
linea.setEstado(getEstadoInicial(presupuesto));
|
if(estadoInicial != null){
|
||||||
|
linea.setEstado(estadoInicial);
|
||||||
|
} else {
|
||||||
|
linea.setEstado(getEstadoInicial(presupuesto));
|
||||||
|
}
|
||||||
linea.setEstadoManual(false);
|
linea.setEstadoManual(false);
|
||||||
pedidoLineaRepository.save(linea);
|
pedidoLineaRepository.save(linea);
|
||||||
|
|
||||||
@ -125,10 +139,175 @@ public class PedidoService {
|
|||||||
saveDireccionesPedidoLinea(direcciones, saved, linea, direccionFacturacionId);
|
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*/
|
/** Lista de los items del pedido preparados para la vista*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public List<Map<String, Object>> getLineas(Long pedidoId, Locale locale) {
|
public List<Map<String, Object>> getLineas(Long pedidoId, Locale locale) {
|
||||||
@ -160,17 +339,119 @@ public class PedidoService {
|
|||||||
return pedidoDireccionRepository.findByPedidoLinea_Id(pedidoLineaId);
|
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
|
* 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
|
@Transactional
|
||||||
private void saveDireccionesPedidoLinea(
|
private void saveDireccionesPedidoLinea(
|
||||||
Map<String, Map<String, Object>> direcciones,
|
Map<String, Object> direcciones,
|
||||||
Pedido pedido,
|
Pedido pedido,
|
||||||
PedidoLinea linea, Long direccionFacturacionId) {
|
PedidoLinea linea, Long direccionFacturacionId) {
|
||||||
// direccion prueba
|
// direccion prueba
|
||||||
if (direcciones.containsKey("direccionesFP1")) {
|
if (direcciones.containsKey("direccionesFP1")) {
|
||||||
try {
|
try {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
Map<String, Object> fp1 = (Map<String, Object>) direcciones.get("direccionesFP1");
|
Map<String, Object> fp1 = (Map<String, Object>) direcciones.get("direccionesFP1");
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
PedidoDireccion direccion = saveDireccion(
|
PedidoDireccion direccion = saveDireccion(
|
||||||
|
|||||||
@ -166,9 +166,16 @@ public class PedidosController {
|
|||||||
return text;
|
return text;
|
||||||
})
|
})
|
||||||
.add("actions", pedido -> {
|
.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;\'>"
|
+ "\' style=\'cursor: pointer;\'>"
|
||||||
+ messageSource.getMessage("app.view", null, locale) + "</span>";
|
+ 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)
|
.where(base)
|
||||||
.toJson(total);
|
.toJson(total);
|
||||||
|
|||||||
@ -1,10 +1,15 @@
|
|||||||
package com.imprimelibros.erp.redsys;
|
package com.imprimelibros.erp.redsys;
|
||||||
|
|
||||||
|
import com.imprimelibros.erp.cart.Cart;
|
||||||
import com.imprimelibros.erp.common.Utils;
|
import com.imprimelibros.erp.common.Utils;
|
||||||
import com.imprimelibros.erp.payments.PaymentService;
|
import com.imprimelibros.erp.payments.PaymentService;
|
||||||
import com.imprimelibros.erp.payments.model.Payment;
|
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 com.imprimelibros.erp.redsys.RedsysService.FormPayload;
|
||||||
|
|
||||||
|
import groovy.util.logging.Log;
|
||||||
import jakarta.servlet.ServletContext;
|
import jakarta.servlet.ServletContext;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
@ -27,6 +32,7 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
|||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@ -37,13 +43,16 @@ public class RedsysController {
|
|||||||
private final MessageSource messageSource;
|
private final MessageSource messageSource;
|
||||||
private final SpringTemplateEngine templateEngine;
|
private final SpringTemplateEngine templateEngine;
|
||||||
private final ServletContext servletContext;
|
private final ServletContext servletContext;
|
||||||
|
private final PedidoService pedidoService;
|
||||||
|
|
||||||
public RedsysController(PaymentService paymentService, MessageSource messageSource,
|
public RedsysController(PaymentService paymentService, MessageSource messageSource,
|
||||||
SpringTemplateEngine templateEngine, ServletContext servletContext) {
|
SpringTemplateEngine templateEngine, ServletContext servletContext,
|
||||||
|
PedidoService pedidoService) {
|
||||||
this.paymentService = paymentService;
|
this.paymentService = paymentService;
|
||||||
this.messageSource = messageSource;
|
this.messageSource = messageSource;
|
||||||
this.templateEngine = templateEngine;
|
this.templateEngine = templateEngine;
|
||||||
this.servletContext = servletContext;
|
this.servletContext = servletContext;
|
||||||
|
this.pedidoService = pedidoService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/crear", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
@PostMapping(value = "/crear", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||||
@ -55,9 +64,15 @@ public class RedsysController {
|
|||||||
HttpServletResponse response, Locale locale)
|
HttpServletResponse response, Locale locale)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
||||||
|
// Creamos el pedido inteno
|
||||||
|
Pedido order = pedidoService.crearPedido(cartId, dirFactId, null, null);
|
||||||
|
|
||||||
if ("bank-transfer".equalsIgnoreCase(method)) {
|
if ("bank-transfer".equalsIgnoreCase(method)) {
|
||||||
|
|
||||||
// 1) Creamos el Payment interno SIN orderId (null)
|
// 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)
|
// 1️⃣ Crear la "aplicación" web de Thymeleaf (Jakarta)
|
||||||
JakartaServletWebApplication app = JakartaServletWebApplication.buildApplication(servletContext);
|
JakartaServletWebApplication app = JakartaServletWebApplication.buildApplication(servletContext);
|
||||||
@ -89,7 +104,102 @@ public class RedsysController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Tarjeta o Bizum (Redsys)
|
// 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 = """
|
String html = """
|
||||||
<html><head><meta charset="utf-8"><title>Redirigiendo a Redsys…</title></head>
|
<html><head><meta charset="utf-8"><title>Redirigiendo a Redsys…</title></head>
|
||||||
|
|||||||
@ -0,0 +1,32 @@
|
|||||||
|
databaseChangeLog:
|
||||||
|
- changeSet:
|
||||||
|
id: 0019-add-estados-pago-to-pedidos-lineas
|
||||||
|
author: jjo
|
||||||
|
changes:
|
||||||
|
- modifyDataType:
|
||||||
|
tableName: pedidos_lineas
|
||||||
|
columnName: estado
|
||||||
|
newDataType: >
|
||||||
|
enum(
|
||||||
|
'pendiente_pago',
|
||||||
|
'procesando_pago',
|
||||||
|
'aprobado',
|
||||||
|
'maquetacion',
|
||||||
|
'haciendo_ferro',
|
||||||
|
'produccion',
|
||||||
|
'terminado',
|
||||||
|
'cancelado'
|
||||||
|
)
|
||||||
|
rollback:
|
||||||
|
- modifyDataType:
|
||||||
|
tableName: pedidos_lineas
|
||||||
|
columnName: estado
|
||||||
|
newDataType: >
|
||||||
|
enum(
|
||||||
|
'aprobado',
|
||||||
|
'maquetacion',
|
||||||
|
'haciendo_ferro',
|
||||||
|
'produccion',
|
||||||
|
'terminado',
|
||||||
|
'cancelado'
|
||||||
|
)
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
databaseChangeLog:
|
||||||
|
- changeSet:
|
||||||
|
id: 0020-add-estados-pago-to-pedidos-lineas-2
|
||||||
|
author: jjo
|
||||||
|
changes:
|
||||||
|
- modifyDataType:
|
||||||
|
tableName: pedidos_lineas
|
||||||
|
columnName: estado
|
||||||
|
newDataType: >
|
||||||
|
enum(
|
||||||
|
'pendiente_pago',
|
||||||
|
'procesando_pago',
|
||||||
|
'denegado_pago',
|
||||||
|
'aprobado',
|
||||||
|
'maquetacion',
|
||||||
|
'haciendo_ferro',
|
||||||
|
'produccion',
|
||||||
|
'terminado',
|
||||||
|
'cancelado'
|
||||||
|
)
|
||||||
|
rollback:
|
||||||
|
- modifyDataType:
|
||||||
|
tableName: pedidos_lineas
|
||||||
|
columnName: estado
|
||||||
|
newDataType: >
|
||||||
|
enum(
|
||||||
|
'pendiente_pago',
|
||||||
|
'procesando_pago',
|
||||||
|
'aprobado',
|
||||||
|
'maquetacion',
|
||||||
|
'haciendo_ferro',
|
||||||
|
'produccion',
|
||||||
|
'terminado',
|
||||||
|
'cancelado'
|
||||||
|
)
|
||||||
@ -35,3 +35,7 @@ databaseChangeLog:
|
|||||||
file: db/changelog/changesets/0017-add-fecha-entrega-to-pedidos-lineas.yml
|
file: db/changelog/changesets/0017-add-fecha-entrega-to-pedidos-lineas.yml
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/changesets/0018-change-presupuesto-ch-3.yml
|
file: db/changelog/changesets/0018-change-presupuesto-ch-3.yml
|
||||||
|
- include:
|
||||||
|
file: db/changelog/changesets/0019-add-estados-pago-to-pedidos-lineas.yml
|
||||||
|
- include:
|
||||||
|
file: db/changelog/changesets/0020-add-estados-pago-to-pedidos-lineas-2.yml
|
||||||
@ -11,6 +11,7 @@ app.back=Volver
|
|||||||
app.eliminar=Eliminar
|
app.eliminar=Eliminar
|
||||||
app.imprimir=Imprimir
|
app.imprimir=Imprimir
|
||||||
app.view=Ver
|
app.view=Ver
|
||||||
|
app.pay=Pagar
|
||||||
app.acciones.siguiente=Siguiente
|
app.acciones.siguiente=Siguiente
|
||||||
app.acciones.anterior=Anterior
|
app.acciones.anterior=Anterior
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,9 @@ checkout.success.payment=Pago realizado con éxito. Gracias por su compra.
|
|||||||
checkout.make-payment=Realizar el pago
|
checkout.make-payment=Realizar el pago
|
||||||
checkout.authorization-required=Certifico que tengo los derechos para imprimir los archivos incluidos en mi pedido y me hago responsable en caso de reclamación de los mismos
|
checkout.authorization-required=Certifico que tengo los derechos para imprimir los archivos incluidos en mi pedido y me hago responsable en caso de reclamación de los mismos
|
||||||
|
|
||||||
|
pedido.estado.pendiente_pago=Pendiente de pago
|
||||||
|
pedido.estado.procesando_pago=Procesando pago
|
||||||
|
pedido.estado.denegado_pago=Pago denegado
|
||||||
pedido.estado.aprobado=Aprobado
|
pedido.estado.aprobado=Aprobado
|
||||||
pedido.estado.maquetacion=Maquetación
|
pedido.estado.maquetacion=Maquetación
|
||||||
pedido.estado.haciendo_ferro=Haciendo ferro
|
pedido.estado.haciendo_ferro=Haciendo ferro
|
||||||
|
|||||||
@ -5,4 +5,42 @@ $(() => {
|
|||||||
window.location.href = url;
|
window.location.href = url;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '.btn-pay', function () {
|
||||||
|
|
||||||
|
const csrfToken = document.querySelector('meta[name="_csrf"]')?.getAttribute('content');
|
||||||
|
const csrfHeader = document.querySelector('meta[name="_csrf_header"]')?.getAttribute('content');
|
||||||
|
if (window.$ && csrfToken && csrfHeader) {
|
||||||
|
$.ajaxSetup({
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
xhr.setRequestHeader(csrfHeader, csrfToken);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let pedidoId = $(this).data('id');
|
||||||
|
let amount = $(this).data('amount');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: `/pagos/redsys/reintentar`,
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
amountCents: amount,
|
||||||
|
orderId: pedidoId
|
||||||
|
},
|
||||||
|
success: function (response) {
|
||||||
|
if (response && response.formHtml) {
|
||||||
|
$('body').append(response.formHtml);
|
||||||
|
$('#redsys-payment-form').submit();
|
||||||
|
} else {
|
||||||
|
alert('Error al procesar el pago. Por favor, inténtelo de nuevo.');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
alert('Error al procesar el pago. Por favor, inténtelo de nuevo.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
})
|
})
|
||||||
@ -18,7 +18,7 @@ public class envioCarroTest {
|
|||||||
void addPedido(){
|
void addPedido(){
|
||||||
|
|
||||||
Locale locale = Locale.forLanguageTag("es-ES");
|
Locale locale = Locale.forLanguageTag("es-ES");
|
||||||
cartService.crearPedido(carritoId, null, locale);
|
//cartService.crearPedido(carritoId, null, locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -17,10 +17,10 @@ public class savePresupuestosTest {
|
|||||||
@Test
|
@Test
|
||||||
void testGuardarPresupuesto() {
|
void testGuardarPresupuesto() {
|
||||||
Locale locale = new Locale("es", "ES");
|
Locale locale = new Locale("es", "ES");
|
||||||
Long resultado = cartService.crearPedido(9L, null, locale);
|
//Long resultado = cartService.crearPedido(9L, null, locale);
|
||||||
|
|
||||||
System.out.println("📦 Presupuesto guardado:");
|
System.out.println("📦 Presupuesto guardado:");
|
||||||
System.out.println(resultado);
|
//System.out.println(resultado);
|
||||||
|
|
||||||
// Aquí irían las aserciones para verificar que el presupuesto se guardó correctamente
|
// Aquí irían las aserciones para verificar que el presupuesto se guardó correctamente
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user