From 75b59db1bf91a8bd86c5fec0b5c37985f7319fe2 Mon Sep 17 00:00:00 2001 From: Jerome Velociter Date: Thu, 1 Aug 2013 22:34:36 +0200 Subject: [PATCH] Support for products weight and weight-based shipping price strategy --- ...21__add_shipping_column_to_order_table.sql | 2 +- .../ProductRepresentation.java | 13 ++++ .../api/resources/ProductResource.java | 1 + .../configuration/shop/ProductsSettings.java | 20 +++++- .../mayocat/shop/catalog/model/Product.java | 16 ++++- .../shop/catalog/model/WeightUnit.java | 44 ++++++++++++ .../store/jdbi/mapper/ProductMapper.java | 1 + .../resources/mayoapp/dao/ProductDAO.sql.stg | 4 +- ...0078_0022__add_weight_to_product_table.sql | 1 + .../assets/client/javascripts/product.js | 4 ++ .../assets/client/javascripts/settings.js | 5 +- .../assets/client/javascripts/shipping.js | 5 +- .../partials/directives/carrierSummary.html | 2 +- .../assets/client/partials/product.html | 8 +++ .../client/partials/settingsCatalog.html | 28 ++++++++ .../client/partials/settingsShipping.html | 8 +-- ...ractValueBasedStrategyPriceCalculator.java | 33 +++++++++ .../PriceStrategyPriceCalculator.java | 18 +---- .../WeightStrategyPriceCalculator.java | 32 +++++++++ .../main/resources/META-INF/components.txt | 1 + .../WeightStrategyPriceCalculatorTest.java | 71 +++++++++++++++++++ 21 files changed, 289 insertions(+), 28 deletions(-) create mode 100644 shop/catalog/src/main/java/org/mayocat/shop/catalog/model/WeightUnit.java create mode 100644 shop/catalog/src/main/resources/mayoapp/migrations/V0078_0022__add_weight_to_product_table.sql create mode 100644 shop/shipping/internal/src/main/java/org/mayocat/shop/shipping/strategy/AbstractValueBasedStrategyPriceCalculator.java create mode 100644 shop/shipping/internal/src/main/java/org/mayocat/shop/shipping/strategy/WeightStrategyPriceCalculator.java create mode 100644 shop/shipping/internal/src/test/java/org/mayocat/shop/shipping/strategy/WeightStrategyPriceCalculatorTest.java diff --git a/shop/billing/src/main/resources/mayoapp/migrations/V0078_0021__add_shipping_column_to_order_table.sql b/shop/billing/src/main/resources/mayoapp/migrations/V0078_0021__add_shipping_column_to_order_table.sql index c546d9eec..06eb5de4e 100644 --- a/shop/billing/src/main/resources/mayoapp/migrations/V0078_0021__add_shipping_column_to_order_table.sql +++ b/shop/billing/src/main/resources/mayoapp/migrations/V0078_0021__add_shipping_column_to_order_table.sql @@ -1 +1 @@ -ALTER TABLE purchase_order ADD COLUMN shipping numeric(18,4); \ No newline at end of file + ALTER TABLE purchase_order ADD COLUMN shipping numeric(18,4); \ No newline at end of file diff --git a/shop/catalog/src/main/java/org/mayocat/shop/catalog/api/representations/ProductRepresentation.java b/shop/catalog/src/main/java/org/mayocat/shop/catalog/api/representations/ProductRepresentation.java index b0edef3fe..892f9457c 100644 --- a/shop/catalog/src/main/java/org/mayocat/shop/catalog/api/representations/ProductRepresentation.java +++ b/shop/catalog/src/main/java/org/mayocat/shop/catalog/api/representations/ProductRepresentation.java @@ -29,6 +29,8 @@ public class ProductRepresentation private BigDecimal price; + private BigDecimal weight; + private Integer stock; @JsonInclude(JsonInclude.Include.NON_NULL) @@ -71,6 +73,7 @@ public ProductRepresentation(Product product, List getAddons() { return addons; diff --git a/shop/catalog/src/main/java/org/mayocat/shop/catalog/api/resources/ProductResource.java b/shop/catalog/src/main/java/org/mayocat/shop/catalog/api/resources/ProductResource.java index d11ff9994..7409995f5 100644 --- a/shop/catalog/src/main/java/org/mayocat/shop/catalog/api/resources/ProductResource.java +++ b/shop/catalog/src/main/java/org/mayocat/shop/catalog/api/resources/ProductResource.java @@ -256,6 +256,7 @@ public Response updateProduct(@PathParam("slug") String slug, product.setModel(updatedProductRepresentation.getModel()); product.setOnShelf(updatedProductRepresentation.getOnShelf()); product.setPrice(updatedProductRepresentation.getPrice()); + product.setWeight(updatedProductRepresentation.getWeight()); product.setStock(updatedProductRepresentation.getStock()); product.setAddons(addonsRepresentationUnmarshaller.unmarshall(updatedProductRepresentation.getAddons())); diff --git a/shop/catalog/src/main/java/org/mayocat/shop/catalog/configuration/shop/ProductsSettings.java b/shop/catalog/src/main/java/org/mayocat/shop/catalog/configuration/shop/ProductsSettings.java index bddf5795c..b74c5abd7 100644 --- a/shop/catalog/src/main/java/org/mayocat/shop/catalog/configuration/shop/ProductsSettings.java +++ b/shop/catalog/src/main/java/org/mayocat/shop/catalog/configuration/shop/ProductsSettings.java @@ -3,6 +3,7 @@ import javax.validation.Valid; import org.mayocat.configuration.Configurable; +import org.mayocat.shop.catalog.model.WeightUnit; import com.fasterxml.jackson.annotation.JsonProperty; @@ -11,7 +12,6 @@ */ public class ProductsSettings { - @Valid @JsonProperty private Configurable stock = new Configurable(true); @@ -20,6 +20,14 @@ public class ProductsSettings @JsonProperty private Configurable collections = new Configurable(true); + @Valid + @JsonProperty + private Configurable weight = new Configurable(true); + + @Valid + @JsonProperty + private Configurable weightUnit = new Configurable(WeightUnit.KILOGRAM); + public Configurable getCollections() { return this.collections; @@ -29,4 +37,14 @@ public Configurable getStock() { return stock; } + + public Configurable getWeight() + { + return weight; + } + + public Configurable getWeightUnit() + { + return weightUnit; + } } diff --git a/shop/catalog/src/main/java/org/mayocat/shop/catalog/model/Product.java b/shop/catalog/src/main/java/org/mayocat/shop/catalog/model/Product.java index 739ed99ca..1e3d95052 100644 --- a/shop/catalog/src/main/java/org/mayocat/shop/catalog/model/Product.java +++ b/shop/catalog/src/main/java/org/mayocat/shop/catalog/model/Product.java @@ -44,6 +44,8 @@ public class Product extends AbstractLocalizedEntity implements HasAddons, HasMo private BigDecimal price; + private BigDecimal weight; + private Integer stock; @DoNotIndex @@ -128,6 +130,16 @@ public void setPrice(BigDecimal price) this.price = price; } + public BigDecimal getWeight() + { + return weight; + } + + public void setWeight(BigDecimal weight) + { + this.weight = weight; + } + @Override public PerhapsLoaded> getAddons() { @@ -189,6 +201,7 @@ public boolean equals(Object obj) && Objects.equal(this.onShelf, other.onShelf) && Objects.equal(this.price, other.price) && Objects.equal(this.stock, other.stock) + && Objects.equal(this.weight, other.weight) && Objects.equal(this.featuredImageId, other.featuredImageId); } @@ -201,7 +214,8 @@ public int hashCode() this.onShelf, this.price, this.stock, - this.featuredImageId + this.featuredImageId, + this.weight ); } diff --git a/shop/catalog/src/main/java/org/mayocat/shop/catalog/model/WeightUnit.java b/shop/catalog/src/main/java/org/mayocat/shop/catalog/model/WeightUnit.java new file mode 100644 index 000000000..ab0626c82 --- /dev/null +++ b/shop/catalog/src/main/java/org/mayocat/shop/catalog/model/WeightUnit.java @@ -0,0 +1,44 @@ +package org.mayocat.shop.catalog.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * @version $Id$ + */ +public enum WeightUnit +{ + KILOGRAM("kg"), + GRAM("g"), + OUNCE("oz"), + POUND("lb"); + + WeightUnit(String smybol) + { + this.symbol = smybol; + } + + private String symbol; + + public String getSymbol() + { + return symbol; + } + + @JsonValue + public String toJson() + { + return getSymbol(); + } + + @JsonCreator + public static WeightUnit fromJson(String text) + { + for (WeightUnit unit : values()) { + if (unit.getSymbol().equalsIgnoreCase(text)) { + return unit; + } + } + return null; + } +} diff --git a/shop/catalog/src/main/java/org/mayocat/shop/catalog/store/jdbi/mapper/ProductMapper.java b/shop/catalog/src/main/java/org/mayocat/shop/catalog/store/jdbi/mapper/ProductMapper.java index 27cc375d1..339faad7d 100644 --- a/shop/catalog/src/main/java/org/mayocat/shop/catalog/store/jdbi/mapper/ProductMapper.java +++ b/shop/catalog/src/main/java/org/mayocat/shop/catalog/store/jdbi/mapper/ProductMapper.java @@ -21,6 +21,7 @@ public Product map(int index, ResultSet resultSet, StatementContext statementCon product.setDescription(resultSet.getString("description")); product.setOnShelf(resultSet.getBoolean("on_shelf")); product.setPrice(resultSet.getBigDecimal("price")); + product.setWeight(resultSet.getBigDecimal("weight")); UUID featuredImageId = (UUID) resultSet.getObject("featured_image_id"); if (featuredImageId != null) { product.setFeaturedImageId(featuredImageId); diff --git a/shop/catalog/src/main/resources/mayoapp/dao/ProductDAO.sql.stg b/shop/catalog/src/main/resources/mayoapp/dao/ProductDAO.sql.stg index ff59e240c..bdc3e1462 100644 --- a/shop/catalog/src/main/resources/mayoapp/dao/ProductDAO.sql.stg +++ b/shop/catalog/src/main/resources/mayoapp/dao/ProductDAO.sql.stg @@ -1,7 +1,7 @@ group ProductDAO; createProduct() ::= << - INSERT INTO product (entity_id, position, title, model, on_shelf, description, price, stock, featured_image_id) + INSERT INTO product (entity_id, position, title, model, on_shelf, description, price, weight, stock, featured_image_id) VALUES (:product.id, :position, :product.title, @@ -9,6 +9,7 @@ createProduct() ::= << :product.onShelf, :product.description, :product.price, + :product.weight, :product.stock, :product.featuredImageId) >> @@ -20,6 +21,7 @@ updateProduct() ::= << description = :product.description, on_shelf = :product.onShelf, price = :product.price, + weight = :product.weight, stock = :product.stock, featured_image_id = :product.featuredImageId WHERE entity_id = :product.id diff --git a/shop/catalog/src/main/resources/mayoapp/migrations/V0078_0022__add_weight_to_product_table.sql b/shop/catalog/src/main/resources/mayoapp/migrations/V0078_0022__add_weight_to_product_table.sql new file mode 100644 index 000000000..a795b4ff7 --- /dev/null +++ b/shop/catalog/src/main/resources/mayoapp/migrations/V0078_0022__add_weight_to_product_table.sql @@ -0,0 +1 @@ +ALTER TABLE product ADD COLUMN weight numeric; \ No newline at end of file diff --git a/shop/client/src/main/resources/assets/client/javascripts/product.js b/shop/client/src/main/resources/assets/client/javascripts/product.js index 608a97956..bff158954 100644 --- a/shop/client/src/main/resources/assets/client/javascripts/product.js +++ b/shop/client/src/main/resources/assets/client/javascripts/product.js @@ -163,6 +163,10 @@ angular.module('product', ['ngResource']) } } }); + configurationService.get("catalog", function (catalogConfiguration) { + $scope.hasWeight = catalogConfiguration.products.weight; + $scope.weightUnit = catalogConfiguration.products.weightUnit; + }); } // Initialize existing product or new product diff --git a/shop/client/src/main/resources/assets/client/javascripts/settings.js b/shop/client/src/main/resources/assets/client/javascripts/settings.js index dd80bbdec..be8e02400 100644 --- a/shop/client/src/main/resources/assets/client/javascripts/settings.js +++ b/shop/client/src/main/resources/assets/client/javascripts/settings.js @@ -242,8 +242,9 @@ angular.module('settings', ['ngResource']) }); }); - configurationService.getSettings("catalog.currencies.main", function (mainCurrency) { - $scope.mainCurrency = mainCurrency.value; + configurationService.get("catalog", function(catalogSettings){ + $scope.mainCurrency = catalogSettings.currencies.main; + $scope.weightUnit = catalogSettings.products.weightUnit; }); $scope.loadCarriers(); diff --git a/shop/client/src/main/resources/assets/client/javascripts/shipping.js b/shop/client/src/main/resources/assets/client/javascripts/shipping.js index 7ed0b09cb..a360c1e4a 100644 --- a/shop/client/src/main/resources/assets/client/javascripts/shipping.js +++ b/shop/client/src/main/resources/assets/client/javascripts/shipping.js @@ -132,10 +132,11 @@ * duration, pricing, etc. */ return { - templateUrl: "partials/directives/carrierSummary.html?v=2", // Defeat browser cache http://git.io/6dPuFQ + templateUrl: "partials/directives/carrierSummary.html?v=3", // Defeat browser cache http://git.io/6dPuFQ scope: { carrier: '=', - mainCurrency: '=' + mainCurrency: '=', + weightUnit: '=' }, restrict: 'E' } diff --git a/shop/client/src/main/resources/assets/client/partials/directives/carrierSummary.html b/shop/client/src/main/resources/assets/client/partials/directives/carrierSummary.html index 8ef38381c..99a6a80e2 100644 --- a/shop/client/src/main/resources/assets/client/partials/directives/carrierSummary.html +++ b/shop/client/src/main/resources/assets/client/partials/directives/carrierSummary.html @@ -15,7 +15,7 @@

{{carrier.title}}

- {{rule.fromValue}} - {{rule.upToValue}} kg + {{rule.fromValue}} - {{rule.upToValue}} {{weightUnit}} {{rule.fromValue}} - {{rule.upToValue}} {{mainCurrency}} {{rule.price}} {{mainCurrency}} diff --git a/shop/client/src/main/resources/assets/client/partials/product.html b/shop/client/src/main/resources/assets/client/partials/product.html index 44e6946d7..03b997a20 100644 --- a/shop/client/src/main/resources/assets/client/partials/product.html +++ b/shop/client/src/main/resources/assets/client/partials/product.html @@ -155,6 +155,14 @@

Price

+
+

Weight

+ +
+ {{weightUnit}} +
+
+

Stock

diff --git a/shop/client/src/main/resources/assets/client/partials/settingsCatalog.html b/shop/client/src/main/resources/assets/client/partials/settingsCatalog.html index 9baa1a5aa..2dfcc168a 100644 --- a/shop/client/src/main/resources/assets/client/partials/settingsCatalog.html +++ b/shop/client/src/main/resources/assets/client/partials/settingsCatalog.html @@ -62,6 +62,34 @@

Catalog settings

ng-model="settings.catalog.products.stock.value"/>
+ + +
+ + +
+ +
+ + +
+ +
+
diff --git a/shop/client/src/main/resources/assets/client/partials/settingsShipping.html b/shop/client/src/main/resources/assets/client/partials/settingsShipping.html index b45f3fee5..79fd83884 100644 --- a/shop/client/src/main/resources/assets/client/partials/settingsShipping.html +++ b/shop/client/src/main/resources/assets/client/partials/settingsShipping.html @@ -33,7 +33,7 @@

Shipping settings

- + @@ -172,7 +172,7 @@

Pricing

From up to - kg + {{weightUnit}} {{mainCurrency}} @@ -189,7 +189,7 @@

Pricing

From up to - kg + {{weightUnit}} {{mainCurrency}} @@ -202,7 +202,7 @@

Pricing

- Additional kg + Additional {{weightUnit}}