arreglados problemas varios

This commit is contained in:
2025-11-01 12:07:28 +01:00
parent a01d74aeb2
commit 6afa78df68
20 changed files with 146 additions and 81 deletions

View File

@ -3,7 +3,7 @@ package com.imprimelibros.erp.cart;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.Optional; import java.util.Optional;
public interface CartRepository extends JpaRepository<Cart, Long> { public interface CartRepository extends JpaRepository<Cart, Long> {

View File

@ -14,6 +14,7 @@ import java.util.Objects;
import com.imprimelibros.erp.presupuesto.classes.PresupuestoFormatter; import com.imprimelibros.erp.presupuesto.classes.PresupuestoFormatter;
import com.imprimelibros.erp.presupuesto.dto.Presupuesto; import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
import com.imprimelibros.erp.cart.dto.CartDireccionRepository;
import com.imprimelibros.erp.cart.dto.DireccionCardDTO; 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;
@ -27,6 +28,7 @@ import com.imprimelibros.erp.presupuesto.PresupuestoRepository;
public class CartService { public class CartService {
private final CartRepository cartRepo; private final CartRepository cartRepo;
private final CartDireccionRepository cartDireccionRepo;
private final CartItemRepository itemRepo; private final CartItemRepository itemRepo;
private final MessageSource messageSource; private final MessageSource messageSource;
private final PresupuestoRepository presupuestoRepo; private final PresupuestoRepository presupuestoRepo;
@ -36,11 +38,13 @@ public class CartService {
private final PedidoService pedidoService; private final PedidoService pedidoService;
public CartService(CartRepository cartRepo, CartItemRepository itemRepo, public CartService(CartRepository cartRepo, CartItemRepository itemRepo,
MessageSource messageSource, PresupuestoFormatter presupuestoFormatter, CartDireccionRepository cartDireccionRepo, MessageSource messageSource,
PresupuestoRepository presupuestoRepo, Utils utils, DireccionService direccionService, PresupuestoFormatter presupuestoFormatter, PresupuestoRepository presupuestoRepo,
skApiClient skApiClient, PedidoService pedidoService) { Utils utils, DireccionService direccionService, skApiClient skApiClient,
PedidoService pedidoService) {
this.cartRepo = cartRepo; this.cartRepo = cartRepo;
this.itemRepo = itemRepo; this.itemRepo = itemRepo;
this.cartDireccionRepo = cartDireccionRepo;
this.messageSource = messageSource; this.messageSource = messageSource;
this.presupuestoRepo = presupuestoRepo; this.presupuestoRepo = presupuestoRepo;
this.utils = utils; this.utils = utils;
@ -379,6 +383,16 @@ public class CartService {
} }
} }
// delete cart directions by direccion id in ACTIVE carts
@Transactional
public void deleteCartDireccionesByDireccionId(Long direccionId) {
/*List<CartDireccion> cartDirecciones = cartDireccionRepo.findByDireccion_IdAndCart_Status(direccionId, Cart.Status.ACTIVE);
for (CartDireccion cd : cartDirecciones) {
cartDireccionRepo.deleteById(cd.getId());
}*/
cartDireccionRepo.deleteByDireccionIdAndCartStatus(direccionId, Cart.Status.ACTIVE);
}
/*************************************** /***************************************
* MÉTODOS PRIVADOS * MÉTODOS PRIVADOS
***************************************/ ***************************************/

View File

@ -1,7 +1,13 @@
package com.imprimelibros.erp.cart.dto; package com.imprimelibros.erp.cart.dto;
import com.imprimelibros.erp.cart.Cart;
import com.imprimelibros.erp.cart.CartDireccion; import com.imprimelibros.erp.cart.CartDireccion;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
@ -12,4 +18,14 @@ public interface CartDireccionRepository extends JpaRepository<CartDireccion, Lo
// Lectura por cart_id (útil para componer respuestas) // Lectura por cart_id (útil para componer respuestas)
List<CartDireccion> findByCartId(Long cartId); List<CartDireccion> findByCartId(Long cartId);
@Modifying
@Transactional
@Query("""
delete from CartDireccion cd
where cd.direccion.id = :direccionId
and cd.cart.status = :status
""")
int deleteByDireccionIdAndCartStatus(@Param("direccionId") Long direccionId,
@Param("status") Cart.Status status);
} }

View File

@ -25,6 +25,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.imprimelibros.erp.cart.CartService;
import com.imprimelibros.erp.datatables.DataTable; import com.imprimelibros.erp.datatables.DataTable;
import com.imprimelibros.erp.datatables.DataTablesParser; import com.imprimelibros.erp.datatables.DataTablesParser;
import com.imprimelibros.erp.datatables.DataTablesRequest; import com.imprimelibros.erp.datatables.DataTablesRequest;
@ -51,16 +52,18 @@ public class DireccionController {
protected final MessageSource messageSource; protected final MessageSource messageSource;
protected final UserDao userRepo; protected final UserDao userRepo;
protected final TranslationService translationService; protected final TranslationService translationService;
protected final CartService cartService;
public DireccionController(DireccionRepository repo, PaisesService paisesService, public DireccionController(DireccionRepository repo, PaisesService paisesService,
MessageSource messageSource, UserDao userRepo, TranslationService translationService, MessageSource messageSource, UserDao userRepo, TranslationService translationService,
DireccionService direccionService) { DireccionService direccionService, CartService cartService) {
this.repo = repo; this.repo = repo;
this.paisesService = paisesService; this.paisesService = paisesService;
this.messageSource = messageSource; this.messageSource = messageSource;
this.userRepo = userRepo; this.userRepo = userRepo;
this.translationService = translationService; this.translationService = translationService;
this.direccionService = direccionService; this.direccionService = direccionService;
this.cartService = cartService;
} }
@GetMapping() @GetMapping()
@ -452,6 +455,7 @@ public class DireccionController {
} }
try { try {
direccion.setDeleted(true); direccion.setDeleted(true);
direccion.setDeletedAt(Instant.now()); direccion.setDeletedAt(Instant.now());
@ -462,6 +466,9 @@ public class DireccionController {
} }
repo.saveAndFlush(direccion); repo.saveAndFlush(direccion);
// eliminar referencias en carritos activos
cartService.deleteCartDireccionesByDireccionId(direccion.getId());
return ResponseEntity.ok(Map.of("message", return ResponseEntity.ok(Map.of("message",
messageSource.getMessage("direcciones.exito.eliminado", null, locale))); messageSource.getMessage("direcciones.exito.eliminado", null, locale)));

View File

@ -1,7 +1,6 @@
package com.imprimelibros.erp.presupuesto; package com.imprimelibros.erp.presupuesto;
import com.imprimelibros.erp.common.Utils; import com.imprimelibros.erp.common.Utils;
import com.imprimelibros.erp.configuracion.margenes_presupuestos.MargenPresupuesto;
import com.imprimelibros.erp.datatables.*; import com.imprimelibros.erp.datatables.*;
import com.imprimelibros.erp.presupuesto.dto.Presupuesto; import com.imprimelibros.erp.presupuesto.dto.Presupuesto;

View File

@ -2,8 +2,6 @@ package com.imprimelibros.erp.users;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import java.util.Map;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;

View File

@ -3,20 +3,11 @@ package com.imprimelibros.erp.users;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
import java.text.Collator;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.imprimelibros.erp.direcciones.Direccion;
@Service @Service
public class UserServiceImpl implements UserService { public class UserServiceImpl implements UserService {

View File

@ -0,0 +1,25 @@
# Profile desarrollo
#
# Logging
#
logging.level.org.springframework.security=ERROR
logging.level.root=ERROR
logging.level.org.springframework=ERROR
# Debug JPA / Hibernate
#logging.level.org.hibernate.SQL=DEBUG
#logging.level.org.hibernate.orm.jdbc.bind=TRACE
#spring.jpa.properties.hibernate.format_sql=true
# Datos de la API de Safekat
safekat.api.url=http://localhost:8000/
safekat.api.email=imnavajas@coit.es
safekat.api.password=Safekat2024
# Configuración Redsys
redsys.environment=test
redsys.urls.ok=http://localhost:8080/pagos/redsys/ok
redsys.urls.ko=http://localhost:8080/pagos/redsys/ko
redsys.urls.notify=http://localhost:8080/pagos/redsys/notify

View File

@ -0,0 +1,25 @@
# Profile test
#
# Logging
#
logging.level.org.springframework.security=ERROR
logging.level.root=ERROR
logging.level.org.springframework=ERROR
# Debug JPA / Hibernate
#logging.level.org.hibernate.SQL=DEBUG
#logging.level.org.hibernate.orm.jdbc.bind=TRACE
#spring.jpa.properties.hibernate.format_sql=true
# Datos de la API de Safekat
safekat.api.url=https://erp-dev.safekat.es/
safekat.api.email=imnavajas@coit.es
safekat.api.password=Safekat2024
# Configuración Redsys
redsys.environment=test
redsys.urls.ok=https://imprimelibros.jjimenez.eu/pagos/redsys/ok
redsys.urls.ko=https://imprimelibros.jjimenez.eu/pagos/redsys/ko
redsys.urls.notify=https://imprimelibros.jjimenez.eu/pagos/redsys/notify

View File

@ -1,45 +1,32 @@
spring.application.name=erp spring.application.name=erp
# Active profile
spring.profiles.active=dev
#spring.profiles.active=test
#spring.profiles.active=prod
server.forward-headers-strategy=framework server.forward-headers-strategy=framework
server.servlet.session.cookie.secure=true server.servlet.session.cookie.secure=true
#
# Logging
#
logging.level.org.springframework.security=ERROR
logging.level.root=ERROR
logging.level.org.springframework=ERROR
# #
# Database Configuration # Database Configuration
# #
#spring.datasource.url=jdbc:mysql://localhost:3309/imprimelibros
spring.datasource.url=jdbc:mysql://127.0.0.1:3309/imprimelibros?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Europe/Madrid&characterEncoding=utf8 spring.datasource.url=jdbc:mysql://127.0.0.1:3309/imprimelibros?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Europe/Madrid&characterEncoding=utf8
spring.datasource.username=imprimelibros_user spring.datasource.username=imprimelibros_user
spring.datasource.password=om91irrDctd spring.datasource.password=om91irrDctd
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=false spring.jpa.show-sql=false
# Hibernate Timezone
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
# # Mensajes de error mas cortos
# Safekat API Configuration # Oculta el stack trace en los errores del servidor
# server.error.include-stacktrace=never
safekat.api.url=http://localhost:8000/ # No mostrar el mensaje completo de excepción en la respuesta
#safekat.api.url=https://erp-dev.safekat.es/ server.error.include-message=always
safekat.api.email=imnavajas@coit.es
safekat.api.password=Safekat2024
#
# Debug JPA / Hibernate
#
#logging.level.org.hibernate.SQL=DEBUG
#logging.level.org.hibernate.orm.jdbc.bind=TRACE
#spring.jpa.properties.hibernate.format_sql=true
# #
# Resource chain # Resource chain
@ -57,11 +44,15 @@ server.servlet.session.timeout=30m
security.rememberme.key=N`BY^YRVO:/\H$hsKxNq security.rememberme.key=N`BY^YRVO:/\H$hsKxNq
# #
# Enable HiddenHttpMethodFilter to support PUT and DELETE methods in forms # Enable HiddenHttpMethodFilter to support PUT and DELETE methods in forms
# #
spring.mvc.hiddenmethod.filter.enabled=true spring.mvc.hiddenmethod.filter.enabled=true
# #
# Email # Email
# #
@ -72,11 +63,15 @@ spring.mail.password=%j4Su*#ZcjRDYsa$
spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.enable=true
# #
# Remove JSESSIONID from URL # Remove JSESSIONID from URL
# #
server.servlet.session.persistent=false server.servlet.session.persistent=false
# #
# GeoIP # GeoIP
# #
@ -85,42 +80,31 @@ geoip.maxmind.enabled=true
geoip.http.enabled=true geoip.http.enabled=true
#
# Hibernate Timezone
#
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
# #
# PDF Templates # PDF Templates
# #
# PDF Templates #
imprimelibros.pdf.templates.PRESUPUESTO_presupuesto-a4=imprimelibros/pdf/presupuesto-a4 imprimelibros.pdf.templates.PRESUPUESTO_presupuesto-a4=imprimelibros/pdf/presupuesto-a4
imprimelibros.pdf.templates.FACTURA_factura-a4=imprimelibros/pdf/factura-a4 imprimelibros.pdf.templates.FACTURA_factura-a4=imprimelibros/pdf/factura-a4
#
# Liquibase # Liquibase
#
spring.liquibase.enabled=true spring.liquibase.enabled=true
spring.liquibase.change-log=classpath:db/changelog/master.yml spring.liquibase.change-log=classpath:db/changelog/master.yml
# Si quieres especificar el schema por defecto:
# spring.liquibase.default-schema=imprimelibros
# Si necesitas parámetros de conexión distintos a los de Spring Data (no suele hacer falta):
# spring.liquibase.url=jdbc:mysql://localhost:3306/imprimelibros
# spring.liquibase.user=tu_user
# spring.liquibase.password=tu_pass
# Redsys # Redsys
redsys.environment=test
redsys.merchant-code=124760810 redsys.merchant-code=124760810
redsys.terminal=1 redsys.terminal=1
redsys.currency=978 redsys.currency=978
redsys.transaction-type=0 redsys.transaction-type=0
redsys.secret-key=sq7HjrUOBfKmC576ILgskD5srU870gJ7 redsys.secret-key=sq7HjrUOBfKmC576ILgskD5srU870gJ7
redsys.urls.ok=http://localhost:8080/pagos/redsys/ok
redsys.urls.ko=http://localhost:8080/pagos/redsys/ko
redsys.urls.notify=http://localhost:8080/pagos/redsys/notify
# 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

View File

@ -11,10 +11,11 @@ cart.shipping.add=Añadir dirección
cart.shipping.add.title=Seleccione una dirección cart.shipping.add.title=Seleccione una dirección
cart.shipping.select-placeholder=Buscar en direcciones... cart.shipping.select-placeholder=Buscar en direcciones...
cart.shipping.new-address=Nueva dirección cart.shipping.new-address=Nueva dirección
cart.shipping.info=Todos los pedidos incluyen un envío gratuito a la Península y Baleares por línea de pedido. cart.shipping.info=Todos los pedidos incluyen un envío gratuito a la Península por línea de pedido.
cart.shipping.order=Envío del pedido cart.shipping.order=Envío del pedido
cart.shipping.samples=Envío de prueba cart.shipping.samples=Envío de prueba
cart.shipping.onlyOneShipment=Todo el pedido se envía a una única dirección. cart.shipping.onlyOneShipment=Todo el pedido se envía a la misma dirección.
cart.shipping.onlyOneShipment.info=Seleccione esta opción si desea que todo el pedido se envíe a la misma dirección o desmarque para seleccionar las direcciones para cada línea de la cesta.
cart.shipping.tirada=Tirada: cart.shipping.tirada=Tirada:
cart.shipping.unidades=unidades cart.shipping.unidades=unidades
cart.shipping.ud=ud. cart.shipping.ud=ud.

View File

@ -39,3 +39,12 @@ body {
float: none; /* por si acaso */ float: none; /* por si acaso */
margin: 0; margin: 0;
} }
.form-switch-presupuesto .form-check-input:checked {
border-color: #92b2a7;
background-color: #cbcecd;
}
.form-switch-custom.form-switch-presupuesto .form-check-input:checked::before {
color: #92b2a7;
}

View File

@ -423,14 +423,6 @@
color: inherit; color: inherit;
} }
.form-switch-presupuesto .form-check-input:checked {
border-color: #92b2a7;
background-color: #cbcecd;
}
.form-switch-custom.form-switch-presupuesto .form-check-input:checked::before {
color: #92b2a7;
}
/* ==== Paso al resumen ==== */ /* ==== Paso al resumen ==== */
/* ---- Ajustes rápidos ---- */ /* ---- Ajustes rápidos ---- */

View File

@ -30,6 +30,7 @@ $(() => {
} }
}).always(() => { }).always(() => {
hideLoader(); hideLoader();
checkAddressesForItems();
}); });
checkAddressesForItems(); checkAddressesForItems();
@ -79,7 +80,7 @@ $(() => {
if (item.find(".shipping-addresses-sample")) { if (item.find(".shipping-addresses-sample")) {
const container = item.find(".shipping-addresses-sample"); const container = item.find(".shipping-addresses-sample");
if (container.find('.direccion-card').toArray().length === 0) { if (container && container.length && container.find('.direccion-card').toArray().length === 0) {
errorFoundItem = true; errorFoundItem = true;
} }
} }

View File

@ -218,7 +218,7 @@ $(() => {
$('#direccionFormModalBody').html(html); $('#direccionFormModalBody').html(html);
const title = $('#direccionFormModalBody #direccionForm').data('add'); const title = $('#direccionFormModalBody #direccionForm').data('add');
$('#direccionFormModal .modal-title').text(title); $('#direccionFormModal .modal-title').text(title);
modal.removeClass('d-none'); modal.show();
}); });
} }

View File

@ -168,7 +168,7 @@
confirmButton: 'btn btn-secondary w-xs mt-2', confirmButton: 'btn btn-secondary w-xs mt-2',
}, },
}); });
$('#direccion-datatable').DataTable().ajax.reload(null, false); table.ajax.reload(null, false);
}, },
error: function (xhr) { error: function (xhr) {
// usa el mensaje del backend; fallback genérico por si no llega JSON // usa el mensaje del backend; fallback genérico por si no llega JSON

View File

@ -51,8 +51,8 @@ export default class PresupuestoWizard {
gramajeGuardas: 170, gramajeGuardas: 170,
guardasImpresas: 0, guardasImpresas: 0,
cabezada: 'WHI', cabezada: 'WHI',
papelCubiertaId: 3, papelCubiertaId: 2,
gramajeCubierta: 170, gramajeCubierta: 300,
acabado: 1, acabado: 1,
sobrecubierta: { sobrecubierta: {
activo: false, activo: false,

View File

@ -31,6 +31,9 @@
<span th:text="#{cart.shipping.onlyOneShipment}" class="me-2"></span> <span th:text="#{cart.shipping.onlyOneShipment}" class="me-2"></span>
</label> </label>
</div> </div>
<div class="mb-3 mt-1">
<span class="text-muted" th:text="#{cart.shipping.onlyOneShipment.info}"></span>
</div>
<button type="button" <button type="button"
th:class="${'btn btn-secondary' + (!cart.onlyOneShipment or #lists.size(mainDir ?: {}) > 0 ? ' d-none' : '')}" th:class="${'btn btn-secondary' + (!cart.onlyOneShipment or #lists.size(mainDir ?: {}) > 0 ? ' d-none' : '')}"
id="addOrderAddress" th:text="#{cart.shipping.add}">Añadir dirección</button> id="addOrderAddress" th:text="#{cart.shipping.add}">Añadir dirección</button>

View File

@ -131,7 +131,7 @@
</div> </div>
<div <div
th:class="'form-group direccionFacturacionItems' + (${direccion != null and direccion.direccionFacturacion} ? '' : ' d-none')"> th:class="'form-group direccionFacturacionItems' + (${dirForm != null and dirForm.direccionFacturacion} ? '' : ' d-none')">
<label for="razonSocial"> <label for="razonSocial">
<span th:text="#{direcciones.razon_social}">Razón Social</span> <span th:text="#{direcciones.razon_social}">Razón Social</span>
<span class="text-danger">*</span> <span class="text-danger">*</span>
@ -142,7 +142,7 @@
</div> </div>
<div <div
th:class="'row mt-2 direccionFacturacionItems' + (${direccion != null and direccion.direccionFacturacion} ? '' : ' d-none')"> th:class="'row mt-2 direccionFacturacionItems' + (${dirForm != null and dirForm.direccionFacturacion} ? '' : ' d-none')">
<div class="form-group col-lg-6 col-md-6 col-sm-12 ml-0"> <div class="form-group col-lg-6 col-md-6 col-sm-12 ml-0">
<label for="tipoIdentificacionFiscal"> <label for="tipoIdentificacionFiscal">
<span th:text="#{direcciones.tipo_identificacion_fiscal}">Tipo de identificación fiscal</span> <span th:text="#{direcciones.tipo_identificacion_fiscal}">Tipo de identificación fiscal</span>

View File

@ -27,10 +27,10 @@
<span id="units-text" class="mb-2 fw-semibold d-block text-muted text-uppercase" th:unless="${unidades == 1}" <span id="units-text" class="mb-2 fw-semibold d-block text-muted text-uppercase" th:unless="${unidades == 1}"
th:text="|${unidades} #{cart.shipping.uds}|"></span> th:text="|${unidades} #{cart.shipping.uds}|"></span>
</div> </div>
<div th:if="${isPalets != null and isPalets==1}"> <div th:if="${isPalets != null and (isPalets==1 or isPalets==true)}">
<i class="icon-shipment las la-pallet la-3x text-muted"></i> <i class="icon-shipment las la-pallet la-3x text-muted"></i>
</div> </div>
<div th:if="${isPalets == null or isPalets == 0}"> <div th:if="${isPalets == null or isPalets == 0 or isPalets == false}">
<i class="icon-shipment las la-box la-3x text-muted"></i> <i class="icon-shipment las la-box la-3x text-muted"></i>
</div> </div>
</div> </div>