diff --git a/aggregation/src/main/java/org/open4goods/aggregation/aggregator/RealTimeAggregator.java b/aggregation/src/main/java/org/open4goods/aggregation/aggregator/RealTimeAggregator.java index eee53bf1e..75153c1a0 100644 --- a/aggregation/src/main/java/org/open4goods/aggregation/aggregator/RealTimeAggregator.java +++ b/aggregation/src/main/java/org/open4goods/aggregation/aggregator/RealTimeAggregator.java @@ -56,6 +56,7 @@ public Product build(final DataFragment fragment, final Product data ) throws Ag throw e; } catch (final Exception e) { + e.printStackTrace(); logger.warn("AggregationService {} throw an exception while processing data {}",service.getClass().getName(), data,e); } 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 886403f2a..6d6b6a9ce 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 @@ -58,8 +58,7 @@ public void onDataFragment(final DataFragment dataFragment, final Product produc Set toRemoveFromUnmatched = new HashSet<>(); // Adding the list of "to be removed" attributes toRemoveFromUnmatched.addAll(attributesConfig.getExclusions()); - - + ///////////////////////////////////////// // Converting to AggregatedAttributes for matches from config ///////////////////////////////////////// @@ -71,7 +70,7 @@ 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()) { + for (Attribute attr : all) { // Checking if a potential AggregatedAttribute Attribute translated = attributesConfig.translateAttribute(attr, dataFragment.getDatasourceName()); @@ -85,16 +84,22 @@ public void onDataFragment(final DataFragment dataFragment, final Product produc // Applying parsing rule translated = parseAttributeValue(translated, attrConfig); + if (translated.getRawValue() == null) { + continue; + } + AggregatedAttribute agg = product.getAttributes().getAggregatedAttributes().get(attr.getName()); - toRemoveFromUnmatched.add(translated.getName()); if (null == agg) { // A first time match agg = new AggregatedAttribute(); agg.setName(attr.getName()); } - + + + + toRemoveFromUnmatched.add(translated.getName()); agg.addAttribute(translated,attrConfig, new UnindexedKeyValTimestamp(dataFragment.getDatasourceName(), translated.getValue().toString())); // Replacing new AggAttribute in product @@ -153,6 +158,12 @@ public void onDataFragment(final DataFragment dataFragment, final Product produc product.getAttributes().getUnmapedAttributes().add(agg); } + + // Removing + product.getAttributes().setUnmapedAttributes(product.getAttributes().getUnmapedAttributes().stream().filter(e -> !toRemoveFromUnmatched.contains(e.getName())) .collect(Collectors.toSet())); + + + // TODO : Removing matchlist again to handle remove of old attributes in case of configuration change // product.getAttributes().getUnmapedAttributes(). } @@ -488,6 +499,17 @@ public Attribute parseAttributeValue(final Attribute attr, final AttributeConfig } + + + + ///////////////////////////////// + // FIXED TEXT MAPPING + ///////////////////////////////// + if (!conf.getMappings().isEmpty() ) { + String replacement = conf.getMappings().get(attr.getRawValue()); + attr.setRawValue(replacement); + } + ///////////////////////////////// // Checking preliminary result ///////////////////////////////// diff --git a/commons/src/main/java/org/open4goods/config/yml/attributes/AttributeConfig.java b/commons/src/main/java/org/open4goods/config/yml/attributes/AttributeConfig.java index 22204ea67..0d31a49f3 100644 --- a/commons/src/main/java/org/open4goods/config/yml/attributes/AttributeConfig.java +++ b/commons/src/main/java/org/open4goods/config/yml/attributes/AttributeConfig.java @@ -49,6 +49,14 @@ public class AttributeConfig { */ private boolean asRating = false; + /** + * If true, this attribute will be used as search filter + */ + private boolean asSearchFilter = true; + + + + /** * The ordering that must be applied to this attributes values after aggregations. (ie rendered in search attributes selection) @@ -69,12 +77,12 @@ public class AttributeConfig { /** If true, this attribute will be used for aggregations searches **/ - private Boolean searchable = false; + // private Boolean searchable = false; /** * The position in the search page navigation zone */ - private Integer searchPresentationOrder = Integer.MIN_VALUE; + // private Integer searchPresentationOrder = Integer.MIN_VALUE; /** * If set, this attribute will appear at the given attributeValuesOrdering in tabularised @@ -89,22 +97,22 @@ public class AttributeConfig { private String searchTemplate; - - /** - * If non null, present the "count by" stats for this attribute, Will appear at the index designated by the integer value - */ - private Integer statsOrder; - - /** - * the Chart.js chart type - */ - private AttrChartType statsType = AttrChartType.bar; - - /** - * If true, will be the default stats rendered. (Should so only have one - * attribute set to true) - */ - private boolean statsDefaultView = false; +// +// /** +// * If non null, present the "count by" stats for this attribute, Will appear at the index designated by the integer value +// */ +// private Integer statsOrder; +// +// /** +// * the Chart.js chart type +// */ +// private AttrChartType statsType = AttrChartType.bar; +// +// /** +// * If true, will be the default stats rendered. (Should so only have one +// * attribute set to true) +// */ +// private boolean statsDefaultView = false; @@ -127,6 +135,13 @@ public class AttributeConfig { * If set, text attributes will be converted to numerics using this table conversion */ private Map numericMapping = new HashMap<>(); + + + /** + * If set, fixed text mappings conversion + */ + private Map mappings = new HashMap<>(); + @@ -314,15 +329,6 @@ public void setSynonyms(final Map> synonyms) { - - public Boolean getSearchable() { - return searchable; - } - - public void setSearchable(final Boolean aggregate) { - searchable = aggregate; - } - /** * If set, this attribute will appear at the given attributeValuesOrdering in tabularised * search results @@ -343,30 +349,6 @@ public void setFaIcon(final String faIcon) { this.faIcon = faIcon; } - public Integer getStatsOrder() { - return statsOrder; - } - - public void setStatsOrder(final Integer presentStats) { - statsOrder = presentStats; - } - - public AttrChartType getStatsType() { - return statsType; - } - - public void setStatsType(final AttrChartType statsType) { - this.statsType = statsType; - } - - public boolean isStatsDefaultView() { - return statsDefaultView; - } - - public void setStatsDefaultView(final boolean statsDefaultView) { - this.statsDefaultView = statsDefaultView; - } - public String getSearchTemplate() { return searchTemplate; @@ -412,21 +394,6 @@ public void setNumericMapping(final Map numericMapping) { this.numericMapping = numericMapping; } - - - public Integer getSearchPresentationOrder() { - return searchPresentationOrder; - } - - - - public void setSearchPresentationOrder(final Integer searchPresentationOrder) { - this.searchPresentationOrder = searchPresentationOrder; - } - - - - public boolean isAsRating() { return asRating; } @@ -445,5 +412,21 @@ public void setName(final Localisable name) { this.name = name; } + public Map getMappings() { + return mappings; + } + + public void setMappings(Map mappings) { + this.mappings = mappings; + } + + public boolean isAsSearchFilter() { + return asSearchFilter; + } + + public void setAsSearchFilter(boolean asSearchFilter) { + this.asSearchFilter = asSearchFilter; + } + } diff --git a/commons/src/main/java/org/open4goods/config/yml/ui/VerticalConfig.java b/commons/src/main/java/org/open4goods/config/yml/ui/VerticalConfig.java index 83b4fa18c..e9ab1efbc 100644 --- a/commons/src/main/java/org/open4goods/config/yml/ui/VerticalConfig.java +++ b/commons/src/main/java/org/open4goods/config/yml/ui/VerticalConfig.java @@ -213,27 +213,27 @@ public List searchTableAttributes() { return ret; } - /** - * - * @return the list of AttributeConfig that have to appear in search results, - * ordered by their display position - */ - public List statsAttributes() { - final List ret = new ArrayList<>(); - for (final AttributeConfig a : attributesConfig.getConfigs()) { - if (null != a.getStatsOrder()) { - try { - ret.add(a.getStatsOrder(), a); - } catch (final IndexOutOfBoundsException e) { - LOGGER.warn("statsOrder {} is invalid for attribute {}. Will place last", a.getStatsOrder(), - a.getName()); - ret.add(a); - } - } - } - return ret; - } - +// /** +// * +// * @return the list of AttributeConfig that have to appear in search results, +// * ordered by their display position +// */ +// public List statsAttributes() { +// final List ret = new ArrayList<>(); +// for (final AttributeConfig a : attributesConfig.getConfigs()) { +// if (null != a.getStatsOrder()) { +// try { +// ret.add(a.getStatsOrder(), a); +// } catch (final IndexOutOfBoundsException e) { +// LOGGER.warn("statsOrder {} is invalid for attribute {}. Will place last", a.getStatsOrder(), +// a.getName()); +// ret.add(a); +// } +// } +// } +// return ret; +// } +// /** @@ -243,7 +243,10 @@ public List statsAttributes() { public List verticalFilters() { return verticalFilters.stream() + .map(e -> getAttributesConfig().getAttributeConfigByKey(e)) + .filter(e->e != null) + .filter(e->e.isAsSearchFilter()) .collect(Collectors.toList()); } diff --git a/commons/src/main/java/org/open4goods/model/product/Product.java b/commons/src/main/java/org/open4goods/model/product/Product.java index b192f228a..5db9f0b0d 100644 --- a/commons/src/main/java/org/open4goods/model/product/Product.java +++ b/commons/src/main/java/org/open4goods/model/product/Product.java @@ -396,7 +396,16 @@ public List datasourceCategoriesWithoutShortest() { } - + public String brandAndModel() { + String ret = ""; + if (!StringUtils.isEmpty(brand())) { + ret += brand() +"-"; + } + + ret += model(); + + return ret; + } /** * diff --git a/commons/src/main/java/org/open4goods/services/SearchService.java b/commons/src/main/java/org/open4goods/services/SearchService.java index a022a850f..fbdc8cd14 100644 --- a/commons/src/main/java/org/open4goods/services/SearchService.java +++ b/commons/src/main/java/org/open4goods/services/SearchService.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Map.Entry; import java.util.Set; +import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.open4goods.config.yml.attributes.AttributeConfig; @@ -137,7 +138,7 @@ public VerticalSearchResponse verticalSearch(VerticalConfig vertical, VerticalSe VerticalSearchResponse vsr = new VerticalSearchResponse(); - List customAttrFilters = vertical.verticalFilters(); + List customAttrFilters = vertical.verticalFilters().stream().filter(e-> e!= null).collect(Collectors.toList()); Criteria criterias = new Criteria("vertical").is(vertical.getId()) diff --git a/ui/src/main/resources/templates/inc/attribute-sourcing.html b/ui/src/main/resources/templates/inc/attribute-sourcing.html index a61a5d52f..e6f94f76f 100644 --- a/ui/src/main/resources/templates/inc/attribute-sourcing.html +++ b/ui/src/main/resources/templates/inc/attribute-sourcing.html @@ -1,4 +1,4 @@ - + @@ -7,7 +7,7 @@ - 1 + - 1 + diff --git a/ui/src/main/resources/templates/inc/product-attributes.html b/ui/src/main/resources/templates/inc/product-attributes.html index 1a9157cd1..8d679b1b2 100644 --- a/ui/src/main/resources/templates/inc/product-attributes.html +++ b/ui/src/main/resources/templates/inc/product-attributes.html @@ -5,12 +5,12 @@ - + - - + + diff --git a/ui/src/main/resources/templates/inc/product-descriptions.html b/ui/src/main/resources/templates/inc/product-descriptions.html index 967fc752d..2f5fc0cd8 100644 --- a/ui/src/main/resources/templates/inc/product-descriptions.html +++ b/ui/src/main/resources/templates/inc/product-descriptions.html @@ -35,10 +35,12 @@

Description générale

Web design illustration -

Information sur les prix

+

Evolution des prix

- +
+ +

lorem ipsum

@@ -69,13 +71,13 @@

Bilan écologique

- Web design illustration -

Points de vigilance

- SAMSUNG-75C9 -

- lorem ipsum -

-
+ +

Origine

+ +

Cette information est récuperée par les + premiers chiffres du code barre (), et indique la nationalité de + l'organisme qui a délivré le code barre. Cela n'indique pas nécessairement le lieu de production.

+
diff --git a/ui/src/main/resources/templates/inc/product-ecoscore.html b/ui/src/main/resources/templates/inc/product-ecoscore.html index 35723596f..d1c4327c0 100644 --- a/ui/src/main/resources/templates/inc/product-ecoscore.html +++ b/ui/src/main/resources/templates/inc/product-ecoscore.html @@ -53,7 +53,7 @@
- +
@@ -105,76 +105,9 @@
- - -
- -
- - - - - +
- - -
\ No newline at end of file diff --git a/ui/src/main/resources/templates/inc/product-referentiel-attributes.html b/ui/src/main/resources/templates/inc/product-referentiel-attributes.html index 4a2724417..28d4db1dc 100644 --- a/ui/src/main/resources/templates/inc/product-referentiel-attributes.html +++ b/ui/src/main/resources/templates/inc/product-referentiel-attributes.html @@ -27,8 +27,8 @@ - Modèle - + Modèle + @@ -58,7 +58,10 @@ - + + + + diff --git a/ui/src/main/resources/templates/product.html b/ui/src/main/resources/templates/product.html index e57bf7ef3..a0cd33735 100644 --- a/ui/src/main/resources/templates/product.html +++ b/ui/src/main/resources/templates/product.html @@ -107,8 +107,9 @@ - + @@ -119,7 +120,14 @@
- + + + + + + + +
@@ -130,8 +138,7 @@

Mode développement

Cette section n'apparait qu'a là nudger team

- - + @@ -188,6 +195,7 @@ --> + @@ -196,8 +204,6 @@ - - @@ -253,6 +259,200 @@ setTimeout(reversment.start(), 5000); + + + + + + + + + + + + + + + + + + + + + +// Ecoscore radar chart + + + + const data = { + labels: [ + 'Eating', + 'Drinking', + 'Sleeping', + 'Designing', + 'Coding', + 'Cycling', + 'Running' + ], + datasets: [{ + label: 'My First Dataset', + data: [65, 59, 90, 81, 56, 55, 40], + fill: true, + backgroundColor: 'rgba(255, 99, 132, 0.2)', + borderColor: 'rgb(255, 99, 132)', + pointBackgroundColor: 'rgb(255, 99, 132)', + pointBorderColor: '#fff', + pointHoverBackgroundColor: '#fff', + pointHoverBorderColor: 'rgb(255, 99, 132)' + }, { + label: 'My Second Dataset', + data: [28, 48, 40, 19, 96, 27, 100], + fill: true, + backgroundColor: 'rgba(54, 162, 235, 0.2)', + borderColor: 'rgb(54, 162, 235)', + pointBackgroundColor: 'rgb(54, 162, 235)', + pointBorderColor: '#fff', + pointHoverBackgroundColor: '#fff', + pointHoverBorderColor: 'rgb(54, 162, 235)' + }] + }; + + + + const config = { + type: 'radar', + data: data, + options: { + elements: { + line: { + borderWidth: 3 + } + } + }, + }; + + + const ctx = document.getElementById('radarScore'); + + new Chart(ctx, config); + + + + + + + + + + + +// Price chart + + + + const data2 = { + labels: [ // Date Objects + Utils.newDate(0), + Utils.newDate(1), + Utils.newDate(2), + Utils.newDate(3), + Utils.newDate(4), + Utils.newDate(5), + Utils.newDate(6) + ], + datasets: [{ + label: 'My First dataset', + backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5), + borderColor: Utils.CHART_COLORS.red, + fill: false, + data: Utils.numbers(NUMBER_CFG), + }, { + label: 'My Second dataset', + backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5), + borderColor: Utils.CHART_COLORS.blue, + fill: false, + data: Utils.numbers(NUMBER_CFG), + }, { + label: 'Dataset with point data', + backgroundColor: Utils.transparentize(Utils.CHART_COLORS.green, 0.5), + borderColor: Utils.CHART_COLORS.green, + fill: false, + data: [{ + x: Utils.newDateString(0), + y: Utils.rand(0, 100) + }, { + x: Utils.newDateString(5), + y: Utils.rand(0, 100) + }, { + x: Utils.newDateString(7), + y: Utils.rand(0, 100) + }, { + x: Utils.newDateString(15), + y: Utils.rand(0, 100) + }], + }] + }; + + + + const config2 = { + type: 'line', + data: data2, + options: { + plugins: { + title: { + text: 'Chart.js Time Scale', + display: true + } + }, + scales: { + x: { + type: 'time', + time: { + // Luxon format string + tooltipFormat: 'DD T' + }, + title: { + display: true, + text: 'Date' + } + }, + y: { + title: { + display: true, + text: 'value' + } + } + }, + }, +}; + + + const ctx2 = document.getElementById('priceChart'); + + new Chart(ctx2, config2); + + + + + + + + + + + + + + + + + + + + + +