diff --git a/aggregation/src/main/java/org/open4goods/aggregation/services/aggregation/AttributeRealtimeAggregationService.java b/aggregation/src/main/java/org/open4goods/aggregation/services/aggregation/AttributeRealtimeAggregationService.java index e100e6a9..886403f2 100644 --- a/aggregation/src/main/java/org/open4goods/aggregation/services/aggregation/AttributeRealtimeAggregationService.java +++ b/aggregation/src/main/java/org/open4goods/aggregation/services/aggregation/AttributeRealtimeAggregationService.java @@ -26,16 +26,19 @@ import org.open4goods.model.product.AggregatedFeature; import org.open4goods.model.product.Product; import org.open4goods.services.BrandService; +import org.open4goods.services.VerticalsConfigService; public class AttributeRealtimeAggregationService extends AbstractRealTimeAggregationService { - private final AttributesConfig attributesConfig; + private final BrandService brandService; - public AttributeRealtimeAggregationService(final AttributesConfig attributesConfig, BrandService brandService, final String logsFolder,boolean toConsole) { + private VerticalsConfigService verticalConfigService; + + public AttributeRealtimeAggregationService(final VerticalsConfigService verticalConfigService, BrandService brandService, final String logsFolder,boolean toConsole) { super(logsFolder,toConsole); - this.attributesConfig = attributesConfig; + this.verticalConfigService = verticalConfigService; this.brandService = brandService; } @@ -50,7 +53,13 @@ public AttributeRealtimeAggregationService(final AttributesConfig attributesConf @Override public void onDataFragment(final DataFragment dataFragment, final Product product) { + AttributesConfig attributesConfig = verticalConfigService.getConfigById(product.getVertical() == null ? "all" : product.getVertical() ).get().getAttributesConfig() ; + Set toRemoveFromUnmatched = new HashSet<>(); + // Adding the list of "to be removed" attributes + toRemoveFromUnmatched.addAll(attributesConfig.getExclusions()); + + ///////////////////////////////////////// // Converting to AggregatedAttributes for matches from config ///////////////////////////////////////// @@ -62,7 +71,6 @@ public void onDataFragment(final DataFragment dataFragment, final Product produc all.addAll(product.getAttributes().getUnmapedAttributes().stream().map(e -> new Attribute(e.getName(),e.getValue(),e.getLanguage())).toList()); - for (Attribute attr : dataFragment.getAttributes()) { // Checking if a potential AggregatedAttribute @@ -110,7 +118,7 @@ public void onDataFragment(final DataFragment dataFragment, final Product produc ///////////////////////////////////////// List matchedFeatures = dataFragment.getAttributes().stream() - .filter(this::isFeatureAttribute) + .filter(e -> isFeatureAttribute(e, attributesConfig)) .collect(Collectors.toList()); toRemoveFromUnmatched.addAll(matchedFeatures.stream().map(e->e.getName()).collect(Collectors.toSet())); @@ -337,7 +345,7 @@ private Collection aggregateFeatures(List matchedF * @param e * @return */ - private boolean isFeatureAttribute(Attribute e) { + private boolean isFeatureAttribute(Attribute e, AttributesConfig attributesConfig) { return attributesConfig.getFeaturedValues().contains(e.getRawValue().toString().trim().toUpperCase()); } diff --git a/api/src/main/java/org/open4goods/api/services/RealtimeAggregationService.java b/api/src/main/java/org/open4goods/api/services/RealtimeAggregationService.java index 3b073e3f..6827d3c6 100644 --- a/api/src/main/java/org/open4goods/api/services/RealtimeAggregationService.java +++ b/api/src/main/java/org/open4goods/api/services/RealtimeAggregationService.java @@ -114,7 +114,7 @@ public void shutdown() { /** * List of services in the aggregator - * + *TODO : Replace confif with verticalConfigService, to have hot vertical config onDataFragment * @param config * @return */ @@ -131,7 +131,9 @@ RealTimeAggregator getAggregator(VerticalConfig config) { services.add(new BarCodeAggregationService(apiProperties.logsFolder(), gs1prefixService,barcodeValidationService, apiProperties.isDedicatedLoggerToConsole())); - services.add(new AttributeRealtimeAggregationService(config.getAttributesConfig(), brandService, apiProperties.logsFolder(), apiProperties.isDedicatedLoggerToConsole())); + services.add(new VerticalRealTimeAggregationService( apiProperties.logsFolder(), verticalConfigService, apiProperties.isDedicatedLoggerToConsole())); + + services.add(new AttributeRealtimeAggregationService(verticalConfigService, brandService, apiProperties.logsFolder(), apiProperties.isDedicatedLoggerToConsole())); services.add(new NamesAggregationService(apiProperties.logsFolder(), apiProperties.isDedicatedLoggerToConsole())); @@ -139,7 +141,6 @@ RealTimeAggregator getAggregator(VerticalConfig config) { // services.add(new CategoryService(apiProperties.logsFolder(), taxonomyService)); - services.add(new VerticalRealTimeAggregationService( apiProperties.logsFolder(), verticalConfigService, apiProperties.isDedicatedLoggerToConsole())); services.add(new IdAggregationService( apiProperties.logsFolder(), apiProperties.isDedicatedLoggerToConsole())); diff --git a/commons/src/main/java/org/open4goods/config/yml/ui/AttributesConfig.java b/commons/src/main/java/org/open4goods/config/yml/ui/AttributesConfig.java index 031a7df6..714b582a 100644 --- a/commons/src/main/java/org/open4goods/config/yml/ui/AttributesConfig.java +++ b/commons/src/main/java/org/open4goods/config/yml/ui/AttributesConfig.java @@ -19,6 +19,8 @@ public class AttributesConfig { + // Local cache + private Map> cacheHashedSynonyms; /** * The specific configs configurations */ @@ -56,6 +58,9 @@ public class AttributesConfig { @JsonIgnore private Map hashedAttributesByKey; + + + public AttributesConfig(Set configs) { this.configs = configs; @@ -72,23 +77,27 @@ public AttributesConfig() { * * @return A map-ProviderKey,Synonym, Translated Key */ - @Cacheable(cacheNames = CacheConstants.FOREVER_LOCAL_CACHE_NAME) + // Spring cache ineffectiv on internal calls +// @Cacheable(cacheNames = CacheConstants.FOREVER_LOCAL_CACHE_NAME) public Map> synonyms() { - final Map> hashedSynonyms = new HashMap<>(); - - for (final AttributeConfig ac : configs) { - for (final Entry> entry : ac.getSynonyms().entrySet()) { - if (!hashedSynonyms.containsKey(entry.getKey())) { - hashedSynonyms.put(entry.getKey(), new HashMap<>()); - } - for (final String val : entry.getValue()) { - hashedSynonyms.get(entry.getKey()).put(val, ac.getKey()); + if (cacheHashedSynonyms == null) { + + final Map> hashedSynonyms = new HashMap<>(); + + for (final AttributeConfig ac : configs) { + for (final Entry> entry : ac.getSynonyms().entrySet()) { + if (!hashedSynonyms.containsKey(entry.getKey())) { + hashedSynonyms.put(entry.getKey(), new HashMap<>()); + } + for (final String val : entry.getValue()) { + hashedSynonyms.get(entry.getKey()).put(val, ac.getKey()); + } } } + cacheHashedSynonyms = hashedSynonyms; } - - return hashedSynonyms; + return cacheHashedSynonyms; } public Attribute translateAttribute(final Attribute a, final String provider) { diff --git a/commons/src/main/java/org/open4goods/model/product/AggregatedAttribute.java b/commons/src/main/java/org/open4goods/model/product/AggregatedAttribute.java index 7cafa228..3ec77ec3 100644 --- a/commons/src/main/java/org/open4goods/model/product/AggregatedAttribute.java +++ b/commons/src/main/java/org/open4goods/model/product/AggregatedAttribute.java @@ -8,6 +8,7 @@ import java.util.Set; import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; import org.open4goods.config.yml.attributes.AttributeConfig; import org.open4goods.exceptions.ValidationException; import org.open4goods.model.attribute.Attribute; @@ -63,6 +64,23 @@ public int sourcesCount() { public long distinctValues () { return sources.stream().map(e-> e.getValue()).distinct().count(); } + + /** + * For UI, a String representation of all providers names + * @return + */ + public String providersToString() { + return StringUtils.join( sources.stream().map(e-> e.getKey()).toArray(),", "); + } + + /** + * For UI, a String representation of all providers names and values + * @return + */ + public String sourcesToString() { + return StringUtils.join( sources.stream().map(e-> e.getKey() + ":"+e.getValue()).toArray(),", "); + + } public boolean hasConflicts() { diff --git a/commons/src/main/java/org/open4goods/model/product/AggregatedPrice.java b/commons/src/main/java/org/open4goods/model/product/AggregatedPrice.java index 12ee3fb2..4b01de5e 100644 --- a/commons/src/main/java/org/open4goods/model/product/AggregatedPrice.java +++ b/commons/src/main/java/org/open4goods/model/product/AggregatedPrice.java @@ -18,6 +18,7 @@ public class AggregatedPrice extends Price { @Field(index = false, store = false, type = FieldType.Keyword) private String datasourceName; + @Field(index = false, store = false, type = FieldType.Keyword) private String offerName; @Field(index = false, store = false, type = FieldType.Keyword) diff --git a/commons/src/main/java/org/open4goods/services/SearchService.java b/commons/src/main/java/org/open4goods/services/SearchService.java index d32512bc..a022a850 100644 --- a/commons/src/main/java/org/open4goods/services/SearchService.java +++ b/commons/src/main/java/org/open4goods/services/SearchService.java @@ -234,8 +234,11 @@ public VerticalSearchResponse verticalSearch(VerticalConfig vertical, VerticalSe for (AttributeConfig attrConfig : customAttrFilters) { esQuery = esQuery // TODO : size from conf - .withAggregation(attrConfig.getKey(), Aggregation.of(a -> a.terms(ta -> ta.field("attributes.aggregatedAttributes."+attrConfig.getKey()+".value").missing(OTHER_BUCKET).size(100) )) ); + .withAggregation(attrConfig.getKey(), Aggregation.of(a -> a.terms(ta -> ta.field("attributes.aggregatedAttributes."+attrConfig.getKey()+".value.keyword").missing(OTHER_BUCKET).size(100) )) ); } + + + // Adding custom range aggregations for (NumericRangeFilter filter: request.getNumericFilters()) { esQuery = esQuery diff --git a/commons/src/main/java/org/open4goods/services/VerticalsConfigService.java b/commons/src/main/java/org/open4goods/services/VerticalsConfigService.java index 575cd005..c0980688 100644 --- a/commons/src/main/java/org/open4goods/services/VerticalsConfigService.java +++ b/commons/src/main/java/org/open4goods/services/VerticalsConfigService.java @@ -37,8 +37,8 @@ public class VerticalsConfigService { public static final Logger logger = LoggerFactory.getLogger(VerticalsConfigService.class); private static final String DEFAULT_CONFIG_FILENAME = "_default.yml"; - private static final String CLASSPATH_VERTICALS = "classpath:**verticals/*.yml"; - private static final String CLASSPATH_VERTICAL_PREFIX = "classpath:verticals/"; +// private static final String CLASSPATH_VERTICALS = "classpath:**verticals/*.yml"; +// private static final String CLASSPATH_VERTICAL_PREFIX = "classpath:verticals/"; private SerialisationService serialisationService; diff --git a/ui/src/main/java/org/open4goods/ui/controllers/ui/ProductController.java b/ui/src/main/java/org/open4goods/ui/controllers/ui/ProductController.java index 0f358d92..115e5f79 100644 --- a/ui/src/main/java/org/open4goods/ui/controllers/ui/ProductController.java +++ b/ui/src/main/java/org/open4goods/ui/controllers/ui/ProductController.java @@ -19,6 +19,7 @@ import org.open4goods.services.SerialisationService; import org.open4goods.services.VerticalsConfigService; import org.open4goods.ui.config.yml.UiConfig; +import org.open4goods.ui.helper.UiHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -187,7 +188,9 @@ private ModelAndView buildProductView(String id, String vertical, final HttpServ mv.addObject("product", data); - mv.addObject("verticalConfig", verticalConfigService.getVerticalForPath(vertical)); + + VerticalConfig verticalConfig = verticalConfigService.getVerticalForPath(vertical); + mv.addObject("verticalConfig", verticalConfig); @@ -200,6 +203,9 @@ private ModelAndView buildProductView(String id, String vertical, final HttpServ // Adding the brand informations mv.addObject("hasBrandLogo", brandService.hasLogo(data.brand())); + // Adding the UiHelper class + mv.addObject("helper", new UiHelper(request, verticalConfig)); + // Adding the images resource return mv; diff --git a/ui/src/main/java/org/open4goods/ui/helper/UiHelper.java b/ui/src/main/java/org/open4goods/ui/helper/UiHelper.java new file mode 100644 index 00000000..b4080705 --- /dev/null +++ b/ui/src/main/java/org/open4goods/ui/helper/UiHelper.java @@ -0,0 +1,39 @@ +package org.open4goods.ui.helper; + +import org.open4goods.config.yml.ui.VerticalConfig; +import org.open4goods.services.VerticalsConfigService; + +import jakarta.servlet.http.HttpServletRequest; + +public class UiHelper { + + + private HttpServletRequest request; + private VerticalConfig verticalConfig; + + public UiHelper(HttpServletRequest request, VerticalConfig verticalConfig) { + super(); + this.request = request; + this.verticalConfig = verticalConfig; + } + + + + + /** + * Return the i18n for an attribute + * @param key + * @return + */ + public String attributeName(String key) { + + return verticalConfig.getAttributesConfig().getAttributeConfigByKey(key).i18n(request.getLocale().getLanguage()); + + + } + + + + + +} diff --git a/ui/src/main/resources/i18n/messages_fr.properties b/ui/src/main/resources/i18n/messages_fr.properties index abd7944a..004ffac1 100644 --- a/ui/src/main/resources/i18n/messages_fr.properties +++ b/ui/src/main/resources/i18n/messages_fr.properties @@ -1,7 +1,12 @@ aria.navigation.primary = Navigation principale -attribute.sourcing = {0} source(s) de donn\u00E9e(s), {1} conflit(s) +attribute.sourcing.conflict = {1} conflits +attribute.sourcing.noconflict = Aucun conflit + +attribute.sourcing.list = {0} source(s) de donn\u00E9e(s) ({2}) + + category.meta.description = {0} produits dans la cat\u00E9gorie {1} sont \u00E9ligibles \u00E0 la compensation carbone category.meta.title = Produits de la cat\u00E9gorie {0} diff --git a/ui/src/main/resources/static/css/custom.css b/ui/src/main/resources/static/css/custom.css index c3376d3c..09ad7373 100644 --- a/ui/src/main/resources/static/css/custom.css +++ b/ui/src/main/resources/static/css/custom.css @@ -7,7 +7,9 @@ CUSTOM width: 90%; } - +.help-pointer:hover { + cursor : help; +} /*********************************************** Xwiki css **************************************************/ diff --git a/ui/src/main/resources/static/icons/ko.png b/ui/src/main/resources/static/icons/ko.png new file mode 100644 index 00000000..b80c93b2 Binary files /dev/null and b/ui/src/main/resources/static/icons/ko.png differ diff --git a/ui/src/main/resources/static/icons/ok.png b/ui/src/main/resources/static/icons/ok.png new file mode 100644 index 00000000..35aaa086 Binary files /dev/null and b/ui/src/main/resources/static/icons/ok.png differ diff --git a/ui/src/main/resources/templates/inc/attribute-sourcing.html b/ui/src/main/resources/templates/inc/attribute-sourcing.html new file mode 100644 index 00000000..a61a5d52 --- /dev/null +++ b/ui/src/main/resources/templates/inc/attribute-sourcing.html @@ -0,0 +1,13 @@ + + + + + + + + + + 1 + + 1 + diff --git a/ui/src/main/resources/templates/inc/attributes/class_energy.html b/ui/src/main/resources/templates/inc/attributes/class_energy.html index 01e1096d..d229f66f 100644 --- a/ui/src/main/resources/templates/inc/attributes/class_energy.html +++ b/ui/src/main/resources/templates/inc/attributes/class_energy.html @@ -1,6 +1,6 @@ - - + + diff --git a/ui/src/main/resources/templates/inc/product-attributes.html b/ui/src/main/resources/templates/inc/product-attributes.html index 22678c65..1a9157cd 100644 --- a/ui/src/main/resources/templates/inc/product-attributes.html +++ b/ui/src/main/resources/templates/inc/product-attributes.html @@ -1,15 +1,20 @@ -