--- /tmp/dsg/dolibarr/htdocs/variants/class/github_ProductAttribute.class.php +++ /tmp/dsg/dolibarr/htdocs/variants/class/client_ProductAttribute.class.php @@ -16,18 +16,17 @@ * along with this program. If not, see . */ -require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; /** * Class ProductAttribute * Used to represent a product attribute */ -class ProductAttribute extends CommonObject +class ProductAttribute { /** * Database handler * @var DoliDB */ - public $db; + private $db; /** * Id of the product attribute @@ -40,12 +39,6 @@ * @var string */ public $ref; - - /** - * External ref of the product attribute - * @var string - */ - public $ref_ext; /** * Label of the product attribute @@ -60,11 +53,11 @@ */ public $rang; - /** - * Constructor - * - * @param DoliDB $db Database handler - */ + /** + * Constructor + * + * @param DoliDB $db Database handler + */ public function __construct(DoliDB $db) { global $conf; @@ -85,7 +78,7 @@ return -1; } - $sql = "SELECT rowid, ref, ref_ext, label, rang FROM ".MAIN_DB_PREFIX."product_attribute WHERE rowid = ".(int) $id." AND entity IN (".getEntity('product').")"; + $sql = "SELECT rowid, ref, label, rang FROM ".MAIN_DB_PREFIX."product_attribute WHERE rowid = ".(int) $id." AND entity IN (".getEntity('product').")"; $query = $this->db->query($sql); @@ -97,7 +90,6 @@ $this->id = $obj->rowid; $this->ref = $obj->ref; - $this->ref_ext = $obj->ref_ext; $this->label = $obj->label; $this->rang = $obj->rang; @@ -113,21 +105,20 @@ { $return = array(); - $sql = 'SELECT rowid, ref, ref_ext, label, rang FROM '.MAIN_DB_PREFIX."product_attribute WHERE entity IN (".getEntity('product').')'; + $sql = 'SELECT rowid, ref, label, rang FROM '.MAIN_DB_PREFIX."product_attribute WHERE entity IN (".getEntity('product').')'; $sql .= $this->db->order('rang', 'asc'); $query = $this->db->query($sql); if ($query) { - while ($result = $this->db->fetch_object($query)) { - $tmp = new ProductAttribute($this->db); - $tmp->id = $result->rowid; - $tmp->ref = $result->ref; - $tmp->ref_ext = $result->ref_ext; - $tmp->label = $result->label; - $tmp->rang = $result->rang; - - $return[] = $tmp; - } + while ($result = $this->db->fetch_object($query)) { + $tmp = new ProductAttribute($this->db); + $tmp->id = $result->rowid; + $tmp->ref = $result->ref; + $tmp->label = $result->label; + $tmp->rang = $result->rang; + + $return[] = $tmp; + } } else dol_print_error($this->db); @@ -137,26 +128,16 @@ /** * Creates a product attribute * - * @param User $user Object user - * @param int $notrigger Do not execute trigger + * @param User $user Object user that create * @return int <0 KO, Id of new variant if OK */ - public function create(User $user, $notrigger = 0) - { - if (empty($notrigger)) { - // Call trigger - $result = $this->call_trigger('PRODUCT_ATTRIBUTE_CREATE', $user); - if ($result < 0) { - return -1; - } - // End call triggers - } - + public function create(User $user) + { //Ref must be uppercase $this->ref = strtoupper($this->ref); - $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_attribute (ref, ref_ext, label, entity, rang) - VALUES ('".$this->db->escape($this->ref)."', '".$this->db->escape($this->ref_ext)."', '".$this->db->escape($this->label)."', ".(int) $this->entity.", ".(int) $this->rang.")"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_attribute (ref, label, entity, rang) + VALUES ('".$this->db->escape($this->ref)."', '".$this->db->escape($this->label)."', ".(int) $this->entity.", ".(int) $this->rang.")"; $query = $this->db->query($sql); if ($query) @@ -172,26 +153,16 @@ /** * Updates a product attribute * - * @param User $user Object user - * @param int $notrigger Do not execute trigger + * @param User $user Object user * @return int <0 KO, >0 OK */ - public function update(User $user, $notrigger = 0) - { - if (empty($notrigger)) { - // Call trigger - $result = $this->call_trigger('PRODUCT_ATTRIBUTE_MODIFY', $user); - if ($result < 0) { - return -1; - } - // End call triggers - } - + public function update(User $user) + { //Ref must be uppercase $this->ref = trim(strtoupper($this->ref)); $this->label = trim($this->label); - $sql = "UPDATE ".MAIN_DB_PREFIX."product_attribute SET ref = '".$this->db->escape($this->ref)."', ref_ext = '".$this->db->escape($this->ref_ext)."', label = '".$this->db->escape($this->label)."', rang = ".(int) $this->rang." WHERE rowid = ".(int) $this->id; + $sql = "UPDATE ".MAIN_DB_PREFIX."product_attribute SET ref = '".$this->db->escape($this->ref)."', label = '".$this->db->escape($this->label)."', rang = ".(int) $this->rang." WHERE rowid = ".(int) $this->id; if ($this->db->query($sql)) { return 1; @@ -203,21 +174,11 @@ /** * Deletes a product attribute * - * @param User $user Object user - * @param int $notrigger Do not execute trigger - * @return int <0 KO, >0 OK - */ - public function delete(User $user, $notrigger = 0) - { - if (empty($notrigger)) { - // Call trigger - $result = $this->call_trigger('PRODUCT_ATTRIBUTE_DELETE', $user); - if ($result < 0) { - return -1; - } - // End call triggers - } - + * @param User $user Object user + * @return int <0 KO, >0 OK + */ + public function delete($user = null) + { $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute WHERE rowid = ".(int) $this->id; if ($this->db->query($sql)) { --- /tmp/dsg/dolibarr/htdocs/variants/class/github_ProductAttributeValue.class.php +++ /tmp/dsg/dolibarr/htdocs/variants/class/client_ProductAttributeValue.class.php @@ -16,18 +16,17 @@ * along with this program. If not, see . */ -require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; /** * Class ProductAttributeValue * Used to represent a product attribute value */ -class ProductAttributeValue extends CommonObject +class ProductAttributeValue { /** * Database handler * @var DoliDB */ - public $db; + private $db; /** * Attribute value id @@ -53,18 +52,18 @@ */ public $value; - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - public function __construct(DoliDB $db) - { + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct(DoliDB $db) + { global $conf; $this->db = $db; $this->entity = $conf->entity; - } + } /** * Gets a product attribute value @@ -145,11 +144,10 @@ /** * Creates a value for a product attribute * - * @param User $user Object user - * @param int $notrigger Do not execute trigger - * @return int <0 KO >0 OK - */ - public function create(User $user, $notrigger = 0) + * @param User $user Object user + * @return int <0 KO >0 OK + */ + public function create(User $user) { if (!$this->fk_product_attribute) { return -1; @@ -157,25 +155,15 @@ // Ref must be uppercase $this->ref = strtoupper($this->ref); - $this->value = $this->db->escape($this->value); $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_attribute_value (fk_product_attribute, ref, value, entity) VALUES ('".(int) $this->fk_product_attribute."', '".$this->db->escape($this->ref)."', - '".$this->value."', ".(int) $this->entity.")"; + '".$this->db->escape($this->value)."', ".(int) $this->entity.")"; $query = $this->db->query($sql); if ($query) { $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'product_attribute_value'); - if (empty($notrigger)) { - // Call trigger - $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_CREATE', $user); - if ($result < 0) { - return -1; - } - // End call triggers - } - return 1; } @@ -185,21 +173,11 @@ /** * Updates a product attribute value * - * @param User $user Object user - * @param int $notrigger Do not execute trigger - * @return int <0 if KO, >0 if OK - */ - public function update(User $user, $notrigger = 0) - { - if (empty($notrigger)) { - // Call trigger - $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_MODIFY', $user); - if ($result < 0) { - return -1; - } - // End call triggers - } - + * @param User $user Object user + * @return int <0 if KO, >0 if OK + */ + public function update(User $user) + { //Ref must be uppercase $this->ref = trim(strtoupper($this->ref)); $this->value = trim($this->value); @@ -218,22 +196,12 @@ /** * Deletes a product attribute value * - * @param User $user Object user - * @param int $notrigger Do not execute trigger * @return int <0 KO, >0 OK */ - public function delete(User $user, $notrigger = 0) - { - - if (empty($notrigger)) { - // Call trigger - $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_DELETE', $user); - if ($result < 0) { - return -1; - } - // End call triggers - } + public function delete() + { $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE rowid = ".(int) $this->id; + if ($this->db->query($sql)) { return 1; } @@ -244,36 +212,17 @@ /** * Deletes all product attribute values by a product attribute id * - * @param int $fk_attribute Product attribute id - * @param User $user Object user + * @param int $fk_attribute Product attribute id * @return int <0 KO, >0 OK */ - public function deleteByFkAttribute($fk_attribute, User $user) - { - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE fk_product_attribute = ".(int) $fk_attribute; - - $query = $this->db->query($sql); - - if (!$query) { - return -1; - } - - if (!$this->db->num_rows($query)) { - return 1; - } - - while ($obj = $this->db->fetch_object($query)) { - $tmp = new ProductAttributeValue($this->db); - if ($tmp->fetch($obj->rowid) > 0) { - $result = $tmp->delete($user); - if ($result < 0) { - return -1; - } - } else { - return -1; - } - } - - return 1; + public function deleteByFkAttribute($fk_attribute) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE fk_product_attribute = ".(int) $fk_attribute; + + if ($this->db->query($sql)) { + return 1; + } + + return -1; } } --- /tmp/dsg/dolibarr/htdocs/variants/class/github_ProductCombination.class.php +++ /tmp/dsg/dolibarr/htdocs/variants/class/client_ProductCombination.class.php @@ -27,7 +27,7 @@ * Database handler * @var DoliDB */ - public $db; + private $db; /** * Rowid of combination @@ -54,8 +54,8 @@ public $variation_price; /** - * Is the price variation a relative variation? Can be an array if multiprice feature per level is enabled. - * @var bool|array + * Is the price variation a relative variation? + * @var bool */ public $variation_price_percentage = false; @@ -72,18 +72,6 @@ public $entity; /** - * Combination price level - * @var ProductCombinationLevel[] - */ - public $combination_price_levels; - - /** - * External ref - * @var string - */ - public $variation_ref_ext = ''; - - /** * Constructor * * @param DoliDB $db Database handler @@ -99,14 +87,12 @@ /** * Retrieves a combination by its rowid * - * @param int $rowid Row id - * @return int <0 KO, >0 OK + * @param int $rowid Row id + * @return int <0 KO, >0 OK */ public function fetch($rowid) { - global $conf; - - $sql = "SELECT rowid, fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight, variation_ref_ext FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE rowid = ".(int) $rowid." AND entity IN (".getEntity('product').")"; + $sql = "SELECT rowid, fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE rowid = ".(int) $rowid." AND entity IN (".getEntity('product').")"; $query = $this->db->query($sql); @@ -126,126 +112,19 @@ $this->variation_price = $obj->variation_price; $this->variation_price_percentage = $obj->variation_price_percentage; $this->variation_weight = $obj->variation_weight; - $this->variation_ref_ext = $obj->variation_ref_ext; - - if (!empty($conf->global->PRODUIT_MULTIPRICES)) { - $this->fetchCombinationPriceLevels(); - } return 1; } - - /** - * Retrieves combination price levels - * - * @param int $fk_price_level The price level to fetch, use 0 for all - * @param bool $useCache To use cache or not - * @return int <0 KO, >0 OK - */ - public function fetchCombinationPriceLevels($fk_price_level = 0, $useCache = true) - { - global $conf; - - // Check cache - if (!empty($this->combination_price_levels) && $useCache) { - if ((!empty($fk_price_level) && isset($this->combination_price_levels[$fk_price_level])) || empty($fk_price_level)) { - return 1; - } - } - - if (!is_array($this->combination_price_levels) - || empty($fk_price_level) // if fetch an unique level dont erase all already fetched - ) { - $this->combination_price_levels = array(); - } - - $staticProductCombinationLevel = new ProductCombinationLevel($this->db); - $combination_price_levels = $staticProductCombinationLevel->fetchAll($this->id, $fk_price_level); - - if (!is_array($combination_price_levels)) { - return -1; - } - - if (empty($combination_price_levels)) { - - /** - * for auto retrocompatibility with last behavior - */ - if ($fk_price_level > 0) { - $combination_price_levels[$fk_price_level] = ProductCombinationLevel::createFromParent($this->db, $this, $fk_price_level); - } - else { - for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { - $combination_price_levels[$i] = ProductCombinationLevel::createFromParent($this->db, $this, $i); - } - } - } - - $this->combination_price_levels = $combination_price_levels; - - return 1; - } - - /** - * Retrieves combination price levels - * - * @param int $clean Levels of PRODUIT_MULTIPRICES_LIMIT - * @return int <0 KO, >0 OK - */ - public function saveCombinationPriceLevels($clean = 1) - { - global $conf; - - $error = 0; - - $staticProductCombinationLevel = new ProductCombinationLevel($this->db); - - // Delete all - if (empty($this->combination_price_levels)) { - return $staticProductCombinationLevel->deleteAllForCombination($this->id); - } - - // Clean not needed price levels (level higher than number max defined into setup) - if ($clean) { - $res = $staticProductCombinationLevel->clean($this->id); - if ($res < 0) { - $this->errors[] = 'Fail to clean not needed price levels'; - return -1; - } - } - - foreach ($this->combination_price_levels as $fk_price_level => $combination_price_level) { - $res = $combination_price_level->save(); - if ($res < 1) { - $this->error = 'Error saving combination price level '.$fk_price_level.' : '.$combination_price_level->error; - $this->errors[] = $this->error; - $error++; - break; - } - } - - if ($error) { - return $error * -1; - } - else { - return 1; - } - } - - /** - * Retrieves information of a variant product and ID of its parent product. - * - * @param int $productid Product ID of variant - * @param int $donotloadpricelevel Avoid loading price impact for each level. If PRODUIT_MULTIPRICES is not set, this has no effect. - * @return int <0 if KO, 0 if product ID is not ID of a variant product (so parent not found), >0 if OK (ID of parent) - */ - public function fetchByFkProductChild($productid, $donotloadpricelevel = 0) - { - global $conf; - - $sql = "SELECT rowid, fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight"; - $sql .= " FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE fk_product_child = ".((int) $productid)." AND entity IN (".getEntity('product').")"; + /** + * Retrieves a product combination by a child product row id + * + * @param int $fk_child Product row id + * @return int <0 KO, >0 OK + */ + public function fetchByFkProductChild($fk_child) + { + $sql = "SELECT rowid, fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE fk_product_child = ".(int) $fk_child." AND entity IN (".getEntity('product').")"; $query = $this->db->query($sql); @@ -254,7 +133,7 @@ } if (!$this->db->num_rows($query)) { - return 0; + return -1; } $result = $this->db->fetch_object($query); @@ -266,11 +145,7 @@ $this->variation_price_percentage = $result->variation_price_percentage; $this->variation_weight = $result->variation_weight; - if (empty($donotloadpricelevel) && !empty($conf->global->PRODUIT_MULTIPRICES)) { - $this->fetchCombinationPriceLevels(); - } - - return (int) $this->fk_product_parent; + return 1; } /** @@ -281,8 +156,6 @@ */ public function fetchAllByFkProductParent($fk_product_parent) { - global $conf; - $sql = "SELECT rowid, fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE fk_product_parent = ".(int) $fk_product_parent." AND entity IN (".getEntity('product').")"; $query = $this->db->query($sql); @@ -301,11 +174,6 @@ $tmp->variation_price = $result->variation_price; $tmp->variation_price_percentage = $result->variation_price_percentage; $tmp->variation_weight = $result->variation_weight; - $tmp->variation_ref_ext = $result->variation_ref_ext; - - if (!empty($conf->global->PRODUIT_MULTIPRICES)) { - $tmp->fetchCombinationPriceLevels(); - } $return[] = $tmp; } @@ -341,30 +209,19 @@ */ public function create($user) { - global $conf; - - /* $this->fk_product_child may be empty and will be filled later after subproduct has been created */ - - $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_attribute_combination"; - $sql .= " (fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight, variation_ref_ext, entity)"; - $sql .= " VALUES (".((int) $this->fk_product_parent).", ".((int) $this->fk_product_child).","; - $sql .= (float) $this->variation_price.", ".(int) $this->variation_price_percentage.","; - $sql .= (float) $this->variation_weight.", '".$this->db->escape($this->variation_ref_ext)."', ".(int) $this->entity.")"; - - $resql = $this->db->query($sql); - if ($resql) { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'product_attribute_combination'); - } else { - $this->error = $this->db->lasterror(); - return -1; - } - - if (!empty($conf->global->PRODUIT_MULTIPRICES)) { - $res = $this->saveCombinationPriceLevels(); - if ($res < 0) { - return -2; - } - } + $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_attribute_combination + (fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight, entity) + VALUES (".(int) $this->fk_product_parent.", ".(int) $this->fk_product_child.", + ".(float) $this->variation_price.", ".(int) $this->variation_price_percentage.", + ".(float) $this->variation_weight.", ".(int) $this->entity.")"; + + $query = $this->db->query($sql); + + if (!$query) { + return -1; + } + + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'product_attribute_combination'); return 1; } @@ -377,24 +234,15 @@ */ public function update(User $user) { - global $conf; - - $sql = "UPDATE ".MAIN_DB_PREFIX."product_attribute_combination"; - $sql .= " SET fk_product_parent = ".(int) $this->fk_product_parent.", fk_product_child = ".(int) $this->fk_product_child.","; - $sql .= " variation_price = ".(float) $this->variation_price.", variation_price_percentage = ".(int) $this->variation_price_percentage.","; - $sql .= " variation_ref_ext = '".$this->db->escape($this->variation_ref_ext)."',"; - $sql .= " variation_weight = ".(float) $this->variation_weight." WHERE rowid = ".((int) $this->id); - - $resql = $this->db->query($sql); - if (!$resql) { - return -1; - } - - if (!empty($conf->global->PRODUIT_MULTIPRICES)) { - $res = $this->saveCombinationPriceLevels(); - if ($res < 0) { - return -2; - } + $sql = "UPDATE ".MAIN_DB_PREFIX."product_attribute_combination + SET fk_product_parent = ".(int) $this->fk_product_parent.", fk_product_child = ".(int) $this->fk_product_child.", + variation_price = ".(float) $this->variation_price.", variation_price_percentage = ".(int) $this->variation_price_percentage.", + variation_weight = ".(float) $this->variation_weight." WHERE rowid = ".(int) $this->id; + + $query = $this->db->query($sql); + + if (!$query) { + return -1; } $parent = new Product($this->db); @@ -417,12 +265,6 @@ $comb2val = new ProductCombination2ValuePair($this->db); $comb2val->deleteByFkCombination($this->id); - - // remove combination price levels - if (!$this->db->query("DELETE FROM ".MAIN_DB_PREFIX."product_attribute_combination_price_level WHERE fk_product_attribute_combination = ".(int) $this->id)) { - $this->db->rollback(); - return -1; - } $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE rowid = ".(int) $this->id; @@ -490,15 +332,14 @@ if ($this->variation_weight) { // If we must add a delta on weight $child->weight = ($child->weight ? $child->weight : 0) + $this->variation_weight; } - $child->weight_units = $parent->weight_units; + $child->weight_units = $parent->weight_units; // Don't update the child label if the user has already modified it. if ($child->label == $parent->label) { // This will trigger only at variant creation time $varlabel = $this->getCombinationLabel($this->fk_product_child); - $child->label = $parent->label.$varlabel; ; - } - + $child->label = $parent->label.$varlabel;; + } if ($child->update($child->id, $user) > 0) { $new_vat = $parent->tva_tx; @@ -508,12 +349,9 @@ if (!empty($conf->global->PRODUIT_MULTIPRICES)) { for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { - if ($parent->multiprices[$i] != '' || isset($this->combination_price_levels[$i]->variation_price)) { + if ($parent->multiprices[$i] != '') { $new_type = $parent->multiprices_base_type[$i]; $new_min_price = $parent->multiprices_min[$i]; - $variation_price = doubleval(!isset($this->combination_price_levels[$i]->variation_price) ? $this->variation_price : $this->combination_price_levels[$i]->variation_price); - $variation_price_percentage = doubleval(!isset($this->combination_price_levels[$i]->variation_price_percentage) ? $this->variation_price_percentage : $this->combination_price_levels[$i]->variation_price_percentage); - if ($parent->prices_by_qty_list[$i]) { $new_psq = 1; } else { @@ -526,12 +364,12 @@ $new_price = $parent->multiprices[$i]; } - if ($variation_price_percentage) { + if ($this->variation_price_percentage) { if ($new_price != 0) { - $new_price *= 1 + ($variation_price / 100); + $new_price *= 1 + ($this->variation_price / 100); } } else { - $new_price += $variation_price; + $new_price += $this->variation_price; } $child->updatePrice($new_price, $new_type, $user, $new_vat, $new_min_price, $i, $new_npr, $new_psq); @@ -607,10 +445,10 @@ } /** - * Retrieves all unique attributes for a parent product - * - * @param int $productid Product rowid - * @return ProductAttribute[] Array of attributes + * Retrieves all unique attributres for a parent product + * + * @param int $productid Product rowid + * @return ProductAttribute[] */ public function getUniqueAttributesAndValuesByFkProductParent($productid) { @@ -620,11 +458,13 @@ $variants = array(); //Attributes - $sql = "SELECT DISTINCT fk_prod_attr, a.rang"; - $sql .= " FROM ".MAIN_DB_PREFIX."product_attribute_combination2val c2v LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination c ON c2v.fk_prod_combination = c.rowid"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product p ON p.rowid = c.fk_product_child"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute a ON a.rowid = fk_prod_attr"; - $sql .= " WHERE c.fk_product_parent = ".((int) $productid)." AND p.tosell = 1"; + $sql = "SELECT DISTINCT fk_prod_attr, a.rang +FROM ".MAIN_DB_PREFIX."product_attribute_combination2val c2v LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination c + ON c2v.fk_prod_combination = c.rowid + LEFT JOIN ".MAIN_DB_PREFIX."product p ON p.rowid = c.fk_product_child + LEFT JOIN ".MAIN_DB_PREFIX."product_attribute a ON a.rowid = fk_prod_attr +WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; + $sql .= $this->db->order('a.rang', 'asc'); $query = $this->db->query($sql); @@ -653,6 +493,7 @@ /** * Creates a product combination. Check usages to find more about its use + * * Format of $combinations array: * array( * 0 => array( @@ -663,32 +504,29 @@ * [...] * ) * - * @param User $user Object user - * @param Product $product Parent product - * @param array $combinations Attribute and value combinations. - * @param array $variations Price and weight variations - * @param bool|array $price_var_percent Is the price variation a relative variation? - * @param bool|float $forced_pricevar If the price variation is forced - * @param bool|float $forced_weightvar If the weight variation is forced - * @param bool|string $forced_refvar If the reference is forced - * @param string $ref_ext External reference - * @return int <0 KO, >0 OK - */ - public function createProductCombination(User $user, Product $product, array $combinations, array $variations, $price_var_percent = false, $forced_pricevar = false, $forced_weightvar = false, $forced_refvar = false, $ref_ext = '') - { - global $conf; + * @param User $user Object user + * @param Product $product Parent product + * @param array $combinations Attribute and value combinations. + * @param array $variations Price and weight variations + * @param bool $price_var_percent Is the price variation a relative variation? + * @param bool|float $forced_pricevar If the price variation is forced + * @param bool|float $forced_weightvar If the weight variation is forced + * @param bool|string $forced_refvar If the reference is forced + * @return int <0 KO, >0 OK + */ + public function createProductCombination(User $user, Product $product, array $combinations, array $variations, $price_var_percent = false, $forced_pricevar = false, $forced_weightvar = false, $forced_refvar = false) + { + global $db, $conf; require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttribute.class.php'; require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttributeValue.class.php'; - $this->db->begin(); - - $price_impact = array(1=>0); // init level price impact + $db->begin(); $forced_refvar = trim($forced_refvar); if (!empty($forced_refvar) && $forced_refvar != $product->ref) { - $existingProduct = new Product($this->db); + $existingProduct = new Product($db); $result = $existingProduct->fetch('', $forced_refvar); if ($result > 0) { $newproduct = $existingProduct; @@ -704,36 +542,26 @@ } //Final weight impact - $weight_impact = (float) $forced_weightvar; // If false, return 0 + $weight_impact = (float) $forced_weightvar; // If false, return 0 //Final price impact - if (!is_array($forced_pricevar)) { - $price_impact[1] = (float) $forced_pricevar; // If false, return 0 - } - else { - $price_impact = $forced_pricevar; - } - - $newcomb = new ProductCombination($this->db); + $price_impact = (float) $forced_pricevar; // If false, return 0 + + $newcomb = new ProductCombination($db); $existingCombination = $newcomb->fetchByProductCombination2ValuePairs($product->id, $combinations); if ($existingCombination) { $newcomb = $existingCombination; } else { $newcomb->fk_product_parent = $product->id; - - // Create 1 entry into product_attribute_combination (1 entry for each combinations). This init also $newcomb->id - $result = $newcomb->create($user); - if ($result < 0) { - $this->error = $newcomb->error; - $this->errors = $newcomb->errors; - $this->db->rollback(); + if ($newcomb->create($user) < 0) { // Create 1 entry into product_attribute_combination (1 entry for all combinations) + $db->rollback(); return -1; } } - $prodattr = new ProductAttribute($this->db); - $prodattrval = new ProductAttributeValue($this->db); + $prodattr = new ProductAttribute($db); + $prodattrval = new ProductAttributeValue($db); // $combination contains list of attributes pairs key->value. Example: array('id Color'=>id Blue, 'id Size'=>id Small, 'id Option'=>id val a, ...) //var_dump($combinations); @@ -744,15 +572,13 @@ //If there is an existing combination, there is no need to duplicate the valuepair if (!$existingCombination) { - $tmp = new ProductCombination2ValuePair($this->db); + $tmp = new ProductCombination2ValuePair($db); $tmp->fk_prod_attr = $currcombattr; $tmp->fk_prod_attr_val = $currcombval; $tmp->fk_prod_combination = $newcomb->id; if ($tmp->create($user) < 0) { // Create 1 entry into product_attribute_combination2val - $this->error = $tmp->error; - $this->errors = $tmp->errors; - $this->db->rollback(); + $db->rollback(); return -1; } } @@ -761,15 +587,7 @@ $weight_impact += (float) price2num($variations[$currcombattr][$currcombval]['weight']); } if ($forced_pricevar === false) { - $price_impact[1] += (float) price2num($variations[$currcombattr][$currcombval]['price']); - - // Manage Price levels - if ($conf->global->PRODUIT_MULTIPRICES) { - for ($i = 2; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) - { - $price_impact[$i] += (float) price2num($variations[$currcombattr][$currcombval]['price']); - } - } + $price_impact += (float) price2num($variations[$currcombattr][$currcombval]['price']); } if ($forced_refvar === false) { @@ -788,28 +606,8 @@ } $newcomb->variation_price_percentage = $price_var_percent; - $newcomb->variation_price = $price_impact[1]; + $newcomb->variation_price = $price_impact; $newcomb->variation_weight = $weight_impact; - $newcomb->variation_ref_ext = $this->db->escape($ref_ext); - - // Init price level - if ($conf->global->PRODUIT_MULTIPRICES) { - for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { - $productCombinationLevel = new ProductCombinationLevel($this->db); - $productCombinationLevel->fk_product_attribute_combination = $newcomb->id; - $productCombinationLevel->fk_price_level = $i; - $productCombinationLevel->variation_price = $price_impact[$i]; - - if (is_array($price_var_percent)) { - $productCombinationLevel->variation_price_percentage = (empty($price_var_percent[$i]) ? false : $price_var_percent[$i]); - } else { - $productCombinationLevel->variation_price_percentage = $price_var_percent; - } - - $newcomb->combination_price_levels[$i] = $productCombinationLevel; - } - } - //var_dump($newcomb->combination_price_levels); $newproduct->weight += $weight_impact; @@ -832,7 +630,7 @@ if ($newproduct->error != 'ErrorProductAlreadyExists') { $this->error[] = $newproduct->error; $this->errors = $newproduct->errors; - $this->db->rollback(); + $db->rollback(); return -1; } @@ -861,7 +659,7 @@ } if ($res < 0) { - $this->db->rollback(); + $db->rollback(); return -1; } } @@ -869,7 +667,7 @@ $result = $newproduct->update($newproduct->id, $user); if ($result < 0) { - $this->db->rollback(); + $db->rollback(); return -1; } } @@ -878,13 +676,11 @@ if ($newcomb->update($user) < 0) { - $this->error = $newcomb->error; - $this->errors = $newcomb->errors; - $this->db->rollback(); - return -1; - } - - $this->db->commit(); + $db->rollback(); + return -1; + } + + $db->commit(); return $newproduct->id; } @@ -968,273 +764,3 @@ return $label; } } - - - -/** - * Class ProductCombinationLevel - * Used to represent a product combination Level - */ -class ProductCombinationLevel -{ - /** - * Database handler - * @var DoliDB - */ - public $db; - - /** - * @var string Name of table without prefix where object is stored - */ - public $table_element = 'product_attribute_combination_price_level'; - - /** - * Rowid of combination - * @var int - */ - public $id; - - /** - * Rowid of parent product combination - * @var int - */ - public $fk_product_attribute_combination; - - /** - * Combination price level - * @var int - */ - public $fk_price_level; - - /** - * Price variation - * @var float - */ - public $variation_price; - - /** - * Is the price variation a relative variation? - * @var bool - */ - public $variation_price_percentage = false; - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - public function __construct(DoliDB $db) - { - $this->db = $db; - } - - /** - * Retrieves a combination level by its rowid - * - * @param int $rowid Row id - * @return int <0 KO, >0 OK - */ - public function fetch($rowid) - { - $sql = "SELECT rowid, fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage FROM ".MAIN_DB_PREFIX.$this->table_element." WHERE rowid = ".(int) $rowid; - - $obj = $this->db->getRow($sql); - - if ($obj) { - return $this->fetchFormObj($obj); - } - - return -1; - } - - - /** - * Retrieves combination price levels - * - * @param int $fk_product_attribute_combination Id of product combination - * @param int $fk_price_level The price level to fetch, use 0 for all - * @return mixed self[] | -1 on KO - */ - public function fetchAll($fk_product_attribute_combination, $fk_price_level = 0) - { - - $sql = "SELECT rowid, fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage"; - $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element; - $sql .= " WHERE fk_product_attribute_combination = ".intval($fk_product_attribute_combination); - - if (!empty($fk_price_level)) { - $sql .= ' AND fk_price_level = '.intval($fk_price_level); - } - - $combination_price_levels = $this->db->getRows($sql); - - if (!is_array($combination_price_levels)) { - return -1; - } - - $result = array(); - - if (!empty($combination_price_levels)) { - // For more simple usage set level as array key - foreach ($combination_price_levels as $k => $row) { - $productCombinationLevel = new ProductCombinationLevel($this->db); - $productCombinationLevel->fetchFormObj($row); - $result[$row->fk_price_level] = $productCombinationLevel; - } - } - - return $result; - } - - /** - * assign vars form an stdclass like sql obj - * - * @param int $obj Object resultset - * @return int <0 KO, >0 OK - */ - public function fetchFormObj($obj) - { - if (!$obj) { - return -1; - } - - $this->id = $obj->rowid; - $this->fk_product_attribute_combination = doubleval($obj->fk_product_attribute_combination); - $this->fk_price_level = intval($obj->fk_price_level); - $this->variation_price = doubleval($obj->variation_price); - $this->variation_price_percentage = (bool) $obj->variation_price_percentage; - - return 1; - } - - - /** - * Save a price impact of a product combination for a price level - * - * @return int <0 KO, >0 OK - */ - public function save() - { - if (($this->id > 0 && empty($this->fk_product_attribute_combination)) || empty($this->fk_price_level)) { - return -1; - } - - // Check if level exist in DB before add - if ($this->fk_product_attribute_combination > 0 && empty($this->id)) { - $sql = "SELECT rowid id"; - $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element; - $sql .= " WHERE fk_product_attribute_combination = ".(int) $this->fk_product_attribute_combination; - $sql .= ' AND fk_price_level = '.intval($this->fk_price_level); - - $existObj = $this->db->getRow($sql); - if ($existObj) { - $this->id = $existObj->id; - } - } - - // Update - if (!empty($this->id)) { - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' SET variation_price = '.doubleval($this->variation_price).' , variation_price_percentage = '.intval($this->variation_price_percentage); - $sql .= ' WHERE rowid = '.((int) $this->id); - - $res = $this->db->query($sql); - if ($res > 0) { - return $this->id; - } else { - $this->error = $this->db->error(); - $this->errors[] = $this->error; - return -1; - } - } else { - // Add - $sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element." ("; - $sql .= "fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage"; - $sql .= ") VALUES ("; - $sql .= (int) $this->fk_product_attribute_combination; - $sql .= ", ".intval($this->fk_price_level); - $sql .= ", ".doubleval($this->variation_price); - $sql .= ", ".intval($this->variation_price_percentage); - $sql .= ")"; - - $res = $this->db->query($sql); - if ($res) { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element); - } else { - $this->error = $this->db->error(); - $this->errors[] = $this->error; - return -1; - } - } - - return $this->id; - } - - - /** - * delete - * - * @return int <0 KO, >0 OK - */ - public function delete() - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element." WHERE rowid = ".(int) $this->id; - $res = $this->db->query($sql); - - return $res ? 1 : -1; - } - - - /** - * delete all for a combination - * - * @param int $fk_product_attribute_combination Id of combination - * @return int <0 KO, >0 OK - */ - public function deleteAllForCombination($fk_product_attribute_combination) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element." WHERE fk_product_attribute_combination = ".(int) $fk_product_attribute_combination; - $res = $this->db->query($sql); - - return $res ? 1 : -1; - } - - - /** - * Clean not needed price levels for a combination - * - * @param int $fk_product_attribute_combination Id of combination - * @return int <0 KO, >0 OK - */ - public function clean($fk_product_attribute_combination) - { - global $conf; - - $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element; - $sql .= " WHERE fk_product_attribute_combination = ".(int) $fk_product_attribute_combination; - $sql .= " AND fk_price_level > ".intval($conf->global->PRODUIT_MULTIPRICES_LIMIT); - $res = $this->db->query($sql); - - return $res ? 1 : -1; - } - - - /** - * Create new Product Combination Price level from Parent - * - * @param DoliDB $db Database handler - * @param ProductCombination $productCombination Product combination - * @param int $fkPriceLevel Price level - * @return ProductCombinationLevel - */ - public static function createFromParent(DoliDB $db, ProductCombination $productCombination, $fkPriceLevel) - { - $productCombinationLevel = new self($db); - $productCombinationLevel->fk_price_level = $fkPriceLevel; - $productCombinationLevel->fk_product_attribute_combination = $productCombination->id; - $productCombinationLevel->variation_price = $productCombination->variation_price; - $productCombinationLevel->variation_price_percentage = (bool) $productCombination->variation_price_percentage; - - return $productCombinationLevel; - } -} --- /tmp/dsg/dolibarr/htdocs/variants/class/github_ProductCombination2ValuePair.class.php +++ /tmp/dsg/dolibarr/htdocs/variants/class/client_ProductCombination2ValuePair.class.php @@ -52,15 +52,15 @@ */ public $fk_prod_attr_val; - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - public function __construct(DoliDB $db) - { - $this->db = $db; - } + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + } /** * Translates this class to a human-readable string