/** * Axelor Business Solutions * * Copyright (C) 2016 Axelor (<http://axelor.com>). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.axelor.apps.base.service; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.axelor.apps.base.db.Product; import com.axelor.apps.base.db.ProductVariant; import com.axelor.apps.base.db.ProductVariantAttr; import com.axelor.apps.base.db.ProductVariantValue; import com.axelor.apps.base.db.repo.ProductRepository; import com.axelor.apps.base.db.repo.ProductVariantRepository; import com.google.inject.Inject; public class ProductVariantService { private static final Logger LOG = LoggerFactory.getLogger(ProductVariantService.class); @Inject private ProductRepository productRepo; @Inject private ProductVariantRepository productVariantRepo; public ProductVariant createProductVariant(ProductVariantAttr productVariantAttr1, ProductVariantAttr productVariantAttr2, ProductVariantAttr productVariantAttr3, ProductVariantAttr productVariantAttr4, ProductVariantValue productVariantValue1, ProductVariantValue productVariantValue2, ProductVariantValue productVariantValue3, ProductVariantValue productVariantValue4, boolean usedForStock) { ProductVariant productVariant = new ProductVariant(); productVariant.setProductVariantAttr1(productVariantAttr1); productVariant.setProductVariantAttr2(productVariantAttr2); productVariant.setProductVariantAttr3(productVariantAttr3); productVariant.setProductVariantAttr4(productVariantAttr4); productVariant.setProductVariantValue1(productVariantValue1); productVariant.setProductVariantValue2(productVariantValue2); productVariant.setProductVariantValue3(productVariantValue3); productVariant.setProductVariantValue4(productVariantValue4); productVariant.setUsedForStock(usedForStock); return productVariant; } public ProductVariantValue createProductVariantValue(ProductVariantAttr productVariantAttr, String code, String name, BigDecimal priceExtra) { ProductVariantValue productVariantValue = new ProductVariantValue(); productVariantValue.setCode(code); productVariantValue.setName(name); productVariantValue.setPriceExtra(priceExtra); productVariantValue.setProductVariantAttr(productVariantAttr); return productVariantValue; } public ProductVariantAttr createProductVariantAttr(String name) { ProductVariantAttr productVariantAttr = new ProductVariantAttr(); productVariantAttr.setName(name); productVariantAttr.setProductVariantValueList(new ArrayList<ProductVariantValue>()); return productVariantAttr; } public boolean equalsName(ProductVariant productVariant1, ProductVariant productVariant2) { if(productVariant1 != null && productVariant2 != null && productVariant1.getName().equals(productVariant2.getName())) { return true; } return false; } public boolean equals(ProductVariant productVariant1, ProductVariant productVariant2) { if(productVariant1 != null && productVariant2 != null && productVariant1.getProductVariantAttr1().equals(productVariant2.getProductVariantAttr1()) && productVariant1.getProductVariantAttr2().equals(productVariant2.getProductVariantAttr2()) && productVariant1.getProductVariantAttr3().equals(productVariant2.getProductVariantAttr3()) && productVariant1.getProductVariantAttr4().equals(productVariant2.getProductVariantAttr4()) && productVariant1.getProductVariantValue1().equals(productVariant2.getProductVariantValue1()) && productVariant1.getProductVariantValue2().equals(productVariant2.getProductVariantValue2()) && productVariant1.getProductVariantValue3().equals(productVariant2.getProductVariantValue3()) && productVariant1.getProductVariantValue4().equals(productVariant2.getProductVariantValue4())) { return true; } return false; } private ProductVariant getProductVariant(ProductVariantAttr productVariantAttr1, ProductVariantAttr productVariantAttr2, ProductVariantAttr productVariantAttr3, ProductVariantAttr productVariantAttr4, ProductVariantValue productVariantValue1, ProductVariantValue productVariantValue2, ProductVariantValue productVariantValue3, ProductVariantValue productVariantValue4, boolean usedForStock) { return productVariantRepo.all().filter("self.productVariantAttr1 = ?1 AND self.productVariantAttr2 = ?2 AND self.productVariantAttr3 = ?3 AND " + "self.productVariantAttr4 = ?4 AND self.productVariantValue1 = ?5 AND self.productVariantValue2 = ?6 AND self.productVariantValue3 = ?7 AND " + "self.productVariantValue4 = ?8 AND self.usedForStock = 'true'", productVariantAttr1, productVariantAttr2, productVariantAttr3, productVariantAttr4, productVariantValue1, productVariantValue2, productVariantValue3, productVariantValue4, usedForStock).fetchOne(); } public ProductVariant copyProductVariant(ProductVariant productVariant, boolean usedForStock) { return this.createProductVariant( productVariant.getProductVariantAttr1(), productVariant.getProductVariantAttr2(), productVariant.getProductVariantAttr3(), productVariant.getProductVariantAttr4(), productVariant.getProductVariantValue1(), productVariant.getProductVariantValue2(), productVariant.getProductVariantValue3(), productVariant.getProductVariantValue4(), usedForStock); } public ProductVariant getStockProductVariant(ProductVariant productVariant) { ProductVariant stockProductVariant = this.getProductVariant( productVariant.getProductVariantAttr1(), productVariant.getProductVariantAttr2(), productVariant.getProductVariantAttr3(), productVariant.getProductVariantAttr4(), productVariant.getProductVariantValue1(), productVariant.getProductVariantValue2(), productVariant.getProductVariantValue3(), productVariant.getProductVariantValue4(), true); if(stockProductVariant == null) { stockProductVariant = this.copyProductVariant(productVariant, true); } return stockProductVariant; } /** * Méthode permettant de récupérer la déclinaison de produit en fonction des attributs du parent (produit fabriqué) * @param parentProduct * Le produit finis ou semi-finis * @param productModel * Le modele de produit (Produit consommé) * @return * La déclinaison de produit consommé */ public Product getProductVariant(Product parentProduct, Product productModel) { ProductVariant productVariant = parentProduct.getProductVariant(); if(productVariant != null && productModel.getIsModel()) { return this.getProductVariant(productVariant, productModel); } return productModel; } private Product getProductVariant(ProductVariant parentProductVariant, Product productSearched) { LOG.debug("Recherche d'un variant du produit {} ayant des attributs communs avec {}", productSearched.getCode(), parentProductVariant.getName()); ProductVariantValue productVariantValue1 = parentProductVariant.getProductVariantValue1(); ProductVariantValue productVariantValue2 = parentProductVariant.getProductVariantValue2(); ProductVariantValue productVariantValue3 = parentProductVariant.getProductVariantValue3(); ProductVariantValue productVariantValue4 = parentProductVariant.getProductVariantValue4(); if(productVariantValue1 != null) { LOG.debug("Recherche d'un variant de produit ayant au moins comme attributs {} : {}", productVariantValue1.getProductVariantAttr().getCode(), productVariantValue1.getCode()); List<? extends Product> productList = productRepo.all().filter("self.parentProduct = ?1 " + "AND ((self.productVariant.productVariantAttr1.code = ?2 AND self.productVariant.productVariantValue1.code = ?3) " + "OR (self.productVariant.productVariantAttr2.code = ?2 AND self.productVariant.productVariantValue2.code = ?3) " + "OR (self.productVariant.productVariantAttr3.code = ?2 AND self.productVariant.productVariantValue3.code = ?3) " + "OR (self.productVariant.productVariantAttr4.code = ?2 AND self.productVariant.productVariantValue4.code = ?3)) ", productSearched, productVariantValue1.getProductVariantAttr().getCode(), productVariantValue1.getCode()).fetch(); if(productList == null || productList.isEmpty()) { return productSearched; } Product productFind = null; int nbAttr = 0; for(Product product : productList) { if(productVariantValue1 != null && productVariantValue2 != null && productVariantValue3 != null && productVariantValue4 != null) { //4 if(this.containsProductVariantValue(product, productVariantValue1) && this.containsProductVariantValue(product, productVariantValue2) && this.containsProductVariantValue(product, productVariantValue3) && this.containsProductVariantValue(product, productVariantValue4)) { LOG.debug("Variant de produit trouvé directement : {} avec l'ensemble des attributs (4) en commun", product.getCode()); return product; } //3 if(nbAttr < 3) { if(this.containsProductVariantValue(product, productVariantValue1) && this.containsProductVariantValue(product, productVariantValue2) && this.containsProductVariantValue(product, productVariantValue3)) { productFind = product; nbAttr = 3; } if(this.containsProductVariantValue(product, productVariantValue1) && this.containsProductVariantValue(product, productVariantValue2) && this.containsProductVariantValue(product, productVariantValue4)) { productFind = product; nbAttr = 3; } if(this.containsProductVariantValue(product, productVariantValue1) && this.containsProductVariantValue(product, productVariantValue3) && this.containsProductVariantValue(product, productVariantValue4)) { productFind = product; nbAttr = 3; } if(this.containsProductVariantValue(product, productVariantValue2) && this.containsProductVariantValue(product, productVariantValue3) && this.containsProductVariantValue(product, productVariantValue4)) { productFind = product; nbAttr = 3; } } if(nbAttr < 2) { //2 if(this.containsProductVariantValue(product, productVariantValue1) && this.containsProductVariantValue(product, productVariantValue2)) { productFind = product; nbAttr = 2; } if(this.containsProductVariantValue(product, productVariantValue1) && this.containsProductVariantValue(product, productVariantValue3)) { productFind = product; nbAttr = 2; } if(this.containsProductVariantValue(product, productVariantValue1) && this.containsProductVariantValue(product, productVariantValue4)) { productFind = product; nbAttr = 2; } if(this.containsProductVariantValue(product, productVariantValue2) && this.containsProductVariantValue(product, productVariantValue3)) { productFind = product; nbAttr = 2; } if(this.containsProductVariantValue(product, productVariantValue2) && this.containsProductVariantValue(product, productVariantValue4)) { productFind = product; nbAttr = 2; } if(this.containsProductVariantValue(product, productVariantValue3) && this.containsProductVariantValue(product, productVariantValue4)) { productFind = product; nbAttr = 2; } } if(nbAttr < 1) { //1 if(this.containsProductVariantValue(product, productVariantValue1)) { productFind = product; nbAttr = 1; } if(this.containsProductVariantValue(product, productVariantValue2)) { productFind = product; nbAttr = 1; } if(this.containsProductVariantValue(product, productVariantValue3)) { productFind = product; nbAttr = 1; } if(this.containsProductVariantValue(product, productVariantValue4)) { productFind = product; nbAttr = 1; } } } if(productVariantValue1 != null && productVariantValue2 != null && productVariantValue3 != null) { //3 if(this.containsProductVariantValue(product, productVariantValue1) && this.containsProductVariantValue(product, productVariantValue2) && this.containsProductVariantValue(product, productVariantValue3)) { LOG.debug("Variant de produit trouvé directement : {} avec l'ensemble des attributs (3) en commun", product.getCode()); return product; } if(nbAttr < 2) { //2 if(this.containsProductVariantValue(product, productVariantValue1) && this.containsProductVariantValue(product, productVariantValue2)) { productFind = product; nbAttr = 2; } if(this.containsProductVariantValue(product, productVariantValue1) && this.containsProductVariantValue(product, productVariantValue3)) { productFind = product; nbAttr = 2; } if(this.containsProductVariantValue(product, productVariantValue2) && this.containsProductVariantValue(product, productVariantValue3)) { productFind = product; nbAttr = 2; } } if(nbAttr < 1) { //1 if(this.containsProductVariantValue(product, productVariantValue1)) { productFind = product; nbAttr = 1; } if(this.containsProductVariantValue(product, productVariantValue2)) { productFind = product; nbAttr = 1; } if(this.containsProductVariantValue(product, productVariantValue3)) { productFind = product; nbAttr = 1; } } } if(productVariantValue1 != null && productVariantValue2 != null) { //2 if(this.containsProductVariantValue(product, productVariantValue1) && this.containsProductVariantValue(product, productVariantValue2)) { LOG.debug("Variant de produit trouvé directement : {} avec l'ensemble des attributs (2) en commun", product.getCode()); return product; } if(nbAttr < 1) { //1 if(this.containsProductVariantValue(product, productVariantValue1)) { productFind = product; nbAttr = 1; } if(this.containsProductVariantValue(product, productVariantValue2)) { productFind = product; nbAttr = 1; } } } if(productVariantValue1 != null) { if(this.containsProductVariantValue(product, productVariantValue1)) { LOG.debug("Variant de produit trouvé directement : {} avec l'ensemble des attributs (1) en commun", product.getCode()); return product; } } } if(productFind != null) { LOG.debug("Variant de produit trouvé : {} avec {} attributs en commun", productFind.getCode(), nbAttr); return productFind; } } return productSearched; } private boolean containsProductVariantValue(Product product, ProductVariantValue productVariantValue) { ProductVariant productVariantFind = product.getProductVariant(); ProductVariantValue productVariantValue1 = productVariantFind.getProductVariantValue1(); ProductVariantValue productVariantValue2 = productVariantFind.getProductVariantValue2(); ProductVariantValue productVariantValue3 = productVariantFind.getProductVariantValue3(); ProductVariantValue productVariantValue4 = productVariantFind.getProductVariantValue4(); if((productVariantValue1 != null && productVariantValue1.getCode().equals(productVariantValue.getCode()) && productVariantValue1.getProductVariantAttr().getCode().equals(productVariantValue.getProductVariantAttr().getCode())) || (productVariantValue2 != null && productVariantValue2.getCode().equals(productVariantValue.getCode()) && productVariantValue2.getProductVariantAttr().getCode().equals(productVariantValue.getProductVariantAttr().getCode())) || (productVariantValue3 != null && productVariantValue3.getCode().equals(productVariantValue.getCode()) && productVariantValue3.getProductVariantAttr().getCode().equals(productVariantValue.getProductVariantAttr().getCode())) || (productVariantValue4 != null && productVariantValue4.getCode().equals(productVariantValue.getCode()) && productVariantValue4.getProductVariantAttr().getCode().equals(productVariantValue.getProductVariantAttr().getCode()))) { return true; } return false; } }