From a7c8242936a92bd1600574943d808c22c7ee28fe Mon Sep 17 00:00:00 2001 From: Mireya Serrano Date: Sun, 24 May 2026 13:52:33 +0200 Subject: [PATCH] Multiples direcciones para clientes --- .../integration/dolibarr/DolibarrClient.java | 31 ++++++++ .../dolibarr/dto/DolibarrAddressDto.java | 19 +++++ .../prestashop/PrestashopClient.java | 23 ++++++ .../prestashop/dto/PrestashopAddressDto.java | 5 ++ .../sync_service/sync/OrderSyncService.java | 72 +++++++++++++++++-- 5 files changed, 145 insertions(+), 5 deletions(-) create mode 100644 sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/dolibarr/dto/DolibarrAddressDto.java 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 fc97a4b..446c1a6 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 @@ -8,6 +8,7 @@ import org.springframework.core.ParameterizedTypeReference; import org.springframework.stereotype.Component; import org.springframework.web.client.RestClient; +import java.util.ArrayList; import java.util.List; /** @@ -157,6 +158,36 @@ public class DolibarrClient { .body(DolibarrThirdpartyDto.class); } + public DolibarrAddressDto createThirdpartyAddress(Integer socid, DolibarrAddressDto dto) { + log.debug("Creating Dolibarr thirdparty address socid={}", socid); + Integer newId = restClient.post() + .uri("/thirdparties/{socid}/addresses", socid) + .body(dto) + .retrieve() + .body(Integer.class); + + return restClient.get() + .uri("/thirdparties/{socid}/addresses/{id}", socid, newId) + .retrieve() + .body(DolibarrAddressDto.class); + } + + public List getThirdpartyAddresses(Integer socid) { + try{ + List addresses = restClient.get() + .uri("/thirdparties/{socid}/addresses", socid) + .retrieve() + .body(new ParameterizedTypeReference>() {}); + return addresses != null ? addresses : List.of(); + }catch (DolibarrApiException e){ + if (e.getStatusCode().value() == 404) { + log.debug("No addresses found for thirdparty socid={}", socid); + return List.of(); + } + throw e; + } + } + // ── 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 new file mode 100644 index 0000000..77871c7 --- /dev/null +++ b/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/dolibarr/dto/DolibarrAddressDto.java @@ -0,0 +1,19 @@ +package com.teterialosjuanjos.tfg.sync_service.integration.dolibarr.dto; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public record DolibarrAddressDto( + Integer id, + @JsonProperty("socid") Integer socid, + String label, + String address, + String zip, + String city, + @JsonProperty("id_country") Integer idCountry, + String phone, + @JsonProperty("default_address") Integer defaultAddress +) {} diff --git a/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/prestashop/PrestashopClient.java b/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/prestashop/PrestashopClient.java index c2be447..dcdf258 100644 --- a/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/prestashop/PrestashopClient.java +++ b/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/prestashop/PrestashopClient.java @@ -257,6 +257,29 @@ public class PrestashopClient { } } + public List getCustomerAddresses(Integer id) { + try{ + PrestashopAddressDto.ListResponse response = restClient.get() + .uri(u -> u.path("/addresses") + .queryParam("ws_key", wsKey) + .queryParam("output_format", "JSON") + .queryParam("filter[id_customer]", id) + .build()) + .retrieve() + .body(PrestashopAddressDto.ListResponse.class); + return (response != null && response.addresses() != null) ? response.addresses() : List.of(); + } catch (PrestashopApiException e) { + if (e.getStatusCode() != null && e.getStatusCode().value() == 404) { + log.debug("PS addresses not found for customer id={}", id); + return List.of(); + } + throw e; + } catch (HttpMessageConversionException | RestClientException e) { + log.debug("PS returned unparseable body for addresses of customer id={}, treating as not found: {}", id, e.getMessage()); + return List.of(); + } + } + // ── XML builders ────────────────────────────────────────────────────── // PS WebService requires XML body for writes; output_format=JSON only affects the response. diff --git a/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/prestashop/dto/PrestashopAddressDto.java b/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/prestashop/dto/PrestashopAddressDto.java index 9b14307..5e48b9c 100644 --- a/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/prestashop/dto/PrestashopAddressDto.java +++ b/sync-service/src/main/java/com/teterialosjuanjos/tfg/sync_service/integration/prestashop/dto/PrestashopAddressDto.java @@ -3,6 +3,8 @@ package com.teterialosjuanjos.tfg.sync_service.integration.prestashop.dto; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; + @JsonIgnoreProperties(ignoreUnknown = true) public record PrestashopAddressDto ( Integer id, @@ -19,4 +21,7 @@ public record PrestashopAddressDto ( ){ @JsonIgnoreProperties(ignoreUnknown = true) public record SingleResponse(PrestashopAddressDto address){} + + @JsonIgnoreProperties(ignoreUnknown = true) + public record ListResponse(List addresses){} } 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 3d8a152..4937d26 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 @@ -2,6 +2,7 @@ package com.teterialosjuanjos.tfg.sync_service.sync; import com.teterialosjuanjos.tfg.sync_service.config.IntegrationProperties; import com.teterialosjuanjos.tfg.sync_service.integration.dolibarr.DolibarrClient; +import com.teterialosjuanjos.tfg.sync_service.integration.dolibarr.dto.DolibarrAddressDto; import com.teterialosjuanjos.tfg.sync_service.integration.dolibarr.dto.DolibarrInvoiceDto; import com.teterialosjuanjos.tfg.sync_service.integration.dolibarr.dto.DolibarrOrderDto; import com.teterialosjuanjos.tfg.sync_service.integration.dolibarr.dto.DolibarrThirdpartyDto; @@ -167,6 +168,7 @@ public class OrderSyncService { ? psCustomer.email() : "ps_customer_%s@noemail.local".formatted(psOrder.idCustomer()); + // Get or create thirdparty with default address from PrestaShop String address = null; String city = null; String zip = null; @@ -176,10 +178,7 @@ public class OrderSyncService { Integer addressId = Integer.parseInt(psCustomer.idDefaultAddress()); PrestashopAddressDto psAddress = prestashopClient.getAddress(addressId); if (psAddress != null) { - address = psAddress.address1(); - if (psAddress.address2() != null && !psAddress.address2().isBlank()) { - address = (address != null ? address + " " : "") + psAddress.address2(); - } + address = formatAddress(psAddress.address1(), psAddress.address2()); city = psAddress.city(); zip = psAddress.postcode(); } @@ -188,7 +187,70 @@ public class OrderSyncService { } } - return dolibarrClient.getOrCreateThirdparty(email, name, address, city, zip); + DolibarrThirdpartyDto thirdparty = dolibarrClient.getOrCreateThirdparty(email, name, address, city, zip); + + // Sync additional addresses if customer exists and is not a guest + if (!isGuest && psCustomer != null) { + syncCustomerAddresses(Integer.parseInt(psOrder.idCustomer()), thirdparty.id()); + } + + return thirdparty; + } + + private void syncCustomerAddresses(Integer psCustomerId, Integer dolibarrThirdpartyId) { + try { + List psAddresses = prestashopClient.getCustomerAddresses(psCustomerId); + if (psAddresses.isEmpty()) { + return; + } + + // Get the default address ID to skip it (avoid duplication) + PrestashopCustomerDto psCustomer = prestashopClient.getCustomer(psCustomerId); + String defaultAddressId = psCustomer != null ? psCustomer.idDefaultAddress() : null; + + for (PrestashopAddressDto psAddr : psAddresses) { + // Skip the default address (already synced to thirdparty main fields) + 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())); + + if (!alreadyExists) { + // Create new address in Dolibarr + DolibarrAddressDto newAddr = new DolibarrAddressDto( + null, + dolibarrThirdpartyId, + formatPersonName(psAddr.firstname(), psAddr.lastname()), + formatAddress(psAddr.address1(), psAddr.address2()), + psAddr.postcode(), + psAddr.city(), + null, // id_country + psAddr.phone(), + 0 // not default + ); + dolibarrClient.createThirdpartyAddress(dolibarrThirdpartyId, newAddr); + log.debug("Synced PS address {} to Dolibarr thirdparty {}", psAddr.id(), dolibarrThirdpartyId); + } + } + } catch (Exception e) { + log.warn("Failed to sync additional addresses for PS customer {}: {}", psCustomerId, e.getMessage()); + } + } + + private String formatAddress(String addr1, String addr2) { + if (addr1 == null || addr1.isBlank()) return null; + if (addr2 == null || addr2.isBlank()) return addr1; + return addr1 + " " + addr2; + } + + private String formatPersonName(String firstname, String lastname) { + String full = (firstname != null ? firstname : "") + " " + (lastname != null ? lastname : ""); + return full.trim(); } /**