fix: fetch all Dolibarr products without tms sqlfilter
Incremental sync via t.tms filter breaks when products were created before the service started running: their tms is older than lastSyncStart so they are never returned. Since the sync is idempotent (ProductMapping handles create-vs-update), always fetching all products is safe and simpler. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
359590b7d8
commit
806497b24d
|
|
@ -7,9 +7,6 @@ import org.springframework.core.ParameterizedTypeReference;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.client.RestClient;
|
import org.springframework.web.client.RestClient;
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.ZoneOffset;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
@ -24,9 +21,6 @@ import java.util.Map;
|
||||||
@Component
|
@Component
|
||||||
public class DolibarrClient {
|
public class DolibarrClient {
|
||||||
|
|
||||||
private static final DateTimeFormatter DOLIBARR_DATE_FORMAT =
|
|
||||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneOffset.UTC);
|
|
||||||
|
|
||||||
private final RestClient restClient;
|
private final RestClient restClient;
|
||||||
|
|
||||||
public DolibarrClient(@Qualifier("dolibarrRestClient") RestClient restClient) {
|
public DolibarrClient(@Qualifier("dolibarrRestClient") RestClient restClient) {
|
||||||
|
|
@ -36,20 +30,15 @@ public class DolibarrClient {
|
||||||
// ── Products ──────────────────────────────────────────────────────────
|
// ── Products ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all products, optionally filtered by last modification date.
|
* Returns all active products (up to 500).
|
||||||
*
|
*
|
||||||
* @param modifiedSince if non-null, only products with {@code tms >= modifiedSince} are returned
|
* <p>Full fetch on every run keeps sync idempotent and avoids timezone issues
|
||||||
|
* with Dolibarr's {@code tms} column filter. The service handles create-vs-update
|
||||||
|
* via {@code ProductMapping}, so re-processing unchanged products is safe.</p>
|
||||||
*/
|
*/
|
||||||
public List<DolibarrProductDto> getProducts(Instant modifiedSince) {
|
public List<DolibarrProductDto> getProducts() {
|
||||||
return restClient.get()
|
return restClient.get()
|
||||||
.uri(u -> {
|
.uri(u -> u.path("/products").queryParam("limit", 500).build())
|
||||||
u.path("/products").queryParam("limit", 500);
|
|
||||||
if (modifiedSince != null) {
|
|
||||||
u.queryParam("sqlfilters",
|
|
||||||
"(t.tms:>=:'%s')".formatted(DOLIBARR_DATE_FORMAT.format(modifiedSince)));
|
|
||||||
}
|
|
||||||
return u.build();
|
|
||||||
})
|
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.body(new ParameterizedTypeReference<List<DolibarrProductDto>>() {});
|
.body(new ParameterizedTypeReference<List<DolibarrProductDto>>() {});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,15 +40,9 @@ public class ProductSyncService {
|
||||||
private final IntegrationProperties integrationProperties;
|
private final IntegrationProperties integrationProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes a full incremental product push and returns a summary.
|
* Fetches all Dolibarr products and pushes them to PrestaShop (create or update by SKU).
|
||||||
*/
|
*/
|
||||||
public SyncResult synchronize() {
|
public SyncResult synchronize() {
|
||||||
// Determine cutoff BEFORE saving current log to avoid self-reference
|
|
||||||
Instant lastSyncStart = syncLogRepository
|
|
||||||
.findFirstBySyncTypeOrderByStartedAtDesc(SyncType.PRODUCT_PUSH)
|
|
||||||
.map(SyncLog::getStartedAt)
|
|
||||||
.orElse(null);
|
|
||||||
|
|
||||||
SyncLog syncLog = syncLogRepository.save(SyncLog.builder()
|
SyncLog syncLog = syncLogRepository.save(SyncLog.builder()
|
||||||
.syncType(SyncType.PRODUCT_PUSH)
|
.syncType(SyncType.PRODUCT_PUSH)
|
||||||
.startedAt(Instant.now())
|
.startedAt(Instant.now())
|
||||||
|
|
@ -59,8 +53,8 @@ public class ProductSyncService {
|
||||||
List<String> errors = new ArrayList<>();
|
List<String> errors = new ArrayList<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<DolibarrProductDto> products = dolibarrClient.getProducts(lastSyncStart);
|
List<DolibarrProductDto> products = dolibarrClient.getProducts();
|
||||||
log.info("ProductSync: {} products to process (since {})", products.size(), lastSyncStart);
|
log.info("ProductSync: {} products to process", products.size());
|
||||||
|
|
||||||
for (DolibarrProductDto product : products) {
|
for (DolibarrProductDto product : products) {
|
||||||
if (product.ref() == null || product.ref().isBlank()) {
|
if (product.ref() == null || product.ref().isBlank()) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue