mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-13 00:48:49 +00:00
arreglados varios temas además del DL (redsys, etc)
This commit is contained in:
@ -445,7 +445,6 @@ public class CartService {
|
||||
cartDireccionRepo.deleteByDireccionIdAndCartStatus(direccionId, Cart.Status.ACTIVE);
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public Long crearPedido(Long cartId, Locale locale) {
|
||||
|
||||
@ -540,11 +539,23 @@ public class CartService {
|
||||
if (cart.getOnlyOneShipment()) {
|
||||
List<CartDireccion> direcciones = cart.getDirecciones().stream().limit(1).toList();
|
||||
if (!direcciones.isEmpty()) {
|
||||
direccionesPresupuesto.add(direcciones.get(0).toSkMap(
|
||||
presupuesto.getSelectedTirada(),
|
||||
presupuesto.getPeso(),
|
||||
direcciones.get(0).getIsPalets(),
|
||||
false));
|
||||
if (presupuesto.getServiciosJson() != null
|
||||
&& presupuesto.getServiciosJson().contains("deposito-legal")) {
|
||||
direccionesPresupuesto.add(direcciones.get(0).toSkMap(
|
||||
presupuesto.getSelectedTirada()-4,
|
||||
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(
|
||||
@ -553,10 +564,7 @@ public class CartService {
|
||||
false,
|
||||
true));
|
||||
}
|
||||
if (presupuesto.getServiciosJson() != null
|
||||
&& presupuesto.getServiciosJson().contains("deposito-legal")) {
|
||||
direccionesPresupuesto.add(direcciones.get(0).toSkMapDepositoLegal());
|
||||
}
|
||||
|
||||
Map<String, Object> direccionesRet = new HashMap<>();
|
||||
direccionesRet.put("direcciones", direccionesPresupuesto);
|
||||
if (!direccionesPrueba.isEmpty())
|
||||
|
||||
@ -2,8 +2,6 @@ package com.imprimelibros.erp.direcciones;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.annotations.SQLDelete;
|
||||
import org.hibernate.annotations.SQLRestriction;
|
||||
|
||||
@ -32,7 +32,6 @@ import com.imprimelibros.erp.users.UserDao;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/pagos")
|
||||
|
||||
@ -273,6 +273,14 @@ public class PaymentService {
|
||||
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();
|
||||
tx.setPayment(p);
|
||||
tx.setType(PaymentTransactionType.REFUND);
|
||||
|
||||
@ -6,9 +6,6 @@ import java.time.LocalDateTime;
|
||||
@Entity
|
||||
@Table(
|
||||
name = "payment_transactions",
|
||||
uniqueConstraints = {
|
||||
@UniqueConstraint(name = "uq_tx_gateway_txid", columnNames = {"gateway_transaction_id"})
|
||||
},
|
||||
indexes = {
|
||||
@Index(name = "idx_tx_pay", columnList = "payment_id"),
|
||||
@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.JpaSpecificationExecutor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
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> findFirstByPaymentIdAndTypeAndStatusOrderByIdDesc(
|
||||
Long paymentId,
|
||||
|
||||
@ -9,7 +9,6 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.imprimelibros.erp.presupuesto.PresupuestoRepository;
|
||||
import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
|
||||
import com.imprimelibros.erp.presupuesto.service.PresupuestoService;
|
||||
|
||||
@Service
|
||||
public class PedidoService {
|
||||
|
||||
@ -189,9 +189,9 @@ public class RedsysController {
|
||||
try {
|
||||
String idem = "refund-" + paymentId + "-" + amountCents + "-" + UUID.randomUUID();
|
||||
paymentService.refundViaRedsys(paymentId, amountCents, idem);
|
||||
return ResponseEntity.ok("{success:true}");
|
||||
return ResponseEntity.ok("{\"success\":true}");
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.badRequest().body("{success:false, error: '" + e.getMessage() + "'}");
|
||||
return ResponseEntity.badRequest().body("{\"success\":false, \"error\": \"" + e.getMessage() + "\"}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -321,11 +321,33 @@ public class RedsysService {
|
||||
Map<String, Object> decoded = decodeMerchantParametersToMap(dsMerchantParametersResp);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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:
|
||||
file: db/changelog/changesets/0010-drop-unique-tx-gateway.yml
|
||||
- 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
|
||||
@ -24,6 +24,7 @@ $(() => {
|
||||
orderCellsTop: true,
|
||||
pageLength: 50,
|
||||
lengthMenu: [10, 25, 50, 100, 500],
|
||||
order: [[5, 'desc']], // Ordena por fecha por defecto
|
||||
language: { url: '/assets/libs/datatables/i18n/' + language + '.json' },
|
||||
responsive: true,
|
||||
dom: 'lBrtip',
|
||||
@ -139,6 +140,7 @@ $(() => {
|
||||
orderCellsTop: true,
|
||||
pageLength: 50,
|
||||
lengthMenu: [10, 25, 50, 100, 500],
|
||||
order: [[5, 'desc']],
|
||||
language: { url: '/assets/libs/datatables/i18n/' + language + '.json' },
|
||||
responsive: true,
|
||||
dom: 'lBrtip',
|
||||
@ -161,7 +163,7 @@ $(() => {
|
||||
url: '/pagos/datatable/transferencias',
|
||||
method: 'GET',
|
||||
},
|
||||
order: [[7, 'desc']], // Ordena por fecha por defecto
|
||||
order: [[6, 'desc']], // Ordena por fecha por defecto
|
||||
columns: [
|
||||
{ data: 'client', name: 'client', orderable: true },
|
||||
{ data: 'transfer_id', name: 'transfer_id', orderable: true },
|
||||
|
||||
Reference in New Issue
Block a user