mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-13 00:48:49 +00:00
Merge branch 'feat/pago_success' into 'main'
Feat/pago success See merge request jjimenez/erp-imprimelibros!23
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@ -31,3 +31,6 @@ build/
|
|||||||
|
|
||||||
### VS Code ###
|
### VS Code ###
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
|
### Logs ###
|
||||||
|
erp-*.log
|
||||||
|
|||||||
@ -31,6 +31,8 @@ services:
|
|||||||
SPRING_DATASOURCE_PASSWORD: om91irrDctd
|
SPRING_DATASOURCE_PASSWORD: om91irrDctd
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "8080:8080"
|
||||||
|
volumes:
|
||||||
|
- ./logs:/var/log/imprimelibros
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
- imprimelibros-network
|
- imprimelibros-network
|
||||||
|
|||||||
2799
logs/erp.log
Normal file
2799
logs/erp.log
Normal file
File diff suppressed because it is too large
Load Diff
@ -445,6 +445,7 @@ 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) {
|
||||||
|
|
||||||
@ -456,11 +457,15 @@ public class CartService {
|
|||||||
|
|
||||||
for (Integer i = 0; i < items.size(); i++) {
|
for (Integer i = 0; i < items.size(); i++) {
|
||||||
CartItem item = items.get(i);
|
CartItem item = items.get(i);
|
||||||
Presupuesto p = item.getPresupuesto();
|
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);
|
Map<String, Object> data_to_send = presupuestoService.toSkApiRequest(p, true);
|
||||||
data_to_send.put("createPedido", 0);
|
data_to_send.put("createPedido", 0);
|
||||||
if (items.size() > 1) {
|
|
||||||
// Recuperar el mapa anidado datosCabecera
|
// Recuperar el mapa anidado datosCabecera
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Map<String, Object> datosCabecera = (Map<String, Object>) data_to_send.get("datosCabecera");
|
Map<String, Object> datosCabecera = (Map<String, Object>) data_to_send.get("datosCabecera");
|
||||||
@ -470,7 +475,7 @@ public class CartService {
|
|||||||
"titulo",
|
"titulo",
|
||||||
"[" + (i + 1) + "/" + items.size() + "] " + (tituloOriginal != null ? tituloOriginal : ""));
|
"[" + (i + 1) + "/" + items.size() + "] " + (tituloOriginal != null ? tituloOriginal : ""));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Map<String, Object> direcciones_presupuesto = this.getDireccionesPresupuesto(cart, p);
|
Map<String, Object> direcciones_presupuesto = this.getDireccionesPresupuesto(cart, p);
|
||||||
data_to_send.put("direcciones", direcciones_presupuesto.get("direcciones"));
|
data_to_send.put("direcciones", direcciones_presupuesto.get("direcciones"));
|
||||||
data_to_send.put("direccionesFP1", direcciones_presupuesto.get("direccionesFP1"));
|
data_to_send.put("direccionesFP1", direcciones_presupuesto.get("direccionesFP1"));
|
||||||
@ -530,11 +535,8 @@ public class CartService {
|
|||||||
|
|
||||||
List<Map<String, Object>> direccionesPresupuesto = new ArrayList<>();
|
List<Map<String, Object>> direccionesPresupuesto = new ArrayList<>();
|
||||||
List<Map<String, Object>> direccionesPrueba = new ArrayList<>();
|
List<Map<String, Object>> direccionesPrueba = new ArrayList<>();
|
||||||
List<CartDireccion> direcciones = cart.getDirecciones().stream()
|
|
||||||
.filter(d -> d.getPresupuesto() != null && d.getPresupuesto().getId().equals(presupuesto.getId()))
|
|
||||||
.toList();
|
|
||||||
if (cart.getOnlyOneShipment()) {
|
if (cart.getOnlyOneShipment()) {
|
||||||
direcciones = direcciones.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(
|
direccionesPresupuesto.add(direcciones.get(0).toSkMap(
|
||||||
presupuesto.getSelectedTirada(),
|
presupuesto.getSelectedTirada(),
|
||||||
@ -555,11 +557,19 @@ public class CartService {
|
|||||||
}
|
}
|
||||||
Map<String, Object> direccionesRet = new HashMap<>();
|
Map<String, Object> direccionesRet = new HashMap<>();
|
||||||
direccionesRet.put("direcciones", direccionesPresupuesto);
|
direccionesRet.put("direcciones", direccionesPresupuesto);
|
||||||
|
if (!direccionesPrueba.isEmpty())
|
||||||
direccionesRet.put("direccionesFP1", direccionesPrueba.get(0));
|
direccionesRet.put("direccionesFP1", direccionesPrueba.get(0));
|
||||||
|
else {
|
||||||
|
direccionesRet.put("direccionesFP1", new ArrayList<>());
|
||||||
|
}
|
||||||
return direccionesRet;
|
return direccionesRet;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (CartDireccion cd : cart.getDirecciones()) {
|
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
|
// direccion de ejemplar de prueba
|
||||||
if (cd.getPresupuesto() == null || !cd.getPresupuesto().getId().equals(presupuesto.getId())) {
|
if (cd.getPresupuesto() == null || !cd.getPresupuesto().getId().equals(presupuesto.getId())) {
|
||||||
|
|||||||
@ -457,6 +457,7 @@ public class PaymentService {
|
|||||||
* - crea el pedido a partir del carrito
|
* - crea el pedido a partir del carrito
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@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);
|
||||||
|
|||||||
@ -315,16 +315,28 @@ public class PresupuestoService {
|
|||||||
|
|
||||||
Map<String, Object> body = new HashMap<>();
|
Map<String, Object> body = new HashMap<>();
|
||||||
body.put("tipo_impresion_id", this.getTipoImpresionId(presupuesto));
|
body.put("tipo_impresion_id", this.getTipoImpresionId(presupuesto));
|
||||||
if (toSave) {
|
Boolean hasDepositoLegal = false;
|
||||||
|
if (presupuesto.getServiciosJson() != null
|
||||||
|
&& presupuesto.getServiciosJson().contains("deposito-legal")) {
|
||||||
|
hasDepositoLegal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toSave && hasDepositoLegal) {
|
||||||
body.put("tirada", Arrays.stream(presupuesto.getTiradas())
|
body.put("tirada", Arrays.stream(presupuesto.getTiradas())
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.map(tirada -> tirada + 4)
|
.map(tirada -> tirada + 4)
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
|
if(presupuesto.getSelectedTirada() != null) {
|
||||||
|
presupuesto.setSelectedTirada(presupuesto.getSelectedTirada());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
body.put("tirada", Arrays.stream(presupuesto.getTiradas())
|
body.put("tirada", Arrays.stream(presupuesto.getTiradas())
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.put("selectedTirada",
|
||||||
|
presupuesto.getSelectedTirada() != null ? presupuesto.getSelectedTirada() : presupuesto.getTirada1());
|
||||||
body.put("tamanio", tamanio);
|
body.put("tamanio", tamanio);
|
||||||
body.put("tipo", presupuesto.getTipoEncuadernacion());
|
body.put("tipo", presupuesto.getTipoEncuadernacion());
|
||||||
body.put("clienteId", SK_CLIENTE_ID);
|
body.put("clienteId", SK_CLIENTE_ID);
|
||||||
@ -356,6 +368,7 @@ public class PresupuestoService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (toSave) {
|
if (toSave) {
|
||||||
|
Map<String, Object> servicios = new HashMap<>();
|
||||||
Map<String, Object> data = new HashMap<>();
|
Map<String, Object> data = new HashMap<>();
|
||||||
data.put("input_data", body);
|
data.put("input_data", body);
|
||||||
data.put("ferroDigital", 1);
|
data.put("ferroDigital", 1);
|
||||||
@ -365,11 +378,13 @@ public class PresupuestoService {
|
|||||||
if (presupuesto.getServiciosJson() != null
|
if (presupuesto.getServiciosJson() != null
|
||||||
&& presupuesto.getServiciosJson().indexOf("ejemplar-prueba") > 0) {
|
&& presupuesto.getServiciosJson().indexOf("ejemplar-prueba") > 0) {
|
||||||
data.put("prototipo", 1);
|
data.put("prototipo", 1);
|
||||||
|
servicios.put("prototipo", "1");
|
||||||
} else {
|
} else {
|
||||||
data.put("prototipo", 0);
|
data.put("prototipo", 0);
|
||||||
}
|
}
|
||||||
if (presupuesto.getServiciosJson() != null && presupuesto.getServiciosJson().indexOf("retractilado") > 0) {
|
if (presupuesto.getServiciosJson() != null && presupuesto.getServiciosJson().indexOf("retractilado") > 0) {
|
||||||
data.put("retractilado", 1);
|
data.put("retractilado", 1);
|
||||||
|
servicios.put("retractilado", "1");
|
||||||
} else {
|
} else {
|
||||||
data.put("retractilado", 0);
|
data.put("retractilado", 0);
|
||||||
}
|
}
|
||||||
@ -382,6 +397,7 @@ public class PresupuestoService {
|
|||||||
datosCabecera.put("coleccion", "");
|
datosCabecera.put("coleccion", "");
|
||||||
datosCabecera.put("referenciaCliente", presupuesto.getId());
|
datosCabecera.put("referenciaCliente", presupuesto.getId());
|
||||||
data.put("datosCabecera", datosCabecera);
|
data.put("datosCabecera", datosCabecera);
|
||||||
|
body.put("servicios", servicios);
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1099,10 +1115,14 @@ public class PresupuestoService {
|
|||||||
try {
|
try {
|
||||||
// retractilado: recalcular precio
|
// retractilado: recalcular precio
|
||||||
if (s.get("id").equals("retractilado")) {
|
if (s.get("id").equals("retractilado")) {
|
||||||
double precio_retractilado = obtenerPrecioRetractilado(cantidad) != null
|
|
||||||
? Double.parseDouble(obtenerPrecioRetractilado(cantidad))
|
String p = obtenerPrecioRetractilado(cantidad);
|
||||||
: 0.0;
|
if(p != null){
|
||||||
|
double precio_retractilado = Double.parseDouble(p);
|
||||||
s.put("price", precio_retractilado);
|
s.put("price", precio_retractilado);
|
||||||
|
} else {
|
||||||
|
s.put("price", 0.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// si tiene protitipo, guardamos el valor para el IVA al 4%
|
// si tiene protitipo, guardamos el valor para el IVA al 4%
|
||||||
else if (s.get("id").equals("ejemplar-prueba")) {
|
else if (s.get("id").equals("ejemplar-prueba")) {
|
||||||
@ -1120,6 +1140,7 @@ public class PresupuestoService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
if(presupuesto.getSelectedTirada() != null && presupuesto.getSelectedTirada().equals(tirada))
|
||||||
presupuesto.setServiciosJson(new ObjectMapper().writeValueAsString(servicios));
|
presupuesto.setServiciosJson(new ObjectMapper().writeValueAsString(servicios));
|
||||||
} catch (Exception ignore) {
|
} catch (Exception ignore) {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -71,7 +71,7 @@ public class RedsysController {
|
|||||||
|
|
||||||
String importeFormateado = Utils.formatCurrency(amountCents / 100.0, locale);
|
String importeFormateado = Utils.formatCurrency(amountCents / 100.0, locale);
|
||||||
ctx.setVariable("importe", importeFormateado);
|
ctx.setVariable("importe", importeFormateado);
|
||||||
ctx.setVariable("concepto", "TRANSF-" + p.getId());
|
ctx.setVariable("concepto", "TRANSF-" + p.getOrderId());
|
||||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||||
boolean isAuth = auth != null
|
boolean isAuth = auth != null
|
||||||
&& auth.isAuthenticated()
|
&& auth.isAuthenticated()
|
||||||
@ -119,11 +119,7 @@ public class RedsysController {
|
|||||||
// GET: cuando el usuario cae aquí sin parámetros, o Redsys redirige por GET
|
// GET: cuando el usuario cae aquí sin parámetros, o Redsys redirige por GET
|
||||||
@GetMapping("/ok")
|
@GetMapping("/ok")
|
||||||
public String okGet(RedirectAttributes redirectAttrs, Model model, Locale locale) {
|
public String okGet(RedirectAttributes redirectAttrs, Model model, Locale locale) {
|
||||||
String msg = messageSource.getMessage("checkout.success.payment", null,
|
return "imprimelibros/pagos/pago-ok";
|
||||||
"Pago realizado con éxito. Gracias por su compra.", locale);
|
|
||||||
model.addAttribute("successPago", msg);
|
|
||||||
redirectAttrs.addFlashAttribute("successPago", msg);
|
|
||||||
return "redirect:/cart";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// POST: si Redsys envía Ds_Signature y Ds_MerchantParameters (muchas
|
// POST: si Redsys envía Ds_Signature y Ds_MerchantParameters (muchas
|
||||||
|
|||||||
@ -3,16 +3,35 @@
|
|||||||
#
|
#
|
||||||
# Logging
|
# Logging
|
||||||
#
|
#
|
||||||
|
logging.level.root=INFO
|
||||||
logging.level.org.springframework.security=ERROR
|
logging.level.org.springframework.security=ERROR
|
||||||
logging.level.root=ERROR
|
|
||||||
logging.level.org.springframework=ERROR
|
logging.level.org.springframework=ERROR
|
||||||
|
logging.level.org.springframework.web=ERROR
|
||||||
|
logging.level.org.thymeleaf=ERROR
|
||||||
|
logging.level.org.apache.catalina.core=ERROR
|
||||||
# Debug JPA / Hibernate
|
# Debug JPA / Hibernate
|
||||||
#logging.level.org.hibernate.SQL=DEBUG
|
#logging.level.org.hibernate.SQL=DEBUG
|
||||||
#logging.level.org.hibernate.orm.jdbc.bind=TRACE
|
#logging.level.org.hibernate.orm.jdbc.bind=TRACE
|
||||||
#spring.jpa.properties.hibernate.format_sql=true
|
#spring.jpa.properties.hibernate.format_sql=true
|
||||||
|
|
||||||
|
server.error.include-message=always
|
||||||
|
server.error.include-stacktrace=on_param
|
||||||
|
server.error.include-binding-errors=on_param
|
||||||
|
|
||||||
|
|
||||||
|
# Archivo relativo a tu proyecto (asegúrate de que exista el directorio ./logs)
|
||||||
|
logging.file.name=logs/erp.log
|
||||||
|
|
||||||
|
# Rotación tiempo+tamaño (mismo patrón, pero en ./logs)
|
||||||
|
logging.logback.rollingpolicy.file-name-pattern=logs/erp-%d{yyyy-MM-dd}.%i.log
|
||||||
|
logging.logback.rollingpolicy.max-file-size=10MB
|
||||||
|
logging.logback.rollingpolicy.max-history=10
|
||||||
|
logging.logback.rollingpolicy.total-size-cap=1GB
|
||||||
|
|
||||||
|
# Formatos con timestamp
|
||||||
|
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n
|
||||||
|
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n
|
||||||
|
|
||||||
# Datos de la API de Safekat
|
# Datos de la API de Safekat
|
||||||
safekat.api.url=http://localhost:8000/
|
safekat.api.url=http://localhost:8000/
|
||||||
safekat.api.email=imnavajas@coit.es
|
safekat.api.email=imnavajas@coit.es
|
||||||
|
|||||||
@ -3,14 +3,34 @@
|
|||||||
#
|
#
|
||||||
# Logging
|
# Logging
|
||||||
#
|
#
|
||||||
logging.level.org.springframework.security=ERROR
|
|
||||||
|
# Niveles
|
||||||
logging.level.root=ERROR
|
logging.level.root=ERROR
|
||||||
logging.level.org.springframework=ERROR
|
logging.level.org.springframework=ERROR
|
||||||
# Debug JPA / Hibernate
|
logging.level.org.springframework.security=ERROR
|
||||||
#logging.level.org.hibernate.SQL=DEBUG
|
logging.level.org.springframework.web=ERROR
|
||||||
#logging.level.org.hibernate.orm.jdbc.bind=TRACE
|
logging.level.org.thymeleaf=ERROR
|
||||||
#spring.jpa.properties.hibernate.format_sql=true
|
logging.level.org.apache.catalina.core=ERROR
|
||||||
|
|
||||||
|
server.error.include-message=never
|
||||||
|
server.error.include-stacktrace=never
|
||||||
|
server.error.include-binding-errors=never
|
||||||
|
# Opcional: desactivar Whitelabel y servir tu propia página de error
|
||||||
|
server.error.whitelabel.enabled=false
|
||||||
|
|
||||||
|
|
||||||
|
# Archivo principal dentro del contenedor (monta /var/log/imprimelibros como volumen)
|
||||||
|
logging.file.name=/var/log/imprimelibros/erp.log
|
||||||
|
|
||||||
|
# Rotación tiempo+tamaño -> requiere %d y %i
|
||||||
|
logging.logback.rollingpolicy.file-name-pattern=/var/log/imprimelibros/erp-%d{yyyy-MM-dd}.%i.log
|
||||||
|
logging.logback.rollingpolicy.max-file-size=10MB
|
||||||
|
logging.logback.rollingpolicy.max-history=10
|
||||||
|
logging.logback.rollingpolicy.total-size-cap=1GB
|
||||||
|
|
||||||
|
# Formatos con timestamp
|
||||||
|
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n
|
||||||
|
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n
|
||||||
|
|
||||||
|
|
||||||
# Datos de la API de Safekat
|
# Datos de la API de Safekat
|
||||||
|
|||||||
@ -19,15 +19,6 @@ spring.jpa.show-sql=false
|
|||||||
# Hibernate Timezone
|
# Hibernate Timezone
|
||||||
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
|
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
|
||||||
|
|
||||||
|
|
||||||
# Mensajes de error mas cortos
|
|
||||||
# Oculta el stack trace en los errores del servidor
|
|
||||||
server.error.include-stacktrace=never
|
|
||||||
# No mostrar el mensaje completo de excepción en la respuesta
|
|
||||||
server.error.include-message=always
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Resource chain
|
# Resource chain
|
||||||
# Activa el resource chain y versionado por contenido
|
# Activa el resource chain y versionado por contenido
|
||||||
@ -106,5 +97,3 @@ redsys.currency=978
|
|||||||
redsys.transaction-type=0
|
redsys.transaction-type=0
|
||||||
redsys.secret-key=sq7HjrUOBfKmC576ILgskD5srU870gJ7
|
redsys.secret-key=sq7HjrUOBfKmC576ILgskD5srU870gJ7
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,28 @@
|
|||||||
|
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
|
||||||
|
|
||||||
@ -31,6 +31,9 @@ pagos.transferencia.finalizar.error.general=Error al finalizar la transferencia
|
|||||||
pagos.transferencia.ok.title=Pago por transferencia bancaria
|
pagos.transferencia.ok.title=Pago por transferencia bancaria
|
||||||
pagos.transferencia.ok.text=Ha realizado su pedido correctamente. Para completar el pago, realice una transferencia bancaria con los siguientes datos:<br>Titular de la cuenta: Impresión Imprime Libros SL<br>IBAN: ES00 1234 5678 9012 3456 7890<br>Importe: {0}<br>Concepto: {1}<br>Le rogamos que nos envíe el justificante de la transferencia respondiendo al correo de confirmación de pedido que le acabamos de enviar.<br>Si no encuentra el mensaje, por favor revise la carpeta de correo no deseado y añada <a href="mailto:contacto@imprimelibros.com">contacto@imprimelibros.com</a>
|
pagos.transferencia.ok.text=Ha realizado su pedido correctamente. Para completar el pago, realice una transferencia bancaria con los siguientes datos:<br>Titular de la cuenta: Impresión Imprime Libros SL<br>IBAN: ES00 1234 5678 9012 3456 7890<br>Importe: {0}<br>Concepto: {1}<br>Le rogamos que nos envíe el justificante de la transferencia respondiendo al correo de confirmación de pedido que le acabamos de enviar.<br>Si no encuentra el mensaje, por favor revise la carpeta de correo no deseado y añada <a href="mailto:contacto@imprimelibros.com">contacto@imprimelibros.com</a>
|
||||||
|
|
||||||
|
pagos.tarjeta-bizum.ok.title=Pago realizado correctamente
|
||||||
|
pagos.tarjeta-bizum.ok.text=Gracias por confiar en nosotros.<br> Su pago se ha procesado correctamente. En breve recibirá un correo electrónico con los detalles de su pedido.
|
||||||
|
|
||||||
pagos.refund.title=Devolución
|
pagos.refund.title=Devolución
|
||||||
pagos.refund.text=Introduce la cantidad a devolver (en euros):
|
pagos.refund.text=Introduce la cantidad a devolver (en euros):
|
||||||
pagos.refund.success=Devolución solicitada con éxito. Si no se refleja inmediatamente, espere unos minutos y actualiza la página.
|
pagos.refund.success=Devolución solicitada con éxito. Si no se refleja inmediatamente, espere unos minutos y actualiza la página.
|
||||||
|
|||||||
@ -4,7 +4,8 @@ body {
|
|||||||
|
|
||||||
/* botón base */
|
/* botón base */
|
||||||
.btn-opcion-presupuesto {
|
.btn-opcion-presupuesto {
|
||||||
--vz-btn-color: #92b2a7; /* texto y borde */
|
--vz-btn-color: #92b2a7;
|
||||||
|
/* texto y borde */
|
||||||
--vz-btn-border-color: #92b2a7;
|
--vz-btn-border-color: #92b2a7;
|
||||||
--vz-btn-hover-color: #fff;
|
--vz-btn-hover-color: #fff;
|
||||||
--vz-btn-hover-bg: #92b2a7;
|
--vz-btn-hover-bg: #92b2a7;
|
||||||
@ -18,12 +19,13 @@ body {
|
|||||||
--vz-btn-disabled-border-color: #92b2a7;
|
--vz-btn-disabled-border-color: #92b2a7;
|
||||||
--vz-gradient: none;
|
--vz-gradient: none;
|
||||||
|
|
||||||
background-color: rgba(146, 178, 167, 0.2); /* no seleccionado */
|
background-color: rgba(146, 178, 167, 0.2);
|
||||||
|
/* no seleccionado */
|
||||||
color: #92b2a7;
|
color: #92b2a7;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cuando el radio/checkbox está checked */
|
/* cuando el radio/checkbox está checked */
|
||||||
.btn-check:checked + .btn-opcion-presupuesto,
|
.btn-check:checked+.btn-opcion-presupuesto,
|
||||||
.btn-opcion-presupuesto.active {
|
.btn-opcion-presupuesto.active {
|
||||||
background-color: #92b2a7;
|
background-color: #92b2a7;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@ -32,18 +34,22 @@ body {
|
|||||||
|
|
||||||
/* Solo dentro del modal */
|
/* Solo dentro del modal */
|
||||||
.swal2-popup .form-switch-custom {
|
.swal2-popup .form-switch-custom {
|
||||||
font-size: 1rem; /* clave: fija el tamaño base del switch */
|
font-size: 1rem;
|
||||||
|
/* clave: fija el tamaño base del switch */
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.swal2-popup .form-switch-custom .form-check-input {
|
.swal2-popup .form-switch-custom .form-check-input {
|
||||||
float: none; /* por si acaso */
|
float: none;
|
||||||
|
/* por si acaso */
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.swal2-popup .form-switch-custom .form-check-input:checked{
|
.swal2-popup .form-switch-custom .form-check-input:checked {
|
||||||
border-color: #92b2a7;
|
border-color: #92b2a7;
|
||||||
background-color: #cbcecd;
|
background-color: #cbcecd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.swal2-popup .form-switch-custom .form-check-input:checked::before {
|
.swal2-popup .form-switch-custom .form-check-input:checked::before {
|
||||||
color: #92b2a7;
|
color: #92b2a7;
|
||||||
}
|
}
|
||||||
@ -64,6 +70,40 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fadeout {
|
@keyframes fadeout {
|
||||||
0%, 70% { opacity: 1; }
|
|
||||||
100% { opacity: 0; }
|
0%,
|
||||||
|
70% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-container {
|
||||||
|
width: 300px;
|
||||||
|
height: 20px;
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bar-custom {
|
||||||
|
height: 100%;
|
||||||
|
background-color: #92b2a7;
|
||||||
|
border-radius: 10px;
|
||||||
|
width: 0;
|
||||||
|
animation: fillProgress 5s ease-in-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fillProgress {
|
||||||
|
from {
|
||||||
|
width: 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@
|
|||||||
<th:block layout:fragment="content">
|
<th:block layout:fragment="content">
|
||||||
<div th:if="${#authorization.expression('isAuthenticated()')}">
|
<div th:if="${#authorization.expression('isAuthenticated()')}">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<!-- contenido para usuario logueado -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div th:unless="${#authorization.expression('isAuthenticated()')}">
|
<div th:unless="${#authorization.expression('isAuthenticated()')}">
|
||||||
@ -36,8 +36,10 @@
|
|||||||
<div th:unless="${#authorization.expression('isAuthenticated()')}">
|
<div th:unless="${#authorization.expression('isAuthenticated()')}">
|
||||||
<script th:src="@{/assets/js/pages/imprimelibros/presupuestador/imagen-selector.js}"></script>
|
<script th:src="@{/assets/js/pages/imprimelibros/presupuestador/imagen-selector.js}"></script>
|
||||||
<script type="module" th:src="@{/assets/js/pages/imprimelibros/presupuestador/wizard-home.js}"></script>
|
<script type="module" th:src="@{/assets/js/pages/imprimelibros/presupuestador/wizard-home.js}"></script>
|
||||||
<script type="module" th:src="@{/assets/js/pages/imprimelibros/presupuestador/presupuesto-maquetacion.js}"></script>
|
<script type="module"
|
||||||
<script type="module" th:src="@{/assets/js/pages/imprimelibros/presupuestador/presupuesto-marcapaginas.js}"></script>
|
th:src="@{/assets/js/pages/imprimelibros/presupuestador/presupuesto-maquetacion.js}"></script>
|
||||||
|
<script type="module"
|
||||||
|
th:src="@{/assets/js/pages/imprimelibros/presupuestador/presupuesto-marcapaginas.js}"></script>
|
||||||
</div>
|
</div>
|
||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
window.languageBundle = /*[[${languageBundle}]]*/ {};
|
window.languageBundle = /*[[${languageBundle}]]*/ {};
|
||||||
|
|||||||
@ -0,0 +1,76 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorate="~{imprimelibros/layout}">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<th:block layout:fragment="pagetitle" />
|
||||||
|
<th:block th:replace="~{imprimelibros/partials/head-css :: head-css}" />
|
||||||
|
<th:block layout:fragment="pagecss">
|
||||||
|
<link href="/assets/libs/datatables/dataTables.bootstrap5.min.css" rel="stylesheet" />
|
||||||
|
</th:block>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div th:replace="~{imprimelibros/partials/topbar :: topbar}" />
|
||||||
|
<div th:replace="~{imprimelibros/partials/sidebar :: sidebar}"
|
||||||
|
sec:authorize="isAuthenticated() and hasAnyRole('SUPERADMIN','ADMIN')">
|
||||||
|
|
||||||
|
<th:block layout:fragment="content">
|
||||||
|
<div th:if="${isAuth}">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
<nav aria-label="breadcrumb">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li class="breadcrumb-item"><a href="/"><i class="ri-home-5-fill"></i></a></li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<div class="row" id="card">
|
||||||
|
<div class="card">
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<h3 th:text="#{pagos.tarjeta-bizum.ok.title}"></h3>
|
||||||
|
<span th:utext="#{pagos.tarjeta-bizum.ok.text}"></span>
|
||||||
|
<div class="col-md-12 d-flex justify-content-center mt-4">
|
||||||
|
<div class="progress-container">
|
||||||
|
<div class="progress-bar-custom"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--end row-->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</th:block>
|
||||||
|
|
||||||
|
<th:block th:replace="~{theme/partials/vendor-scripts :: scripts}" />
|
||||||
|
<th:block layout:fragment="pagejs">
|
||||||
|
<script th:inline="javascript">
|
||||||
|
window.languageBundle = /*[[${languageBundle}]]*/ {};
|
||||||
|
// a los 5 segundos redirigimos a la página principal
|
||||||
|
setTimeout(function () {
|
||||||
|
window.location.href = '/';
|
||||||
|
}, 5000);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- JS de Buttons y dependencias -->
|
||||||
|
<div th:if="${appMode} == 'view'">
|
||||||
|
<script type="module" th:src="@{/assets/js/pages/imprimelibros/presupuestador/wizard-publicos.js}"></script>
|
||||||
|
</div>
|
||||||
|
<div th:if="${appMode} == 'edit'">
|
||||||
|
<script type="module" th:src="@{/assets/js/pages/imprimelibros/presupuestador/wizard-privado.js}"></script>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="module" th:src="@{/assets/js/pages/imprimelibros/presupuestos/resumen-view.js}"></script>
|
||||||
|
|
||||||
|
</th:block>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user