mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-24 09:40:21 +00:00
Compare commits
5 Commits
d31a6e9e8e
...
84a822db22
| Author | SHA1 | Date | |
|---|---|---|---|
| 84a822db22 | |||
| 69f27df98b | |||
| 6bd36dbe8c | |||
| 3086a6de41 | |||
| 4f1b3f2bb6 |
3376
logs/erp.log
3376
logs/erp.log
File diff suppressed because it is too large
Load Diff
@ -445,7 +445,6 @@ public class CartService {
|
|||||||
cartDireccionRepo.deleteByDireccionIdAndCartStatus(direccionId, Cart.Status.ACTIVE);
|
cartDireccionRepo.deleteByDireccionIdAndCartStatus(direccionId, Cart.Status.ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public Long crearPedido(Long cartId, Locale locale) {
|
public Long crearPedido(Long cartId, Locale locale) {
|
||||||
|
|
||||||
@ -483,7 +482,9 @@ public class CartService {
|
|||||||
Map<String, Object> result = skApiClient.savePresupuesto(data_to_send);
|
Map<String, Object> result = skApiClient.savePresupuesto(data_to_send);
|
||||||
|
|
||||||
if (result.containsKey("error")) {
|
if (result.containsKey("error")) {
|
||||||
System.out.println("Error al guardar presupuesto en SK: " + result.get("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:
|
// decide si seguir con otros items o abortar:
|
||||||
// continue; o bien throw ...
|
// continue; o bien throw ...
|
||||||
continue;
|
continue;
|
||||||
@ -538,11 +539,23 @@ public class CartService {
|
|||||||
if (cart.getOnlyOneShipment()) {
|
if (cart.getOnlyOneShipment()) {
|
||||||
List<CartDireccion> direcciones = cart.getDirecciones().stream().limit(1).toList();
|
List<CartDireccion> direcciones = cart.getDirecciones().stream().limit(1).toList();
|
||||||
if (!direcciones.isEmpty()) {
|
if (!direcciones.isEmpty()) {
|
||||||
direccionesPresupuesto.add(direcciones.get(0).toSkMap(
|
if (presupuesto.getServiciosJson() != null
|
||||||
presupuesto.getSelectedTirada(),
|
&& presupuesto.getServiciosJson().contains("deposito-legal")) {
|
||||||
presupuesto.getPeso(),
|
direccionesPresupuesto.add(direcciones.get(0).toSkMap(
|
||||||
direcciones.get(0).getIsPalets(),
|
presupuesto.getSelectedTirada()-4,
|
||||||
false));
|
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
|
if (presupuesto.getServiciosJson() != null
|
||||||
&& presupuesto.getServiciosJson().contains("ejemplar-prueba")) {
|
&& presupuesto.getServiciosJson().contains("ejemplar-prueba")) {
|
||||||
direccionesPrueba.add(direcciones.get(0).toSkMap(
|
direccionesPrueba.add(direcciones.get(0).toSkMap(
|
||||||
@ -551,10 +564,7 @@ public class CartService {
|
|||||||
false,
|
false,
|
||||||
true));
|
true));
|
||||||
}
|
}
|
||||||
if (presupuesto.getServiciosJson() != null
|
|
||||||
&& presupuesto.getServiciosJson().contains("deposito-legal")) {
|
|
||||||
direccionesPresupuesto.add(direcciones.get(0).toSkMapDepositoLegal());
|
|
||||||
}
|
|
||||||
Map<String, Object> direccionesRet = new HashMap<>();
|
Map<String, Object> direccionesRet = new HashMap<>();
|
||||||
direccionesRet.put("direcciones", direccionesPresupuesto);
|
direccionesRet.put("direcciones", direccionesPresupuesto);
|
||||||
if (!direccionesPrueba.isEmpty())
|
if (!direccionesPrueba.isEmpty())
|
||||||
|
|||||||
@ -2,8 +2,6 @@ package com.imprimelibros.erp.direcciones;
|
|||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.hibernate.annotations.SQLDelete;
|
import org.hibernate.annotations.SQLDelete;
|
||||||
import org.hibernate.annotations.SQLRestriction;
|
import org.hibernate.annotations.SQLRestriction;
|
||||||
|
|||||||
@ -32,7 +32,6 @@ import com.imprimelibros.erp.users.UserDao;
|
|||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/pagos")
|
@RequestMapping("/pagos")
|
||||||
|
|||||||
@ -37,7 +37,7 @@ public class PaymentService {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
@ -83,7 +83,8 @@ public class PaymentService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void handleRedsysNotification(String dsSignature, String dsMerchantParameters, Locale locale) throws Exception {
|
public void handleRedsysNotification(String dsSignature, String dsMerchantParameters, Locale locale)
|
||||||
|
throws Exception {
|
||||||
|
|
||||||
// 0) Intentamos parsear la notificación. Si falla, registramos el webhook crudo
|
// 0) Intentamos parsear la notificación. Si falla, registramos el webhook crudo
|
||||||
// y salimos.
|
// y salimos.
|
||||||
@ -169,13 +170,20 @@ public class PaymentService {
|
|||||||
? PaymentTransactionStatus.succeeded
|
? PaymentTransactionStatus.succeeded
|
||||||
: PaymentTransactionStatus.failed);
|
: PaymentTransactionStatus.failed);
|
||||||
|
|
||||||
Object authCode = notif.raw.get("Ds_AuthorisationCode");
|
|
||||||
String gatewayTxId = null;
|
String gatewayTxId = null;
|
||||||
if (authCode != null) {
|
// 1) Si es Bizum y tenemos Ds_Bizum_IdOper, úsalo como ID único
|
||||||
String trimmed = String.valueOf(authCode).trim();
|
if (notif.isBizum()
|
||||||
// Redsys devuelve " " (espacios) cuando NO hay código de autorización.
|
&& notif.bizumIdOper != null
|
||||||
// Eso lo consideramos "sin ID" → null, para no chocar con el índice único.
|
&& !notif.bizumIdOper.isBlank()) {
|
||||||
if (!trimmed.isEmpty()) {
|
|
||||||
|
gatewayTxId = notif.bizumIdOper.trim();
|
||||||
|
|
||||||
|
// 2) Si no es Bizum, intenta usar Ds_AuthorisationCode
|
||||||
|
} else if (notif.authorisationCode != null) {
|
||||||
|
String trimmed = notif.authorisationCode.trim();
|
||||||
|
|
||||||
|
// Redsys suele mandar "000000" para Bizum; por si acaso también lo filtramos
|
||||||
|
if (!trimmed.isEmpty() && !"000000".equals(trimmed)) {
|
||||||
gatewayTxId = trimmed;
|
gatewayTxId = trimmed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,7 +195,14 @@ public class PaymentService {
|
|||||||
txRepo.save(tx);
|
txRepo.save(tx);
|
||||||
|
|
||||||
if (authorized) {
|
if (authorized) {
|
||||||
p.setAuthorizationCode(tx.getGatewayTransactionId());
|
if (notif.isBizum()) {
|
||||||
|
p.setAuthorizationCode(null); // o "000000" si te interesa mostrarlo
|
||||||
|
} else if (notif.authorisationCode != null
|
||||||
|
&& !"000000".equals(notif.authorisationCode.trim())
|
||||||
|
&& !notif.authorisationCode.isBlank()) {
|
||||||
|
p.setAuthorizationCode(notif.authorisationCode.trim());
|
||||||
|
}
|
||||||
|
|
||||||
p.setStatus(PaymentStatus.captured);
|
p.setStatus(PaymentStatus.captured);
|
||||||
p.setAmountCapturedCents(p.getAmountCapturedCents() + notif.amountCents);
|
p.setAmountCapturedCents(p.getAmountCapturedCents() + notif.amountCents);
|
||||||
p.setAuthorizedAt(LocalDateTime.now());
|
p.setAuthorizedAt(LocalDateTime.now());
|
||||||
@ -258,6 +273,14 @@ public class PaymentService {
|
|||||||
throw new IllegalStateException("Error al solicitar la devolución a Redsys", e);
|
throw new IllegalStateException("Error al solicitar la devolución a Redsys", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🔧 NORMALIZAR ANTES DE GUARDAR
|
||||||
|
if (gatewayRefundId != null) {
|
||||||
|
gatewayRefundId = gatewayRefundId.trim();
|
||||||
|
if (gatewayRefundId.isEmpty() || "000000".equals(gatewayRefundId)) {
|
||||||
|
gatewayRefundId = null; // → múltiples NULL NO rompen el UNIQUE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PaymentTransaction tx = new PaymentTransaction();
|
PaymentTransaction tx = new PaymentTransaction();
|
||||||
tx.setPayment(p);
|
tx.setPayment(p);
|
||||||
tx.setType(PaymentTransactionType.REFUND);
|
tx.setType(PaymentTransactionType.REFUND);
|
||||||
@ -459,17 +482,16 @@ public class PaymentService {
|
|||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
private Boolean processOrder(Long cartId, Locale locale) {
|
private Boolean processOrder(Long cartId, Locale locale) {
|
||||||
|
|
||||||
Cart cart = this.cartService.findById(cartId);
|
Cart cart = this.cartService.findById(cartId);
|
||||||
if (cart != null) {
|
if (cart != null) {
|
||||||
// Bloqueamos el carrito
|
// Bloqueamos el carrito
|
||||||
this.cartService.lockCartById(cart.getId());
|
this.cartService.lockCartById(cart.getId());
|
||||||
// Creamos el pedido
|
// Creamos el pedido
|
||||||
Long orderId = this.cartService.crearPedido(cart.getId(), locale);
|
Long orderId = this.cartService.crearPedido(cart.getId(), locale);
|
||||||
if(orderId == null){
|
if (orderId == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
// envio de correo de confirmacion de pedido podria ir aqui
|
// envio de correo de confirmacion de pedido podria ir aqui
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,9 +6,6 @@ import java.time.LocalDateTime;
|
|||||||
@Entity
|
@Entity
|
||||||
@Table(
|
@Table(
|
||||||
name = "payment_transactions",
|
name = "payment_transactions",
|
||||||
uniqueConstraints = {
|
|
||||||
@UniqueConstraint(name = "uq_tx_gateway_txid", columnNames = {"gateway_transaction_id"})
|
|
||||||
},
|
|
||||||
indexes = {
|
indexes = {
|
||||||
@Index(name = "idx_tx_pay", columnList = "payment_id"),
|
@Index(name = "idx_tx_pay", columnList = "payment_id"),
|
||||||
@Index(name = "idx_tx_type_status", columnList = "type,status"),
|
@Index(name = "idx_tx_type_status", columnList = "type,status"),
|
||||||
|
|||||||
@ -8,10 +8,11 @@ import com.imprimelibros.erp.payments.model.PaymentTransactionType;
|
|||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface PaymentTransactionRepository extends JpaRepository<PaymentTransaction, Long>, JpaSpecificationExecutor<PaymentTransaction> {
|
public interface PaymentTransactionRepository extends JpaRepository<PaymentTransaction, Long>, JpaSpecificationExecutor<PaymentTransaction> {
|
||||||
Optional<PaymentTransaction> findByGatewayTransactionId(String gatewayTransactionId);
|
List<PaymentTransaction> findByGatewayTransactionId(String gatewayTransactionId);
|
||||||
Optional<PaymentTransaction> findByIdempotencyKey(String idempotencyKey);
|
Optional<PaymentTransaction> findByIdempotencyKey(String idempotencyKey);
|
||||||
Optional<PaymentTransaction> findFirstByPaymentIdAndTypeAndStatusOrderByIdDesc(
|
Optional<PaymentTransaction> findFirstByPaymentIdAndTypeAndStatusOrderByIdDesc(
|
||||||
Long paymentId,
|
Long paymentId,
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
|
|
||||||
import com.imprimelibros.erp.presupuesto.PresupuestoRepository;
|
import com.imprimelibros.erp.presupuesto.PresupuestoRepository;
|
||||||
import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
|
import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
|
||||||
import com.imprimelibros.erp.presupuesto.service.PresupuestoService;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class PedidoService {
|
public class PedidoService {
|
||||||
|
|||||||
@ -189,9 +189,9 @@ public class RedsysController {
|
|||||||
try {
|
try {
|
||||||
String idem = "refund-" + paymentId + "-" + amountCents + "-" + UUID.randomUUID();
|
String idem = "refund-" + paymentId + "-" + amountCents + "-" + UUID.randomUUID();
|
||||||
paymentService.refundViaRedsys(paymentId, amountCents, idem);
|
paymentService.refundViaRedsys(paymentId, amountCents, idem);
|
||||||
return ResponseEntity.ok("{success:true}");
|
return ResponseEntity.ok("{\"success\":true}");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return ResponseEntity.badRequest().body("{success:false, error: '" + e.getMessage() + "'}");
|
return ResponseEntity.badRequest().body("{\"success\":false, \"error\": \"" + e.getMessage() + "\"}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -195,6 +195,9 @@ public class RedsysService {
|
|||||||
public final long amountCents;
|
public final long amountCents;
|
||||||
public final String currency;
|
public final String currency;
|
||||||
public final Long cartId;
|
public final Long cartId;
|
||||||
|
public final String processedPayMethod; // Ds_ProcessedPayMethod
|
||||||
|
public final String bizumIdOper; // Ds_Bizum_IdOper
|
||||||
|
public final String authorisationCode; // Ds_AuthorisationCode
|
||||||
|
|
||||||
public RedsysNotification(Map<String, Object> raw) {
|
public RedsysNotification(Map<String, Object> raw) {
|
||||||
this.raw = raw;
|
this.raw = raw;
|
||||||
@ -203,6 +206,9 @@ public class RedsysService {
|
|||||||
this.currency = str(raw.get("Ds_Currency"));
|
this.currency = str(raw.get("Ds_Currency"));
|
||||||
this.amountCents = parseLongSafe(raw.get("Ds_Amount"));
|
this.amountCents = parseLongSafe(raw.get("Ds_Amount"));
|
||||||
this.cartId = extractCartId(raw.get("Ds_MerchantData"));
|
this.cartId = extractCartId(raw.get("Ds_MerchantData"));
|
||||||
|
this.processedPayMethod = str(raw.get("Ds_ProcessedPayMethod"));
|
||||||
|
this.bizumIdOper = str(raw.get("Ds_Bizum_IdOper"));
|
||||||
|
this.authorisationCode = str(raw.get("Ds_AuthorisationCode"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Long extractCartId(Object merchantDataObj) {
|
private static Long extractCartId(Object merchantDataObj) {
|
||||||
@ -231,6 +237,11 @@ public class RedsysService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isBizum() {
|
||||||
|
// Redsys suele usar 68 para Bizum; ajustable si tu banco usa otro código.
|
||||||
|
return "68".equals(processedPayMethod);
|
||||||
|
}
|
||||||
|
|
||||||
private static String str(Object o) {
|
private static String str(Object o) {
|
||||||
return o == null ? null : String.valueOf(o);
|
return o == null ? null : String.valueOf(o);
|
||||||
}
|
}
|
||||||
@ -245,7 +256,7 @@ public class RedsysService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Solicita a Redsys una devolución (TransactionType = 3)
|
* Solicita a Redsys una devolución (TransactionType = 3)
|
||||||
*
|
*
|
||||||
* @param order El mismo Ds_Merchant_Order que se usó en el cobro.
|
* @param order El mismo Ds_Merchant_Order que se usó en el cobro.
|
||||||
* @param amountCents Importe en céntimos a devolver.
|
* @param amountCents Importe en céntimos a devolver.
|
||||||
@ -308,14 +319,35 @@ public class RedsysService {
|
|||||||
|
|
||||||
// Decodificar MerchantParameters de la respuesta
|
// Decodificar MerchantParameters de la respuesta
|
||||||
Map<String, Object> decoded = decodeMerchantParametersToMap(dsMerchantParametersResp);
|
Map<String, Object> decoded = decodeMerchantParametersToMap(dsMerchantParametersResp);
|
||||||
|
|
||||||
String dsResponse = String.valueOf(decoded.get("Ds_Response"));
|
String dsResponse = String.valueOf(decoded.get("Ds_Response"));
|
||||||
if (!"0900".equals(dsResponse)) {
|
if (dsResponse == null) {
|
||||||
|
throw new IllegalStateException("Respuesta Redsys refund sin Ds_Response");
|
||||||
|
}
|
||||||
|
|
||||||
|
int code;
|
||||||
|
try {
|
||||||
|
code = Integer.parseInt(dsResponse);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new IllegalStateException("Código Ds_Response no numérico en refund: " + dsResponse, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ Consideramos OK: 0–99 (éxito típico) o 900 (0900)
|
||||||
|
boolean ok = (code >= 0 && code <= 99) || code == 900;
|
||||||
|
if (!ok) {
|
||||||
throw new IllegalStateException("Devolución rechazada, Ds_Response=" + dsResponse);
|
throw new IllegalStateException("Devolución rechazada, Ds_Response=" + dsResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
return String.valueOf(decoded.getOrDefault("Ds_AuthorisationCode", order));
|
// Devolvemos algún identificador razonable para la transacción de refund
|
||||||
|
Object authCodeObj = decoded.get("Ds_AuthorisationCode");
|
||||||
|
String authCode = authCodeObj != null ? String.valueOf(authCodeObj).trim() : null;
|
||||||
|
|
||||||
|
if (authCode == null || authCode.isEmpty()) {
|
||||||
|
// Fallback: usa el Ds_Order original como ID de refund
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
return authCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
databaseChangeLog:
|
||||||
|
- changeSet:
|
||||||
|
id: 0012--drop-unique-gateway-txid-2
|
||||||
|
author: jjo
|
||||||
|
changes:
|
||||||
|
# 1) Eliminar el índice UNIQUE actual
|
||||||
|
- dropIndex:
|
||||||
|
indexName: uq_tx_gateway_txid
|
||||||
|
tableName: payment_transactions
|
||||||
|
|
||||||
|
# 2) Crear un índice normal (no único) sobre gateway_transaction_id
|
||||||
|
- createIndex:
|
||||||
|
indexName: idx_tx_gateway_txid
|
||||||
|
tableName: payment_transactions
|
||||||
|
columns:
|
||||||
|
- column:
|
||||||
|
name: gateway_transaction_id
|
||||||
|
|
||||||
|
rollback:
|
||||||
|
# Rollback: volver al índice UNIQUE como estaba antes
|
||||||
|
- dropIndex:
|
||||||
|
indexName: idx_tx_gateway_txid
|
||||||
|
tableName: payment_transactions
|
||||||
|
|
||||||
|
- createIndex:
|
||||||
|
indexName: uq_tx_gateway_txid
|
||||||
|
tableName: payment_transactions
|
||||||
|
unique: true
|
||||||
|
columns:
|
||||||
|
- column:
|
||||||
|
name: gateway_transaction_id
|
||||||
@ -1,28 +0,0 @@
|
|||||||
databaseChangeLog:
|
|
||||||
- changeSet:
|
|
||||||
id: 0012-drop-unique-tx-gateway
|
|
||||||
author: JJO
|
|
||||||
|
|
||||||
# ✅ Solo ejecuta el changeSet si existe la UNIQUE constraint
|
|
||||||
preConditions:
|
|
||||||
- onFail: MARK_RAN
|
|
||||||
- uniqueConstraintExists:
|
|
||||||
tableName: payment_transactions
|
|
||||||
constraintName: idx_payment_tx_gateway_txid
|
|
||||||
|
|
||||||
changes:
|
|
||||||
# 1️⃣ Eliminar la UNIQUE constraint si existe
|
|
||||||
- dropIndex:
|
|
||||||
tableName: payment_transactions
|
|
||||||
indexName: idx_payment_tx_gateway_txid
|
|
||||||
|
|
||||||
|
|
||||||
rollback:
|
|
||||||
# 🔙 1) Eliminar el índice normal creado en este changeSet
|
|
||||||
- createIndex:
|
|
||||||
tableName: payment_transactions
|
|
||||||
indexName: idx_payment_tx_gateway_txid
|
|
||||||
columns:
|
|
||||||
- column:
|
|
||||||
name: gateway_transaction_id
|
|
||||||
|
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
databaseChangeLog:
|
||||||
|
- changeSet:
|
||||||
|
id: 0013-drop-unique-refund-gateway-id
|
||||||
|
author: jjo
|
||||||
|
changes:
|
||||||
|
# 1) Eliminar el índice UNIQUE actual sobre gateway_refund_id
|
||||||
|
- dropIndex:
|
||||||
|
indexName: uq_refund_gateway_id
|
||||||
|
tableName: refunds
|
||||||
|
|
||||||
|
# 2) Crear un índice normal (no único) sobre gateway_refund_id
|
||||||
|
- createIndex:
|
||||||
|
indexName: idx_refund_gateway_id
|
||||||
|
tableName: refunds
|
||||||
|
columns:
|
||||||
|
- column:
|
||||||
|
name: gateway_refund_id
|
||||||
|
|
||||||
|
rollback:
|
||||||
|
# Rollback: quitar el índice normal
|
||||||
|
- dropIndex:
|
||||||
|
indexName: idx_refund_gateway_id
|
||||||
|
tableName: refunds
|
||||||
|
|
||||||
|
# y restaurar el UNIQUE como estaba antes
|
||||||
|
- createIndex:
|
||||||
|
indexName: uq_refund_gateway_id
|
||||||
|
tableName: refunds
|
||||||
|
unique: true
|
||||||
|
columns:
|
||||||
|
- column:
|
||||||
|
name: gateway_refund_id
|
||||||
|
|
||||||
@ -20,4 +20,8 @@ databaseChangeLog:
|
|||||||
- include:
|
- include:
|
||||||
file: db/changelog/changesets/0010-drop-unique-tx-gateway.yml
|
file: db/changelog/changesets/0010-drop-unique-tx-gateway.yml
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/changesets/0011-update-pedidos-presupuesto.yml
|
file: db/changelog/changesets/0011-update-pedidos-presupuesto.yml
|
||||||
|
- include:
|
||||||
|
file: db/changelog/changesets/0012--drop-unique-gateway-txid-2.yml
|
||||||
|
- include:
|
||||||
|
file: db/changelog/changesets/0013-drop-unique-refund-gateway-id.yml
|
||||||
@ -20,8 +20,8 @@ $(() => {
|
|||||||
// Actualizar al cargar
|
// Actualizar al cargar
|
||||||
updateCartCount();
|
updateCartCount();
|
||||||
|
|
||||||
// Si quieres refrescar cada 60s:
|
// Si quieres refrescar cada 10s:
|
||||||
setInterval(updateCartCount, 60000);
|
setInterval(updateCartCount, 10000);
|
||||||
|
|
||||||
// generate a custom event to update the cart count from other scripts
|
// generate a custom event to update the cart count from other scripts
|
||||||
document.addEventListener("update-cart", updateCartCount);
|
document.addEventListener("update-cart", updateCartCount);
|
||||||
|
|||||||
@ -24,6 +24,7 @@ $(() => {
|
|||||||
orderCellsTop: true,
|
orderCellsTop: true,
|
||||||
pageLength: 50,
|
pageLength: 50,
|
||||||
lengthMenu: [10, 25, 50, 100, 500],
|
lengthMenu: [10, 25, 50, 100, 500],
|
||||||
|
order: [[5, 'desc']], // Ordena por fecha por defecto
|
||||||
language: { url: '/assets/libs/datatables/i18n/' + language + '.json' },
|
language: { url: '/assets/libs/datatables/i18n/' + language + '.json' },
|
||||||
responsive: true,
|
responsive: true,
|
||||||
dom: 'lBrtip',
|
dom: 'lBrtip',
|
||||||
@ -139,6 +140,7 @@ $(() => {
|
|||||||
orderCellsTop: true,
|
orderCellsTop: true,
|
||||||
pageLength: 50,
|
pageLength: 50,
|
||||||
lengthMenu: [10, 25, 50, 100, 500],
|
lengthMenu: [10, 25, 50, 100, 500],
|
||||||
|
order: [[5, 'desc']],
|
||||||
language: { url: '/assets/libs/datatables/i18n/' + language + '.json' },
|
language: { url: '/assets/libs/datatables/i18n/' + language + '.json' },
|
||||||
responsive: true,
|
responsive: true,
|
||||||
dom: 'lBrtip',
|
dom: 'lBrtip',
|
||||||
@ -161,7 +163,7 @@ $(() => {
|
|||||||
url: '/pagos/datatable/transferencias',
|
url: '/pagos/datatable/transferencias',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
},
|
},
|
||||||
order: [[7, 'desc']], // Ordena por fecha por defecto
|
order: [[6, 'desc']], // Ordena por fecha por defecto
|
||||||
columns: [
|
columns: [
|
||||||
{ data: 'client', name: 'client', orderable: true },
|
{ data: 'client', name: 'client', orderable: true },
|
||||||
{ data: 'transfer_id', name: 'transfer_id', orderable: true },
|
{ data: 'transfer_id', name: 'transfer_id', orderable: true },
|
||||||
|
|||||||
25
src/test/java/com/imprimelibros/erp/cart/envioCarroTest.java
Normal file
25
src/test/java/com/imprimelibros/erp/cart/envioCarroTest.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package com.imprimelibros.erp.cart;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
public class envioCarroTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
CartService cartService;
|
||||||
|
|
||||||
|
private final Long carritoId = 64L;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void addPedido(){
|
||||||
|
|
||||||
|
Locale locale = Locale.forLanguageTag("es-ES");
|
||||||
|
cartService.crearPedido(carritoId, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user