diff --git a/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/dolibarr/DolibarrClient.java b/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/dolibarr/DolibarrClient.java index 446c1a6..eba3c55 100644 --- a/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/dolibarr/DolibarrClient.java +++ b/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/dolibarr/DolibarrClient.java @@ -161,13 +161,13 @@ public class DolibarrClient { public DolibarrAddressDto createThirdpartyAddress(Integer socid, DolibarrAddressDto dto) { log.debug("Creating Dolibarr thirdparty address socid={}", socid); Integer newId = restClient.post() - .uri("/thirdparties/{socid}/addresses", socid) + .uri("/socaddress") .body(dto) .retrieve() .body(Integer.class); return restClient.get() - .uri("/thirdparties/{socid}/addresses/{id}", socid, newId) + .uri("/socaddress/{id}", newId) .retrieve() .body(DolibarrAddressDto.class); } @@ -175,7 +175,9 @@ public class DolibarrClient { public List getThirdpartyAddresses(Integer socid) { try{ List addresses = restClient.get() - .uri("/thirdparties/{socid}/addresses", socid) + .uri(u -> u.path("/socaddress") + .queryParam("sqlfilters", "(s.fk_soc:=:'" + socid + "')") + .build()) .retrieve() .body(new ParameterizedTypeReference>() {}); return addresses != null ? addresses : List.of(); @@ -188,6 +190,30 @@ public class DolibarrClient { } } + /** * Updates an existing address in Dolibarr. */ + public DolibarrAddressDto updateThirdpartyAddress(Integer addressId, DolibarrAddressDto dto) { + log.debug("Updating Dolibarr address id={}", addressId); + restClient.put() + .uri("/socaddress/{id}", addressId) + .body(dto) + .retrieve() + .toBodilessEntity(); + + return restClient.get() + .uri("/socaddress/{id}", addressId) + .retrieve() + .body(DolibarrAddressDto.class); + } + + /** * Deletes an address from Dolibarr. */ + public void deleteThirdpartyAddress(Integer addressId) { + log.debug("Deleting Dolibarr address id={}", addressId); + restClient.delete() + .uri("/socaddress/{id}", addressId) + .retrieve() + .toBodilessEntity(); + } + // ── Orders ──────────────────────────────────────────────────────────── /** diff --git a/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/dolibarr/dto/DolibarrAddressDto.java b/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/dolibarr/dto/DolibarrAddressDto.java index 77871c7..ebba289 100644 --- a/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/dolibarr/dto/DolibarrAddressDto.java +++ b/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/dolibarr/dto/DolibarrAddressDto.java @@ -8,12 +8,12 @@ import com.fasterxml.jackson.annotation.JsonProperty; @JsonInclude(JsonInclude.Include.NON_NULL) public record DolibarrAddressDto( Integer id, - @JsonProperty("socid") Integer socid, + @JsonProperty("fk_soc") Integer fkSoc, String label, String address, String zip, String city, - @JsonProperty("id_country") Integer idCountry, + @JsonProperty("fk_country") Integer fkCountry, String phone, @JsonProperty("default_address") Integer defaultAddress ) {} diff --git a/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/sync/OrderSyncService.java b/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/sync/OrderSyncService.java index 4937d26..6c890b2 100644 --- a/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/sync/OrderSyncService.java +++ b/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/sync/OrderSyncService.java @@ -25,6 +25,8 @@ import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; /** * Pulls new PrestaShop orders and imports them into Dolibarr as sales orders and invoices. @@ -199,46 +201,81 @@ public class OrderSyncService { private void syncCustomerAddresses(Integer psCustomerId, Integer dolibarrThirdpartyId) { try { + // 1. Obtener direcciones de PrestaShop List psAddresses = prestashopClient.getCustomerAddresses(psCustomerId); - if (psAddresses.isEmpty()) { - return; - } - // Get the default address ID to skip it (avoid duplication) + // 2. Obtener direcciones existentes en Dolibarr + List dolibarrAddresses = dolibarrClient.getThirdpartyAddresses(dolibarrThirdpartyId); + PrestashopCustomerDto psCustomer = prestashopClient.getCustomer(psCustomerId); String defaultAddressId = psCustomer != null ? psCustomer.idDefaultAddress() : null; + // 3. Procesar cada dirección de PrestaShop for (PrestashopAddressDto psAddr : psAddresses) { - // Skip the default address (already synced to thirdparty main fields) + // Ignorar la dirección por defecto (ya está en thirdparty.address/city/zip) if (psAddr.id() != null && psAddr.id().toString().equals(defaultAddressId)) { continue; } - // Check if address already exists in Dolibarr - List existingAddresses = dolibarrClient.getThirdpartyAddresses(dolibarrThirdpartyId); - boolean alreadyExists = existingAddresses.stream() - .anyMatch(a -> a.address() != null && a.address().equals(formatAddress(psAddr.address1(), psAddr.address2())) - && a.city() != null && a.city().equals(psAddr.city())); + String formattedAddress = formatAddress(psAddr.address1(), psAddr.address2()); + String formattedCity = psAddr.city(); - if (!alreadyExists) { - // Create new address in Dolibarr + // Buscar si existe una dirección con los mismos datos en Dolibarr + DolibarrAddressDto existingAddr = dolibarrAddresses.stream() + .filter(a -> a.address() != null && a.address().equals(formattedAddress) + && a.city() != null && a.city().equals(formattedCity)) + .findFirst() + .orElse(null); + + if (existingAddr != null) { + // ACTUALIZAR: La dirección existe pero podría tener cambios en zip, phone, etc. + DolibarrAddressDto updatedAddr = new DolibarrAddressDto( + existingAddr.id(), + dolibarrThirdpartyId, + formatPersonName(psAddr.firstname(), psAddr.lastname()), + formattedAddress, + psAddr.postcode(), + formattedCity, + null, + psAddr.phone(), + 0 + ); + dolibarrClient.updateThirdpartyAddress(existingAddr.id(), updatedAddr); + log.debug("Updated PS address {} in Dolibarr", psAddr.id()); + } else { + // CREAR: Dirección nueva en PrestaShop DolibarrAddressDto newAddr = new DolibarrAddressDto( null, dolibarrThirdpartyId, formatPersonName(psAddr.firstname(), psAddr.lastname()), - formatAddress(psAddr.address1(), psAddr.address2()), + formattedAddress, psAddr.postcode(), - psAddr.city(), - null, // id_country + formattedCity, + null, psAddr.phone(), - 0 // not default + 0 ); dolibarrClient.createThirdpartyAddress(dolibarrThirdpartyId, newAddr); - log.debug("Synced PS address {} to Dolibarr thirdparty {}", psAddr.id(), dolibarrThirdpartyId); + log.debug("Created PS address {} in Dolibarr", psAddr.id()); } } + + // 4. ELIMINAR direcciones que ya no existen en PrestaShop + Set psAddressStrings = psAddresses.stream() + .filter(a -> !(a.id() != null && a.id().toString().equals(defaultAddressId))) + .map(a -> formatAddress(a.address1(), a.address2()) + "|" + a.city()) + .collect(Collectors.toSet()); + + for (DolibarrAddressDto dolibarrAddr : dolibarrAddresses) { + String dolibarrAddressStr = dolibarrAddr.address() + "|" + dolibarrAddr.city(); + if (!psAddressStrings.contains(dolibarrAddressStr)) { + dolibarrClient.deleteThirdpartyAddress(dolibarrAddr.id()); + log.debug("Deleted orphaned address {} from Dolibarr", dolibarrAddr.id()); + } + } + } catch (Exception e) { - log.warn("Failed to sync additional addresses for PS customer {}: {}", psCustomerId, e.getMessage()); + log.warn("Failed to sync addresses for PS customer {}: {}", psCustomerId, e.getMessage()); } }