shopizer-developers

Merge with master

1/12/2017 4:20:50 PM

Changes

Details

diff --git a/shopizer-canadapost/target/classes/META-INF/maven/com.shopizer/shopizer-shipping-canadapost-module/pom.properties b/shopizer-canadapost/target/classes/META-INF/maven/com.shopizer/shopizer-shipping-canadapost-module/pom.properties
index 2d3e607..a0e98b1 100644
--- a/shopizer-canadapost/target/classes/META-INF/maven/com.shopizer/shopizer-shipping-canadapost-module/pom.properties
+++ b/shopizer-canadapost/target/classes/META-INF/maven/com.shopizer/shopizer-shipping-canadapost-module/pom.properties
@@ -1,5 +1,5 @@
 #Generated by Maven Integration for Eclipse
-#Wed Jan 11 12:49:06 EST 2017
+#Thu Jan 12 13:16:17 EST 2017
 version=2.0.5-SNAPSHOT
 groupId=com.shopizer
 m2e.projectName=shopizer-canadapost
diff --git a/shopizer-shipping-distance-module/target/classes/META-INF/maven/com.shopizer/shopizer-shipping-distance-processor/pom.properties b/shopizer-shipping-distance-module/target/classes/META-INF/maven/com.shopizer/shopizer-shipping-distance-processor/pom.properties
index 691be56..c6134c5 100644
--- a/shopizer-shipping-distance-module/target/classes/META-INF/maven/com.shopizer/shopizer-shipping-distance-processor/pom.properties
+++ b/shopizer-shipping-distance-module/target/classes/META-INF/maven/com.shopizer/shopizer-shipping-distance-processor/pom.properties
@@ -1,5 +1,5 @@
 #Generated by Maven Integration for Eclipse
-#Wed Jan 11 12:49:07 EST 2017
+#Thu Jan 12 13:16:18 EST 2017
 version=2.0.5-SNAPSHOT
 groupId=com.shopizer
 m2e.projectName=shopizer-shipping-distance-processor
diff --git a/sm-core/.classpath b/sm-core/.classpath
index fc5f96c..8c4866c 100644
--- a/sm-core/.classpath
+++ b/sm-core/.classpath
@@ -32,5 +32,7 @@
 			<attribute name="maven.pomderived" value="true"/>
 		</attributes>
 	</classpathentry>
+	<classpathentry kind="src" path="/sm-core-modules"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/sm-core-model"/>
 	<classpathentry kind="output" path="target/classes"/>
 </classpath>
diff --git a/sm-core/src/main/java/com/salesmanager/core/business/constants/Constants.java b/sm-core/src/main/java/com/salesmanager/core/business/constants/Constants.java
index c2747c8..20c137f 100644
--- a/sm-core/src/main/java/com/salesmanager/core/business/constants/Constants.java
+++ b/sm-core/src/main/java/com/salesmanager/core/business/constants/Constants.java
@@ -30,6 +30,7 @@ public class Constants {
 	public final static String OT_HANDLING_MODULE_CODE = "handling";
 	public final static String OT_TAX_MODULE_CODE = "tax";
 	public final static String OT_REFUND_MODULE_CODE = "refund";
+	public final static String OT_DISCOUNT_TITLE = "order.total.discount";
 	
 	public final static Locale DEFAULT_LOCALE = Locale.US;
 	public final static Currency DEFAULT_CURRENCY = Currency.getInstance(Locale.US);
diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/ManufacturerShippingCodeOrderTotalModuleImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/ManufacturerShippingCodeOrderTotalModuleImpl.java
new file mode 100644
index 0000000..28822e9
--- /dev/null
+++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/ManufacturerShippingCodeOrderTotalModuleImpl.java
@@ -0,0 +1,143 @@
+package com.salesmanager.core.business.modules.order.total;
+
+import java.math.BigDecimal;
+
+import org.apache.commons.lang.Validate;
+import org.drools.KnowledgeBase;
+import org.drools.runtime.StatelessKnowledgeSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.salesmanager.core.business.constants.Constants;
+import com.salesmanager.core.business.services.catalog.product.PricingService;
+import com.salesmanager.core.model.catalog.product.Product;
+import com.salesmanager.core.model.catalog.product.price.FinalPrice;
+import com.salesmanager.core.model.customer.Customer;
+import com.salesmanager.core.model.merchant.MerchantStore;
+import com.salesmanager.core.model.order.OrderSummary;
+import com.salesmanager.core.model.order.OrderTotal;
+import com.salesmanager.core.model.order.OrderTotalType;
+import com.salesmanager.core.model.shoppingcart.ShoppingCartItem;
+import com.salesmanager.core.modules.order.total.OrderTotalPostProcessorModule;
+
+
+
+
+/**
+ * Add variation to the OrderTotal
+ * This has to be defined in shopizer-core-ordertotal-processors
+ * @author carlsamson
+ *
+ */
+public class ManufacturerShippingCodeOrderTotalModuleImpl implements OrderTotalPostProcessorModule {
+	
+	private static final Logger LOGGER = LoggerFactory.getLogger(ManufacturerShippingCodeOrderTotalModuleImpl.class);
+	
+	private String name;
+	private String code;
+	
+	private StatelessKnowledgeSession orderTotalMethodDecision;//injected from xml file
+	
+	private KnowledgeBase kbase;//injected from xml file
+	
+
+	PricingService pricingService;
+	
+
+	
+	public PricingService getPricingService() {
+		return pricingService;
+	}
+
+	public void setPricingService(PricingService pricingService) {
+		this.pricingService = pricingService;
+	}
+
+	@Override
+	public OrderTotal caculateProductPiceVariation(final OrderSummary summary, ShoppingCartItem shoppingCartItem, Product product, Customer customer, MerchantStore store)
+			throws Exception {
+
+		
+		Validate.notNull(product,"product must not be null");
+		Validate.notNull(product.getManufacturer(),"product manufacturer must not be null");
+		
+		//requires shipping summary, otherwise return null
+		if(summary.getShippingSummary()==null) {
+			return null;
+		}
+
+		OrderTotalInputParameters inputParameters = new OrderTotalInputParameters();
+		inputParameters.setItemManufacturerCode(product.getManufacturer().getCode());
+		
+		
+		inputParameters.setShippingMethod(summary.getShippingSummary().getShippingOptionCode());
+		
+		LOGGER.debug("Setting input parameters " + inputParameters.toString());
+		orderTotalMethodDecision.execute(inputParameters);
+		
+		
+		LOGGER.debug("Applied discount " + inputParameters.getDiscount());
+		
+		OrderTotal orderTotal = null;
+		if(inputParameters.getDiscount() != null) {
+				orderTotal = new OrderTotal();
+				orderTotal.setOrderTotalCode(Constants.OT_DISCOUNT_TITLE);
+				orderTotal.setOrderTotalType(OrderTotalType.SUBTOTAL);
+				orderTotal.setTitle(Constants.OT_SUBTOTAL_MODULE_CODE);
+				
+				//calculate discount that will be added as a negative value
+				FinalPrice productPrice = pricingService.calculateProductPrice(product);
+				
+				Double discount = inputParameters.getDiscount();
+				BigDecimal reduction = productPrice.getFinalPrice().multiply(new BigDecimal(discount));
+				reduction = reduction.multiply(new BigDecimal(shoppingCartItem.getQuantity()));
+				
+				orderTotal.setValue(reduction);
+		}
+			
+		
+		
+		return orderTotal;
+
+	}
+	
+	public KnowledgeBase getKbase() {
+		return kbase;
+	}
+
+
+	public void setKbase(KnowledgeBase kbase) {
+		this.kbase = kbase;
+	}
+
+	public StatelessKnowledgeSession getOrderTotalMethodDecision() {
+		return orderTotalMethodDecision;
+	}
+
+	public void setOrderTotalMethodDecision(StatelessKnowledgeSession orderTotalMethodDecision) {
+		this.orderTotalMethodDecision = orderTotalMethodDecision;
+	}
+
+	@Override
+	public String getName() {
+		return name;
+	}
+
+	@Override
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	@Override
+	public String getCode() {
+		return code;
+	}
+
+	@Override
+	public void setCode(String code) {
+		this.code = code;
+	}
+
+
+
+}
diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/OrderTotalInputParameters.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/OrderTotalInputParameters.java
new file mode 100644
index 0000000..2b9f72c
--- /dev/null
+++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/OrderTotalInputParameters.java
@@ -0,0 +1,61 @@
+package com.salesmanager.core.business.modules.order.total;
+
+/**
+ * Input itm to be added to drules engine
+ * @author carlsamson
+ *
+ */
+public class OrderTotalInputParameters {
+	
+	private Double discount;//output value set by engine
+	private String totalCode;//output value set by engine
+	
+	//input parameters
+	private long productId;
+	private String itemManufacturerCode;
+	private String itemCategoryCode;
+	private String shippingMethod;
+	
+	//might add variation based on other objects such as Customer
+	
+	public Double getDiscount() {
+		return discount;
+	}
+	public void setDiscount(Double discount) {
+		this.discount = discount;
+	}
+	public String getTotalCode() {
+		return totalCode;
+	}
+	public void setTotalCode(String totalCode) {
+		this.totalCode = totalCode;
+	}
+	public String getItemManufacturerCode() {
+		return itemManufacturerCode;
+	}
+	public void setItemManufacturerCode(String itemManufacturerCode) {
+		this.itemManufacturerCode = itemManufacturerCode;
+	}
+	public String getItemCategoryCode() {
+		return itemCategoryCode;
+	}
+	public void setItemCategoryCode(String itemCategoryCode) {
+		this.itemCategoryCode = itemCategoryCode;
+	}
+	public long getProductId() {
+		return productId;
+	}
+	public void setProductId(long productId) {
+		this.productId = productId;
+	}
+	public String getShippingMethod() {
+		return shippingMethod;
+	}
+	public void setShippingMethod(String shippingMethod) {
+		this.shippingMethod = shippingMethod;
+	}
+
+	
+
+
+}
diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/ProductRepositoryCustom.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/ProductRepositoryCustom.java
index 944c667..1b1b8c5 100644
--- a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/ProductRepositoryCustom.java
+++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/ProductRepositoryCustom.java
@@ -11,7 +11,6 @@ import com.salesmanager.core.model.merchant.MerchantStore;
 import com.salesmanager.core.model.reference.language.Language;
 import com.salesmanager.core.model.tax.taxclass.TaxClass;
 
-//@NoRepositoryBean
 public interface ProductRepositoryCustom {
 	
 	
diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/ProductService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/ProductService.java
index 6eb78ea..4242114 100644
--- a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/ProductService.java
+++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/ProductService.java
@@ -49,6 +49,7 @@ public interface ProductService extends SalesManagerEntityService<Long, Product>
 	 * @return
 	 */
 	Product getByCode(String productCode, Language language);
+
 	
 }
 	
diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/ProductServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/ProductServiceImpl.java
index 7294b29..a4730e9 100644
--- a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/ProductServiceImpl.java
+++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/ProductServiceImpl.java
@@ -317,175 +317,6 @@ public class ProductServiceImpl extends SalesManagerEntityServiceImpl<Long, Prod
 
 
 	}
-	
-	/*	@Override	
-	public void saveOrUpdate(Product product) throws ServiceException {
 
-		LOGGER.debug("Save or update product ");
-		Validate.notNull(product,"product cannot be null");
-		Validate.notNull(product.getAvailabilities(),"product must have at least one availability");
-		Validate.notEmpty(product.getAvailabilities(),"product must have at least one availability");
 
-		//List of original availabilities
-		Set<ProductAvailability> originalAvailabilities = null;
-		
-		//List of original attributes
-		Set<ProductAttribute> originalAttributes = null;
-		
-		//List of original reviews
-		Set<ProductRelationship> originalRelationships = null;
-		
-		//List of original images
-		Set<ProductImage> originalProductImages = null;
-		
-		
-		if(product.getId()!=null && product.getId()>0) {
-			LOGGER.debug("Update product",product.getId());
-			//get original product
-			Product originalProduct = this.getById(product.getId());
-			originalAvailabilities = originalProduct.getAvailabilities();
-			originalAttributes = originalProduct.getAttributes();
-			originalRelationships = originalProduct.getRelationships();
-			originalProductImages = originalProduct.getImages();
-		} else {
-			
-			Set<ProductDescription> productDescriptions = product.getDescriptions();
-			product.setDescriptions(null);
-			
-			super.create(product);
-			
-			for(ProductDescription productDescription : productDescriptions) {
-				addProductDescription(product,productDescription);
-			}
-		}
-
-		
-		LOGGER.debug("Creating availabilities");
-		
-		//get availabilities
-		Set<ProductAvailability> availabilities = product.getAvailabilities();
-		List<Long> newAvailabilityIds = new ArrayList<Long>();
-		if(availabilities!=null && availabilities.size()>0) {
-			for(ProductAvailability availability : availabilities) {
-				availability.setProduct(product);
-				productAvailabilityService.saveOrUpdate(availability);
-				newAvailabilityIds.add(availability.getId());
-				//check prices
-				Set<ProductPrice> prices = availability.getPrices();
-				if(prices!=null && prices.size()>0) {
-
-					for(ProductPrice price : prices) {
-						price.setProductAvailability(availability);
-						productPriceService.saveOrUpdate(price);
-					}
-				}	
-			}
-		}
-		
-		//cleanup old availability
-		if(originalAvailabilities!=null) {
-			for(ProductAvailability availability : originalAvailabilities) {
-				if(!newAvailabilityIds.contains(availability.getId())) {
-					productAvailabilityService.delete(availability);
-				}
-			}
-		}
-		
-		LOGGER.debug("Creating attributes");
-		List<Long> newAttributesIds = new ArrayList<Long>();
-		if(product.getAttributes()!=null && product.getAttributes().size()>0) {
-			Set<ProductAttribute> attributes = product.getAttributes();
-			for(ProductAttribute attribute : attributes) {
-				attribute.setProduct(product);
-				ProductOption option = attribute.getProductOption();
-				if(option!=null) {
-					productOptionService.saveOrUpdate(option);
-				}
-				ProductOptionValue optionValue = attribute.getProductOptionValue();
-				if(optionValue != null) {
-					productOptionValueService.saveOrUpdate(optionValue);
-				}
-
-				productAttributeService.saveOrUpdate(attribute);
-				newAttributesIds.add(attribute.getId());
-			}
-		}
-		
-		//cleanup old attributes
-		if(originalAttributes!=null) {
-			for(ProductAttribute attribute : originalAttributes) {
-				if(!newAttributesIds.contains(attribute.getId())) {
-					productAttributeService.delete(attribute);
-				}
-			}
-		}
-		
-		
-		LOGGER.debug("Creating relationships");
-		List<Long> newRelationshipIds = new ArrayList<Long>();
-		if(product.getRelationships()!=null && product.getRelationships().size()>0) {
-			Set<ProductRelationship> relationships = product.getRelationships();
-			for(ProductRelationship relationship : relationships) {
-				relationship.setProduct(product);
-				productRelationshipService.saveOrUpdate(relationship);
-				newRelationshipIds.add(relationship.getId());
-			}
-		}
-		//cleanup old relationships
-		if(originalRelationships!=null) {
-			for(ProductRelationship relationship : originalRelationships) {
-				if(!newRelationshipIds.contains(relationship.getId())) {
-					productRelationshipService.delete(relationship);
-				}
-			}
-		}
-		
-		
-		LOGGER.debug("Creating images");
-
-		//get images
-		List<Long> newImageIds = new ArrayList<Long>();
-		Set<ProductImage> images = product.getImages();
-		if(images!=null && images.size()>0) {
-			for(ProductImage image : images) {
-				if(image.getImage()!=null && (image.getId()==null || image.getId()==0L)) {
-					image.setProduct(product);
-					
-			        InputStream inputStream = image.getImage();
-			        ImageContentFile cmsContentImage = new ImageContentFile();
-			        cmsContentImage.setFileName( image.getProductImage() );
-			        cmsContentImage.setFile( inputStream );
-			        cmsContentImage.setFileContentType(FileContentType.PRODUCT);
-					
-					
-					productImageService.addProductImage(product, image, cmsContentImage);
-					newImageIds.add(image.getId());
-				} else {
-					productImageService.update(image);
-					newImageIds.add(image.getId());
-				}
-			}
-		}
-		
-		//cleanup old images
-		if(originalProductImages!=null) {
-			for(ProductImage image : originalProductImages) {
-				if(!newImageIds.contains(image.getId())) {
-					productImageService.delete(image);
-				}
-			}
-		}
-		
-		if(product.getId()!=null && product.getId()>0) {
-			super.update(product);
-		}
-		
-		searchService.index(product.getMerchantStore(), product);
-
-	}*/
-	
-	
-
-
-	
 }
diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/order/OrderServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/order/OrderServiceImpl.java
index ce3a2e3..ed96dbc 100644
--- a/sm-core/src/main/java/com/salesmanager/core/business/services/order/OrderServiceImpl.java
+++ b/sm-core/src/main/java/com/salesmanager/core/business/services/order/OrderServiceImpl.java
@@ -6,6 +6,7 @@ import com.salesmanager.core.business.modules.order.InvoiceModule;
 import com.salesmanager.core.business.repositories.order.OrderRepository;
 import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl;
 import com.salesmanager.core.business.services.customer.CustomerService;
+import com.salesmanager.core.business.services.order.ordertotal.OrderTotalService;
 import com.salesmanager.core.business.services.payments.PaymentService;
 import com.salesmanager.core.business.services.payments.TransactionService;
 import com.salesmanager.core.business.services.shipping.ShippingService;
@@ -61,6 +62,9 @@ public class OrderServiceImpl  extends SalesManagerEntityServiceImpl<Long, Order
     
     @Inject
     private TransactionService transactionService;
+    
+    @Inject
+    private OrderTotalService orderTotalService;
 
     private final OrderRepository orderRepository;
 
@@ -185,7 +189,7 @@ public class OrderServiceImpl  extends SalesManagerEntityServiceImpl<Long, Order
                             if(itemSubTotal==null) {
                                 itemSubTotal = new OrderTotal();
                                 itemSubTotal.setModule(Constants.OT_ITEM_PRICE_MODULE_CODE);
-                                itemSubTotal.setText(Constants.OT_ITEM_PRICE_MODULE_CODE);
+                                //itemSubTotal.setText(Constants.OT_ITEM_PRICE_MODULE_CODE);
                                 itemSubTotal.setTitle(Constants.OT_ITEM_PRICE_MODULE_CODE);
                                 itemSubTotal.setOrderTotalCode(price.getProductPrice().getCode());
                                 itemSubTotal.setOrderTotalType(OrderTotalType.PRODUCT);
@@ -210,6 +214,25 @@ public class OrderServiceImpl  extends SalesManagerEntityServiceImpl<Long, Order
             }
 
         }
+        
+        //only in order page, otherwise invokes too many processing
+        if(OrderSummaryType.ORDERTOTAL.name().equals(summary.getOrderSummaryType().name())) {
+
+	        //Post processing order total variation modules for sub total calculation - drools, custom modules
+	        //may affect the sub total
+	        OrderTotalVariation orderTotalVariation = orderTotalService.findOrderTotalVariation(summary, customer, store, language);
+	        
+	        int currentCount = 10;
+	        
+	        if(CollectionUtils.isNotEmpty(orderTotalVariation.getVariations())) {
+	        	for(OrderTotal variation : orderTotalVariation.getVariations()) {
+	        		variation.setSortOrder(currentCount++);
+	        		orderTotals.add(variation);
+	        		subTotal = subTotal.subtract(variation.getValue());
+	        	}
+	        }
+        
+        }
 
 
         totalSummary.setSubTotal(subTotal);
@@ -220,13 +243,10 @@ public class OrderServiceImpl  extends SalesManagerEntityServiceImpl<Long, Order
         orderTotalSubTotal.setOrderTotalType(OrderTotalType.SUBTOTAL);
         orderTotalSubTotal.setOrderTotalCode("order.total.subtotal");
         orderTotalSubTotal.setTitle(Constants.OT_SUBTOTAL_MODULE_CODE);
-        orderTotalSubTotal.setText("order.total.subtotal");
+        //orderTotalSubTotal.setText("order.total.subtotal");
         orderTotalSubTotal.setSortOrder(5);
         orderTotalSubTotal.setValue(subTotal);
-
-        //TODO autowire a list of post processing modules for price calculation - drools, custom modules
-        //may affect the sub total
-
+        
         orderTotals.add(orderTotalSubTotal);
 
 
@@ -239,8 +259,8 @@ public class OrderServiceImpl  extends SalesManagerEntityServiceImpl<Long, Order
 	            shippingSubTotal.setOrderTotalType(OrderTotalType.SHIPPING);
 	            shippingSubTotal.setOrderTotalCode("order.total.shipping");
 	            shippingSubTotal.setTitle(Constants.OT_SHIPPING_MODULE_CODE);
-	            shippingSubTotal.setText("order.total.shipping");
-	            shippingSubTotal.setSortOrder(10);
+	            //shippingSubTotal.setText("order.total.shipping");
+	            shippingSubTotal.setSortOrder(100);
 	
 	            orderTotals.add(shippingSubTotal);
 
@@ -261,8 +281,8 @@ public class OrderServiceImpl  extends SalesManagerEntityServiceImpl<Long, Order
                     handlingubTotal.setOrderTotalType(OrderTotalType.HANDLING);
                     handlingubTotal.setOrderTotalCode("order.total.handling");
                     handlingubTotal.setTitle(Constants.OT_HANDLING_MODULE_CODE);
-                    handlingubTotal.setText("order.total.handling");
-                    handlingubTotal.setSortOrder(12);
+                    //handlingubTotal.setText("order.total.handling");
+                    handlingubTotal.setSortOrder(120);
                     handlingubTotal.setValue(summary.getShippingSummary().getHandling());
                     orderTotals.add(handlingubTotal);
                     grandTotal=grandTotal.add(summary.getShippingSummary().getHandling());
@@ -275,7 +295,7 @@ public class OrderServiceImpl  extends SalesManagerEntityServiceImpl<Long, Order
         if(taxes!=null && taxes.size()>0) {
         	BigDecimal totalTaxes = new BigDecimal(0);
         	totalTaxes.setScale(2, RoundingMode.HALF_UP);
-            int taxCount = 20;
+            int taxCount = 200;
             for(TaxItem tax : taxes) {
 
                 OrderTotal taxLine = new OrderTotal();
@@ -304,8 +324,8 @@ public class OrderServiceImpl  extends SalesManagerEntityServiceImpl<Long, Order
         orderTotal.setOrderTotalType(OrderTotalType.TOTAL);
         orderTotal.setOrderTotalCode("order.total.total");
         orderTotal.setTitle(Constants.OT_TOTAL_MODULE_CODE);
-        orderTotal.setText("order.total.total");
-        orderTotal.setSortOrder(300);
+        //orderTotal.setText("order.total.total");
+        orderTotal.setSortOrder(500);
         orderTotal.setValue(grandTotal);
         orderTotals.add(orderTotal);
 
@@ -349,11 +369,9 @@ public class OrderServiceImpl  extends SalesManagerEntityServiceImpl<Long, Order
 
     private OrderTotalSummary caculateShoppingCart( final ShoppingCart shoppingCart, final Customer customer, final MerchantStore store, final Language language) throws Exception {
 
-        
-    	
-    	
-    	
+
     	OrderSummary orderSummary = new OrderSummary();
+    	orderSummary.setOrderSummaryType(OrderSummaryType.SHOPPINGCART);
     	
     	List<ShoppingCartItem> itemsSet = new ArrayList<ShoppingCartItem>(shoppingCart.getLineItems());
     	orderSummary.setProducts(itemsSet);
diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/order/ordertotal/OrderTotalService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/order/ordertotal/OrderTotalService.java
new file mode 100644
index 0000000..0a628af
--- /dev/null
+++ b/sm-core/src/main/java/com/salesmanager/core/business/services/order/ordertotal/OrderTotalService.java
@@ -0,0 +1,19 @@
+package com.salesmanager.core.business.services.order.ordertotal;
+
+import com.salesmanager.core.model.customer.Customer;
+import com.salesmanager.core.model.merchant.MerchantStore;
+import com.salesmanager.core.model.order.OrderSummary;
+import com.salesmanager.core.model.order.OrderTotalVariation;
+import com.salesmanager.core.model.reference.language.Language;
+
+/**
+ * Additional dynamic order total calculation
+ * from the rules engine and other modules
+ * @author carlsamson
+ *
+ */
+public interface OrderTotalService {
+	
+	OrderTotalVariation findOrderTotalVariation(final OrderSummary summary, final Customer customer, final MerchantStore store, final Language language) throws Exception;
+
+}
diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/order/ordertotal/OrderTotalServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/order/ordertotal/OrderTotalServiceImpl.java
new file mode 100644
index 0000000..69a5635
--- /dev/null
+++ b/sm-core/src/main/java/com/salesmanager/core/business/services/order/ordertotal/OrderTotalServiceImpl.java
@@ -0,0 +1,76 @@
+package com.salesmanager.core.business.services.order.ordertotal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.salesmanager.core.business.services.catalog.product.ProductService;
+import com.salesmanager.core.business.services.reference.language.LanguageService;
+import com.salesmanager.core.model.catalog.product.Product;
+import com.salesmanager.core.model.customer.Customer;
+import com.salesmanager.core.model.merchant.MerchantStore;
+import com.salesmanager.core.model.order.OrderSummary;
+import com.salesmanager.core.model.order.OrderTotal;
+import com.salesmanager.core.model.order.OrderTotalVariation;
+import com.salesmanager.core.model.order.RebatesOrderTotalVariation;
+import com.salesmanager.core.model.reference.language.Language;
+import com.salesmanager.core.model.shoppingcart.ShoppingCartItem;
+import com.salesmanager.core.modules.order.total.OrderTotalPostProcessorModule;
+
+@Service("OrderTotalService")
+public class OrderTotalServiceImpl implements OrderTotalService {
+	
+	@Autowired
+	@Resource(name="orderTotalsPostProcessors")
+	List<OrderTotalPostProcessorModule> orderTotalPostProcessors;
+	
+	@Inject
+	private ProductService productService;
+	
+	@Inject
+	private LanguageService languageService;
+
+	@Override
+	public OrderTotalVariation findOrderTotalVariation(OrderSummary summary, Customer customer, MerchantStore store, Language language)
+			throws Exception {
+	
+		RebatesOrderTotalVariation variation = new RebatesOrderTotalVariation();
+		
+		List<OrderTotal> totals = null;
+		
+		if(orderTotalPostProcessors != null) {
+			for(OrderTotalPostProcessorModule module : orderTotalPostProcessors) {
+				//TODO check if the module is enabled from the Admin
+				
+				List<ShoppingCartItem> items = summary.getProducts();
+				for(ShoppingCartItem item : items) {
+					
+					Long productId = item.getProductId();
+					Product product = productService.getProductForLocale(productId, language, languageService.toLocale(language));
+					
+					OrderTotal orderTotal = module.caculateProductPiceVariation(summary, item, product, customer, store);
+					if(orderTotal==null) {
+						continue;
+					}
+					if(totals==null) {
+						totals = new ArrayList<OrderTotal>();
+						variation.setVariations(totals);
+					}
+					
+					//if product is null it will be catched when invoking the module
+					orderTotal.setText(product.getProductDescription().getName());
+					variation.getVariations().add(orderTotal);	
+				}
+			}
+		}
+		
+		
+		return variation;
+	}
+
+}
diff --git a/sm-core/src/main/resources/rules/manufacturer-shipping-ordertotal-rules.xls b/sm-core/src/main/resources/rules/manufacturer-shipping-ordertotal-rules.xls
new file mode 100644
index 0000000..b85fa31
Binary files /dev/null and b/sm-core/src/main/resources/rules/manufacturer-shipping-ordertotal-rules.xls differ
diff --git a/sm-core/src/main/resources/spring/processors/shopizer-core-ordertotal-processors.xml b/sm-core/src/main/resources/spring/processors/shopizer-core-ordertotal-processors.xml
new file mode 100644
index 0000000..4b98cfa
--- /dev/null
+++ b/sm-core/src/main/resources/spring/processors/shopizer-core-ordertotal-processors.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:util="http://www.springframework.org/schema/util"
+	xsi:schemaLocation="
+	http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
+
+		<!-- 
+		     Order total calculation post-processors 
+			 Using decision tables to calculate potential
+			 discounts according to items, shipping etc...
+		-->
+		<util:list id="orderTotalsPostProcessors" value-type="com.salesmanager.core.modules.order.total.OrderTotalPostProcessorModule">
+			<!-- From rules -->
+			<ref bean="manufacturerShippingCodeOrderTotalModule"/>
+		</util:list>
+	
+
+
+	
+</beans>
\ No newline at end of file
diff --git a/sm-core/src/main/resources/spring/shopizer-core-context.xml b/sm-core/src/main/resources/spring/shopizer-core-context.xml
index 7fe2ac8..6d54889 100644
--- a/sm-core/src/main/resources/spring/shopizer-core-context.xml
+++ b/sm-core/src/main/resources/spring/shopizer-core-context.xml
@@ -32,6 +32,8 @@
   <beans:import resource="classpath:/spring/shopizer-core-modules.xml" />
   <!-- shipping pre processors -->
   <beans:import resource="classpath:/spring/processors/shopizer-core-shipping-processors.xml" />
+  <!-- order total pre processors -->
+  <beans:import resource="classpath:/spring/processors/shopizer-core-ordertotal-processors.xml" />
   <!-- rules -->
   <beans:import resource="classpath:/spring/shopizer-core-rules.xml" />
   <!-- search -->
diff --git a/sm-core/src/main/resources/spring/shopizer-core-rules.xml b/sm-core/src/main/resources/spring/shopizer-core-rules.xml
index 025f103..33276be 100644
--- a/sm-core/src/main/resources/spring/shopizer-core-rules.xml
+++ b/sm-core/src/main/resources/spring/shopizer-core-rules.xml
@@ -39,5 +39,23 @@
 		<beans:property name="shippingPriceRule" ref="shippingPriceRule" />
 		<beans:property name="kbase" ref="shippingPriceDecisionBase" />
 	</beans:bean>
+	
+		<!-- placeholder for order-total variation based on product manufacturer -->
+	
+	<!-- Basic Manufacturer Shipping Method rules -->
+	<drools:kbase id="manufacturerShippingMethodOrderTotalBase">
+        <drools:resources>
+            <drools:resource type="DTABLE" source="classpath:rules/manufacturer-shipping-ordertotal-rules.xls"/>
+        </drools:resources>
+    </drools:kbase>
+	
+	<drools:ksession id="manufacturerShippingMethodOrderTotalDecision" name="manufacturerShippingMethodOrderTotalDecision" type="stateless" kbase="manufacturerShippingMethodOrderTotalBase"/>
+ 
+  	<!-- concrete module for the above kbase -->
+  	<beans:bean id="manufacturerShippingCodeOrderTotalModule" class="com.salesmanager.core.business.modules.order.total.ManufacturerShippingCodeOrderTotalModuleImpl">
+		<beans:property name="orderTotalMethodDecision" ref="manufacturerShippingMethodOrderTotalDecision" />
+		<beans:property name="kbase" ref="manufacturerShippingMethodOrderTotalBase" />
+		<beans:property name="pricingService" ref="pricingService" />
+	</beans:bean>
 
 </beans:beans>
\ No newline at end of file
diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/Product.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/Product.java
index 790d36d..94fa0fe 100644
--- a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/Product.java
+++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/Product.java
@@ -65,10 +65,10 @@ public class Product extends SalesManagerEntity<Long, Product> implements Audita
 	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "product")
 	private Set<ProductDescription> descriptions = new HashSet<ProductDescription>();
 	
-	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="product", orphanRemoval = true)
+	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="product")
 	private Set<ProductAvailability> availabilities = new HashSet<ProductAvailability>();
 
-	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "product", orphanRemoval = true)
+	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "product")
 	private Set<ProductAttribute> attributes = new HashSet<ProductAttribute>();
 	
 	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE, mappedBy = "product")//cascade is set to remove because product save requires logic to create physical image first and then save the image id in the database, cannot be done in cascade
diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderSummary.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderSummary.java
index 483373c..4e24643 100644
--- a/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderSummary.java
+++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderSummary.java
@@ -20,6 +20,7 @@ public class OrderSummary implements Serializable {
 	/**
 	 * 
 	 */
+	private OrderSummaryType orderSummaryType = OrderSummaryType.ORDERTOTAL;
 	private static final long serialVersionUID = 1L;
 	private ShippingSummary shippingSummary;
 	private List<ShoppingCartItem> products = new ArrayList<ShoppingCartItem>();
@@ -36,5 +37,11 @@ public class OrderSummary implements Serializable {
 	public ShippingSummary getShippingSummary() {
 		return shippingSummary;
 	}
+	public OrderSummaryType getOrderSummaryType() {
+		return orderSummaryType;
+	}
+	public void setOrderSummaryType(OrderSummaryType orderSummaryType) {
+		this.orderSummaryType = orderSummaryType;
+	}
 
 }
diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderSummaryType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderSummaryType.java
new file mode 100644
index 0000000..5b16f80
--- /dev/null
+++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderSummaryType.java
@@ -0,0 +1,7 @@
+package com.salesmanager.core.model.order;
+
+public enum OrderSummaryType {
+	
+	SHOPPINGCART, ORDERTOTAL
+
+}
diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotalVariation.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotalVariation.java
new file mode 100644
index 0000000..90152b0
--- /dev/null
+++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotalVariation.java
@@ -0,0 +1,23 @@
+package com.salesmanager.core.model.order;
+
+import java.util.List;
+
+/**
+ * Contains a list of negative OrderTotal variation
+ * that will be shown in the order summary
+ * @author carlsamson
+ *
+ */
+public abstract class OrderTotalVariation {
+	
+	List<OrderTotal> variations = null;
+
+	public List<OrderTotal> getVariations() {
+		return variations;
+	}
+
+	public void setVariations(List<OrderTotal> variations) {
+		this.variations = variations;
+	}
+
+}
diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/RebatesOrderTotalVariation.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/RebatesOrderTotalVariation.java
new file mode 100644
index 0000000..e162da8
--- /dev/null
+++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/RebatesOrderTotalVariation.java
@@ -0,0 +1,12 @@
+package com.salesmanager.core.model.order;
+
+
+/**
+ * Implementation of rebates calculated used in the ordertotal calculation
+ * engine
+ * @author carlsamson
+ *
+ */
+public class RebatesOrderTotalVariation extends OrderTotalVariation {
+
+}
diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingSummary.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingSummary.java
index 36395bd..7f16d06 100644
--- a/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingSummary.java
+++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingSummary.java
@@ -20,6 +20,7 @@ public class ShippingSummary implements Serializable {
 	private BigDecimal handling;
 	private String shippingModule;
 	private String shippingOption;
+	private String shippingOptionCode;
 	private boolean freeShipping;
 	private boolean taxOnShipping;
 	
@@ -68,5 +69,11 @@ public class ShippingSummary implements Serializable {
 	public void setDeliveryAddress(Delivery deliveryAddress) {
 		this.deliveryAddress = deliveryAddress;
 	}
+	public String getShippingOptionCode() {
+		return shippingOptionCode;
+	}
+	public void setShippingOptionCode(String shippingOptionCode) {
+		this.shippingOptionCode = shippingOptionCode;
+	}
 
 }
diff --git a/sm-core-modules/src/main/java/com/salesmanager/core/modules/Module.java b/sm-core-modules/src/main/java/com/salesmanager/core/modules/Module.java
new file mode 100644
index 0000000..079f7a6
--- /dev/null
+++ b/sm-core-modules/src/main/java/com/salesmanager/core/modules/Module.java
@@ -0,0 +1,15 @@
+package com.salesmanager.core.modules;
+
+/**
+ * Root interface for all modules
+ * @author carlsamson
+ *
+ */
+public interface Module {
+	
+	String getName();
+	void setName(String name);
+	String getCode();
+	void setCode(String code);
+
+}
diff --git a/sm-core-modules/src/main/java/com/salesmanager/core/modules/order/total/OrderTotalPostProcessorModule.java b/sm-core-modules/src/main/java/com/salesmanager/core/modules/order/total/OrderTotalPostProcessorModule.java
new file mode 100644
index 0000000..0a3c699
--- /dev/null
+++ b/sm-core-modules/src/main/java/com/salesmanager/core/modules/order/total/OrderTotalPostProcessorModule.java
@@ -0,0 +1,34 @@
+package com.salesmanager.core.modules.order.total;
+
+
+
+import com.salesmanager.core.model.catalog.product.Product;
+import com.salesmanager.core.model.customer.Customer;
+import com.salesmanager.core.model.merchant.MerchantStore;
+import com.salesmanager.core.model.order.OrderSummary;
+import com.salesmanager.core.model.order.OrderTotal;
+import com.salesmanager.core.model.shoppingcart.ShoppingCartItem;
+import com.salesmanager.core.modules.Module;
+
+/**
+ * Calculates order total based on specific
+ * modules implementation
+ * @author carlsamson
+ *
+ */
+public interface OrderTotalPostProcessorModule extends Module {
+	
+	   /**
+	    * Uses the OrderSummary and external tools for applying if necessary
+	    * variations on the OrderTotal calculation.
+	    * @param orderSummary
+	    * @param shoppingCartItem
+	    * @param product
+	    * @param customer
+	    * @param store
+	    * @return
+	    * @throws Exception
+	    */
+	   OrderTotal caculateProductPiceVariation(final OrderSummary summary, final ShoppingCartItem shoppingCartItem, final Product product, final Customer customer, final MerchantStore store) throws Exception;
+
+}
diff --git a/sm-search/target/classes/META-INF/maven/com.shopizer/sm-search/pom.properties b/sm-search/target/classes/META-INF/maven/com.shopizer/sm-search/pom.properties
index d573d2a..1ba884b 100644
--- a/sm-search/target/classes/META-INF/maven/com.shopizer/sm-search/pom.properties
+++ b/sm-search/target/classes/META-INF/maven/com.shopizer/sm-search/pom.properties
@@ -1,5 +1,5 @@
 #Generated by Maven Integration for Eclipse
-#Wed Jan 11 12:49:12 EST 2017
+#Thu Jan 12 13:16:22 EST 2017
 version=2.0.5-SNAPSHOT
 groupId=com.shopizer
 m2e.projectName=sm-search
diff --git a/sm-shop/SALESMANAGER.h2.db b/sm-shop/SALESMANAGER.h2.db
index 153d8ce..b098481 100644
Binary files a/sm-shop/SALESMANAGER.h2.db and b/sm-shop/SALESMANAGER.h2.db differ
diff --git a/sm-shop/SALESMANAGER.lock.db b/sm-shop/SALESMANAGER.lock.db
index 0edb143..374bce7 100644
--- a/sm-shop/SALESMANAGER.lock.db
+++ b/sm-shop/SALESMANAGER.lock.db
@@ -1,4 +1,4 @@
 #FileLock
-#Tue Jan 10 13:08:21 EST 2017
-id=15989910441e4ac7e447ecd1c5a4783f751dae0f87d
+#Thu Jan 12 13:17:08 EST 2017
+id=15993e5c751808c7ebcc315eb71970264fe21a80519
 method=file
diff --git a/sm-shop/src/main/java/com/salesmanager/shop/model/order/OrderTotal.java b/sm-shop/src/main/java/com/salesmanager/shop/model/order/OrderTotal.java
index 5d27127..86a0fe8 100644
--- a/sm-shop/src/main/java/com/salesmanager/shop/model/order/OrderTotal.java
+++ b/sm-shop/src/main/java/com/salesmanager/shop/model/order/OrderTotal.java
@@ -13,6 +13,7 @@ public class OrderTotal extends Entity implements Serializable {
 	 */
 	private static final long serialVersionUID = 1L;
 	private String title;
+        private String text;
 	private String code;
 	private int order;
 	private String module;
diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/order/facade/OrderFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/order/facade/OrderFacadeImpl.java
index ddd346b..fb256e8 100644
--- a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/order/facade/OrderFacadeImpl.java
+++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/order/facade/OrderFacadeImpl.java
@@ -555,6 +555,7 @@ public class OrderFacadeImpl implements OrderFacade {
 			summary.setShipping(quote.getSelectedShippingOption().getOptionPrice());
 			summary.setShippingOption(quote.getSelectedShippingOption().getOptionName());
 			summary.setShippingModule(quote.getShippingModuleCode());
+			summary.setShippingOptionCode(quote.getSelectedShippingOption().getOptionCode());
 			
 			if(quote.getDeliveryAddress()!=null) {
 				
diff --git a/sm-shop/src/main/webapp/pages/shop/templates/exoticamobilia/pages/landing.jsp b/sm-shop/src/main/webapp/pages/shop/templates/exoticamobilia/pages/landing.jsp
index e155351..e6018c8 100644
--- a/sm-shop/src/main/webapp/pages/shop/templates/exoticamobilia/pages/landing.jsp
+++ b/sm-shop/src/main/webapp/pages/shop/templates/exoticamobilia/pages/landing.jsp
@@ -50,14 +50,14 @@ response.setDateHeader ("Expires", -1);
 			<c:if test="${requestScope.FEATURED_ITEM!=null || requestScope.SPECIALS!=null}" >							
 						<!-- one div by section -->
 						<c:if test="${requestScope.FEATURED_ITEM!=null}" >
-							<h2><s:message code="menu.catalogue-featured" text="Featured items" /></h2>
+							<h2 class="hTitle"><s:message code="menu.catalogue-featured" text="Featured items" /></h2>
 										    <!-- Iterate over featuredItems -->
 											<c:set var="ITEMS" value="${requestScope.FEATURED_ITEM}" scope="request" />
 											<c:set var="FEATURED" value="true" scope="request" />
 		                         			<jsp:include page="/pages/shop/templates/exoticamobilia/sections/productBox.jsp" />
 						</c:if>
 						<c:if test="${requestScope.SPECIALS!=null}" >
-							<h2><s:message code="label.product.specials" text="Specials" /></h2>
+							<h2 class="hTitle"><s:message code="label.product.specials" text="Specials" /></h2>
 											<!-- Iterate over featuredItems -->
 	                         				<c:set var="ITEMS" value="${requestScope.SPECIALS}" scope="request" />
 		                         			<jsp:include page="/pages/shop/templates/exoticamobilia/sections/productBox.jsp" />
diff --git a/sm-shop/src/main/webapp/resources/templates/exoticamobilia/css/template.css b/sm-shop/src/main/webapp/resources/templates/exoticamobilia/css/template.css
index 5b73082..0403518 100644
--- a/sm-shop/src/main/webapp/resources/templates/exoticamobilia/css/template.css
+++ b/sm-shop/src/main/webapp/resources/templates/exoticamobilia/css/template.css
@@ -10,7 +10,15 @@
 
 }
 
-
+.hTitle {
+  font-family: "Neue Helvetica W01",Helvetica,Arial,sans-serif!important;
+  font-style: normal!important;
+  font-variant: normal;
+  text-transform: none;
+  text-decoration: inherit;
+  font-weight: 300!important;
+  -webkit-font-smoothing: antialiased;
+}
 
 .helvetica-light {
   font-family: "Neue Helvetica W01",Helvetica,Arial,sans-serif!important;