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 960acb8..e91997f 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 @@ -4,6 +4,7 @@ import com.teterialosjuanjos.tfg.sync_service.config.IntegrationProperties; import com.teterialosjuanjos.tfg.sync_service.integration.prestashop.dto.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import org.springframework.web.client.RestClient; @@ -84,6 +85,7 @@ public class PrestashopClient { /** * Creates a new product in PrestaShop. + * PS WebService requires XML request body even when {@code output_format=JSON} is set. * * @return the created product including its assigned {@code id} */ @@ -94,7 +96,8 @@ public class PrestashopClient { .queryParam("ws_key", wsKey) .queryParam("output_format", "JSON") .build()) - .body(new PrestashopProductDto.SingleResponse(dto)) + .contentType(MediaType.APPLICATION_XML) + .body(toProductXml(dto)) .retrieve() .body(PrestashopProductDto.SingleResponse.class); @@ -109,7 +112,8 @@ public class PrestashopClient { .queryParam("ws_key", wsKey) .queryParam("output_format", "JSON") .build(id)) - .body(new PrestashopProductDto.SingleResponse(dto)) + .contentType(MediaType.APPLICATION_XML) + .body(toProductXml(dto)) .retrieve() .toBodilessEntity(); } @@ -147,7 +151,8 @@ public class PrestashopClient { .queryParam("ws_key", wsKey) .queryParam("output_format", "JSON") .build(id)) - .body(new PrestashopStockAvailableDto.SingleResponse(dto)) + .contentType(MediaType.APPLICATION_XML) + .body(toStockAvailableXml(dto)) .retrieve() .toBodilessEntity(); } @@ -194,4 +199,80 @@ public class PrestashopClient { .body(PrestashopCustomerDto.SingleResponse.class); return response != null ? response.customer() : null; } + + // ── XML builders ────────────────────────────────────────────────────── + // PS WebService requires XML body for writes; output_format=JSON only affects the response. + + private String toProductXml(PrestashopProductDto dto) { + String name = firstLangValue(dto.name()); + String description = firstLangValue(dto.description()); + String descShort = firstLangValue(dto.descriptionShort()); + String slug = toSlug(dto.reference()); + + StringBuilder sb = new StringBuilder(512); + sb.append(""); + sb.append(""); + sb.append(""); + if (dto.id() != null) { + sb.append("").append(dto.id()).append(""); + } + sb.append("").append(escapeXml(dto.reference())).append(""); + if (dto.price() != null) { + sb.append("").append(escapeXml(dto.price())).append(""); + } + if (dto.active() != null) { + sb.append("").append(escapeXml(dto.active())).append(""); + } + if (dto.idCategoryDefault() != null) { + sb.append("").append(escapeXml(dto.idCategoryDefault())).append(""); + } + sb.append("1"); + sb.append("").append(escapeXml(slug)).append(""); + sb.append("").append(escapeXml(name)).append(""); + sb.append("").append(escapeXml(description)).append(""); + sb.append("").append(escapeXml(descShort)).append(""); + sb.append(""); + sb.append(""); + return sb.toString(); + } + + private String toStockAvailableXml(PrestashopStockAvailableDto dto) { + StringBuilder sb = new StringBuilder(256); + sb.append(""); + sb.append(""); + sb.append(""); + if (dto.id() != null) { + sb.append("").append(dto.id()).append(""); + } + if (dto.idProduct() != null) { + sb.append("").append(dto.idProduct()).append(""); + } + String idAttr = dto.idProductAttribute() != null ? dto.idProductAttribute() : "0"; + sb.append("").append(idAttr).append(""); + sb.append("").append(dto.quantity()).append(""); + sb.append(""); + sb.append(""); + return sb.toString(); + } + + private static String firstLangValue(List langs) { + if (langs == null || langs.isEmpty()) return ""; + String v = langs.get(0).value(); + return v != null ? v : ""; + } + + /** Generates a URL-safe slug from any string (used for PS link_rewrite). */ + private static String toSlug(String text) { + if (text == null || text.isBlank()) return "product"; + return text.toLowerCase().replaceAll("[^a-z0-9]+", "-").replaceAll("^-|-$", ""); + } + + private static String escapeXml(String text) { + if (text == null) return ""; + return text.replace("&", "&") + .replace("<", "<") + .replace(">", ">") + .replace("\"", """) + .replace("'", "'"); + } }