Multiples direcciones para clientes

This commit is contained in:
Mireya Serrano 2026-05-24 13:52:33 +02:00
parent e2b6966cef
commit a7c8242936
5 changed files with 145 additions and 5 deletions

View File

@ -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<DolibarrAddressDto> getThirdpartyAddresses(Integer socid) {
try{
List<DolibarrAddressDto> addresses = restClient.get()
.uri("/thirdparties/{socid}/addresses", socid)
.retrieve()
.body(new ParameterizedTypeReference<List<DolibarrAddressDto>>() {});
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 ────────────────────────────────────────────────────────────
/**

View File

@ -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
) {}

View File

@ -257,6 +257,29 @@ public class PrestashopClient {
}
}
public List<PrestashopAddressDto> 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.

View File

@ -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<PrestashopAddressDto> addresses){}
}

View File

@ -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<PrestashopAddressDto> 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<DolibarrAddressDto> 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();
}
/**