fix: map Dolibarr tva_tx to PS id_tax_rules_group on product sync
Price with VAT was showing the same value as price without VAT because id_tax_rules_group was hardcoded to 1 (no-tax group in this PS instance). Now reads tva_tx from Dolibarr product, resolves the PS tax rule group via a configurable map (integration.prestashop.tax-rule-groups), and sets the correct group in the product XML. Defaults to default-tax-rules-group-id when no mapping is found. ES groups configured: 21% → 53, 10% → 54, 4% → 55. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c59d2048db
commit
df3775d96b
|
|
@ -3,8 +3,11 @@ package com.teterialosjuanjos.tfg.sync_service.config;
|
|||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.bind.DefaultValue;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Externalized configuration for Dolibarr and PrestaShop integration endpoints.
|
||||
* Bound from {@code integration.*} properties in application.yml; validated at startup.
|
||||
|
|
@ -28,16 +31,23 @@ public record IntegrationProperties(
|
|||
) {}
|
||||
|
||||
/**
|
||||
* @param baseUrl full API base URL, e.g. {@code https://host/tienda/api}
|
||||
* @param apiKey webservice key sent as {@code ws_key} query param
|
||||
* @param defaultCategoryId PrestaShop category ID assigned to new products (default: 2 = Home)
|
||||
* @param languageId PrestaShop language ID used for all multilingual fields (name, description, etc.)
|
||||
* Check yours at GET /api/languages. Default 1 is usually English; set to Spanish ID.
|
||||
* @param baseUrl full API base URL, e.g. {@code https://host/tienda/api}
|
||||
* @param apiKey webservice key sent as {@code ws_key} query param
|
||||
* @param defaultCategoryId PrestaShop category ID assigned to new products (default: 2 = Home)
|
||||
* @param languageId PrestaShop language ID used for all multilingual fields (name, description, etc.)
|
||||
* Check yours at GET /api/languages. Default 1 is usually English; set to Spanish ID.
|
||||
* @param defaultTaxRulesGroupId Fallback PS {@code id_tax_rules_group} when the product's Dolibarr {@code tva_tx}
|
||||
* has no entry in {@code taxRuleGroups}. Defaults to 1.
|
||||
* Check your PS tax groups at GET /api/tax_rule_groups.
|
||||
* @param taxRuleGroups Map of Dolibarr VAT rate (integer key, e.g. "21") to PS {@code id_tax_rules_group}.
|
||||
* Configure in application-dev/prod.yml. If empty, {@code defaultTaxRulesGroupId} is used.
|
||||
*/
|
||||
public record Prestashop(
|
||||
@NotBlank String baseUrl,
|
||||
@NotBlank String apiKey,
|
||||
int defaultCategoryId,
|
||||
int languageId
|
||||
int languageId,
|
||||
@DefaultValue("1") int defaultTaxRulesGroupId,
|
||||
Map<String, Integer> taxRuleGroups
|
||||
) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,5 +26,7 @@ public record DolibarrProductDto(
|
|||
@JsonProperty("tosell") Integer toSell,
|
||||
/** 0 = physical product, 1 = service */
|
||||
Integer type,
|
||||
Double weight
|
||||
Double weight,
|
||||
/** VAT rate in percent, e.g. 21.0 for 21% IVA */
|
||||
@JsonProperty("tva_tx") Double tvaTx
|
||||
) {}
|
||||
|
|
|
|||
|
|
@ -371,7 +371,8 @@ public class PrestashopClient {
|
|||
sb.append("<id_category_default>").append(escapeXml(dto.idCategoryDefault())).append("</id_category_default>");
|
||||
}
|
||||
sb.append("<state>1</state>");
|
||||
sb.append("<id_tax_rules_group>1</id_tax_rules_group>");
|
||||
int taxRulesGroupId = dto.taxRulesGroupId() != null ? dto.taxRulesGroupId() : 1;
|
||||
sb.append("<id_tax_rules_group>").append(taxRulesGroupId).append("</id_tax_rules_group>");
|
||||
sb.append("<id_shop_default>1</id_shop_default>");
|
||||
sb.append("<available_for_order>1</available_for_order>");
|
||||
sb.append("<show_price>1</show_price>");
|
||||
|
|
|
|||
|
|
@ -34,7 +34,9 @@ public record PrestashopProductDto(
|
|||
@JsonProperty("description_short")
|
||||
@JsonDeserialize(using = MultilangStringDeserializer.class) String descriptionShort,
|
||||
/** PS category IDs to set on write; not present in PS JSON responses (ignored on read). */
|
||||
@JsonIgnore List<String> categoryIds
|
||||
@JsonIgnore List<String> categoryIds,
|
||||
/** PS tax rule group ID; resolved from Dolibarr tva_tx at sync time, write-only. */
|
||||
@JsonIgnore Integer taxRulesGroupId
|
||||
) {
|
||||
|
||||
/** Envelope for {@code GET /api/products?display=full} */
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import org.springframework.web.client.RestClientException;
|
|||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
|
@ -249,6 +250,7 @@ public class ProductSyncService {
|
|||
String description = src.description() != null ? src.description() : "";
|
||||
String descriptionShort = src.notePublic() != null ? src.notePublic() : "";
|
||||
String active = (src.toSell() != null && src.toSell() == 0) ? "0" : "1";
|
||||
Integer taxRulesGroupId = resolveTaxRulesGroup(src.tvaTx());
|
||||
|
||||
return new PrestashopProductDto(
|
||||
prestashopId,
|
||||
|
|
@ -259,7 +261,22 @@ public class ProductSyncService {
|
|||
label,
|
||||
description,
|
||||
descriptionShort,
|
||||
allCategoryIds
|
||||
allCategoryIds,
|
||||
taxRulesGroupId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the PrestaShop {@code id_tax_rules_group} from the Dolibarr VAT rate.
|
||||
* Looks up {@code tvaTx} (truncated to int, e.g. 21.0 → "21") in the configured map.
|
||||
* Falls back to {@code defaultTaxRulesGroupId} when no mapping exists.
|
||||
*/
|
||||
private Integer resolveTaxRulesGroup(Double tvaTx) {
|
||||
Map<String, Integer> map = integrationProperties.prestashop().taxRuleGroups();
|
||||
if (tvaTx != null && map != null && !map.isEmpty()) {
|
||||
Integer groupId = map.get(String.valueOf(tvaTx.intValue()));
|
||||
if (groupId != null) return groupId;
|
||||
}
|
||||
return integrationProperties.prestashop().defaultTaxRulesGroupId();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ integration:
|
|||
api-key: DOLIBARR_API_KEY_AQUI
|
||||
prestashop:
|
||||
api-key: PRESTASHOP_API_KEY_AQUI
|
||||
default-tax-rules-group-id: 53 # ES Standard rate (21%) — fallback
|
||||
tax-rule-groups:
|
||||
21: 53 # ES Standard rate (21%)
|
||||
10: 54 # ES Reduced Rate (10%)
|
||||
4: 55 # ES Super Reduced Rate (4%)
|
||||
|
||||
logging:
|
||||
level:
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@ integration:
|
|||
api-key: ${PRESTASHOP_API_KEY}
|
||||
default-category-id: 2
|
||||
language-id: ${PRESTASHOP_LANGUAGE_ID:1} # set to your Spanish language ID (check GET /api/languages)
|
||||
default-tax-rules-group-id: 53 # ES Standard rate (21%) — fallback
|
||||
tax-rule-groups:
|
||||
21: 53 # ES Standard rate (21%)
|
||||
10: 54 # ES Reduced Rate (10%)
|
||||
4: 55 # ES Super Reduced Rate (4%)
|
||||
|
||||
api:
|
||||
security:
|
||||
|
|
|
|||
Loading…
Reference in New Issue