179    if (!empty($this->combination_price_levels) && $useCache) {
 
  180      if ((!empty($fk_price_level) && isset($this->combination_price_levels[$fk_price_level])) || empty($fk_price_level)) {
 
  185    if (!is_array($this->combination_price_levels)
 
  186      || empty($fk_price_level) 
 
  188      $this->combination_price_levels = array();
 
  192    $combination_price_levels = $staticProductCombinationLevel->fetchAll($this->
id, $fk_price_level);
 
  194    if (!is_array($combination_price_levels)) {
 
  198    if (empty($combination_price_levels)) {
 
  202      if ($fk_price_level > 0) {
 
  205        for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) {
 
  211    $this->combination_price_levels = $combination_price_levels;
 
 
  312    $sql = 
"SELECT pac.rowid, pac.fk_product_parent, pac.fk_product_child, pac.variation_price, pac.variation_price_percentage, pac.variation_ref_ext, pac.variation_weight";
 
  313    $sql .= 
" FROM ".MAIN_DB_PREFIX.
"product_attribute_combination AS pac";
 
  315      $sql .= 
" LEFT JOIN ".MAIN_DB_PREFIX.
"product AS p ON p.rowid = pac.fk_product_child";
 
  317    $sql .= 
" WHERE pac.fk_product_parent = ".((int) $fk_product_parent).
" AND pac.entity IN (".
getEntity(
'product').
")";
 
  319      $sql .= $this->db->order(
'p.ref', 
'ASC');
 
  322    $query = $this->db->query($sql);
 
  330    while ($result = $this->db->fetch_object($query)) {
 
  332      $tmp->id = $result->rowid;
 
  333      $tmp->fk_product_parent = $result->fk_product_parent;
 
  334      $tmp->fk_product_child = $result->fk_product_child;
 
  335      $tmp->variation_price = $result->variation_price;
 
  336      $tmp->variation_price_percentage = $result->variation_price_percentage;
 
  337      $tmp->variation_weight = $result->variation_weight;
 
  338      $tmp->variation_ref_ext = $result->variation_ref_ext;
 
  341        $tmp->fetchCombinationPriceLevels();
 
 
  522    $child = 
new Product($this->db);
 
  523    $child->fetch($this->fk_product_child);
 
  525    $child->price_autogen = $parent->price_autogen;
 
  526    $child->weight = $parent->weight;
 
  528    if (is_object($parent->oldcopy) && !$parent->oldcopy->isEmpty() && ($parent->status != $parent->oldcopy->status)) {
 
  529      $child->status = $parent->status;
 
  531    if (is_object($parent->oldcopy) && !$parent->oldcopy->isEmpty() && ($parent->status_buy != $parent->oldcopy->status_buy)) {
 
  532      $child->status_buy = $parent->status_buy;
 
  535    if ($this->variation_weight) {  
 
  536      $child->weight = ($child->weight ? $child->weight : 0) + $this->variation_weight;
 
  538    $child->weight_units = $parent->weight_units;
 
  541    if ($child->label == $parent->label) {
 
  544      $child->label           = $parent->label.$varlabel;
 
  548    if ($child->update($child->id, $user) > 0) {
 
  549      $new_vat = $parent->tva_tx;
 
  550      $new_npr = $parent->tva_npr;
 
  555        for ($i = 1; $i <= $maxi; $i++) {
 
  556          if ($parent->multiprices[$i] != 
'' || isset($this->combination_price_levels[$i]->variation_price)) {
 
  557            $new_type = empty($parent->multiprices_base_type[$i]) ? 
'HT' : $parent->multiprices_base_type[$i];
 
  558            $new_min_price = $parent->multiprices_min[$i];
 
  559            $variation_price = (float) (!isset($this->combination_price_levels[$i]->variation_price) ? $this->variation_price : $this->combination_price_levels[$i]->variation_price);
 
  560            $variation_price_percentage = (bool) (!isset($this->combination_price_levels[$i]->variation_price_percentage) ? $this->variation_price_percentage : $this->combination_price_levels[$i]->variation_price_percentage);
 
  562            if ($parent->prices_by_qty_list[$i]) {
 
  568            if ($new_type == 
'TTC') {
 
  569              $new_price = $parent->multiprices_ttc[$i];
 
  571              $new_price = $parent->multiprices[$i];
 
  574            if ($variation_price_percentage) {
 
  575              if ($new_price != 0) {
 
  576                $new_price *= 1 + ($variation_price / 100);
 
  579              $new_price += $variation_price;
 
  582            $ret = $child->updatePrice($new_price, $new_type, $user, $new_vat, $new_min_price, $i, $new_npr, $new_psq, 0, array(), $parent->default_vat_code);
 
  585              $this->db->rollback();
 
  586              $this->error = $child->error;
 
  587              $this->errors = $child->errors;
 
  593        $new_type = $parent->price_base_type;
 
  594        $new_min_price = $parent->price_min;
 
  595        $new_psq = $parent->price_by_qty;
 
  597        if ($new_type == 
'TTC') {
 
  598          $new_price = $parent->price_ttc;
 
  600          $new_price = $parent->price;
 
  603        if ($this->variation_price_percentage) {
 
  604          if ($new_price != 0) {
 
  605            $new_price *= 1 + ($this->variation_price / 100);
 
  608          $new_price += $this->variation_price;
 
  611        $ret = $child->updatePrice($new_price, $new_type, $user, $new_vat, $new_min_price, 1, $new_npr, $new_psq);
 
  614          $this->db->rollback();
 
  615          $this->error = $child->error;
 
  616          $this->errors = $child->errors;
 
  626    $this->db->rollback();
 
  627    $this->error = $child->error;
 
  628    $this->errors = $child->errors;
 
 
  757  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 = 
'')
 
  761    require_once DOL_DOCUMENT_ROOT.
'/variants/class/ProductAttribute.class.php';
 
  762    require_once DOL_DOCUMENT_ROOT.
'/variants/class/ProductAttributeValue.class.php';
 
  766    $price_impact = array(1 => 0); 
 
  768    $forced_refvar = trim((
string) $forced_refvar);
 
  770    if (!empty($forced_refvar) && $forced_refvar != $product->ref) {
 
  771      $existingProduct = 
new Product($this->db);
 
  772      $result = $existingProduct->fetch(0, $forced_refvar);
 
  774        $newproduct = $existingProduct;
 
  776        $existingProduct = 
false;
 
  777        $newproduct = clone $product;
 
  778        $newproduct->ref = $forced_refvar;
 
  781      $forced_refvar = 
false;
 
  782      $existingProduct = 
false;
 
  783      $newproduct = clone $product;
 
  787    $newproduct->context[
'createproductcombination'] = 
'createproductcombination';
 
  790    $weight_impact = (float) $forced_weightvar; 
 
  793    if (!is_array($forced_pricevar)) {
 
  794      $price_impact[1] = (float) $forced_pricevar; 
 
  796      $price_impact = $forced_pricevar;
 
  799    if (!is_array($price_var_percent)) {
 
  800      $price_var_percent = array(1 => (
bool) $price_var_percent);
 
  804    $existingCombination = $newcomb->fetchByProductCombination2ValuePairs($product->id, $combinations);
 
  806    if ($existingCombination) {
 
  807      $newcomb = $existingCombination;
 
  809      $newcomb->fk_product_parent = $product->id;
 
  812      $result = $newcomb->create($user);
 
  814        $this->error = $newcomb->error;
 
  815        $this->errors = $newcomb->errors;
 
  816        $this->db->rollback();
 
  825    foreach ($combinations as $currcombattr => $currcombval) {
 
  827      $prodattr->fetch($currcombattr);
 
  828      $prodattrval->fetch($currcombval);
 
  831      if (!$existingCombination) {
 
  833        $tmp->fk_prod_attr = $currcombattr;
 
  834        $tmp->fk_prod_attr_val = $currcombval;
 
  835        $tmp->fk_prod_combination = $newcomb->id;
 
  837        if ($tmp->create($user) < 0) {    
 
  838          $this->error = $tmp->error;
 
  839          $this->errors = $tmp->errors;
 
  840          $this->db->rollback();
 
  844      if ($forced_weightvar === 
false) {
 
  845        $weight_impact += (float) 
price2num($variations[$currcombattr][$currcombval][
'weight']);
 
  847      if ($forced_pricevar === 
false) {
 
  848        $price_impact[1] += (float) 
price2num($variations[$currcombattr][$currcombval][
'price']);
 
  851        if ($conf->global->PRODUIT_MULTIPRICES) {
 
  852          for ($i = 2; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) {
 
  853            $price_impact[$i] += (float) 
price2num($variations[$currcombattr][$currcombval][
'price']);
 
  858      if ($forced_refvar === 
false) {
 
  859        if (isset($conf->global->PRODUIT_ATTRIBUTES_SEPARATOR)) {
 
  860          $newproduct->ref .= 
getDolGlobalString(
'PRODUIT_ATTRIBUTES_SEPARATOR') . $prodattrval->ref;
 
  862          $newproduct->ref .= 
'_'.$prodattrval->ref;
 
  867      if ($newproduct->description) {
 
  868        $newproduct->description .= 
'<br>';
 
  870      $newproduct->description .= 
'<strong>'.$prodattr->label.
':</strong> '.$prodattrval->value;
 
  873    $newcomb->variation_price_percentage = (bool) $price_var_percent[1];
 
  874    $newcomb->variation_price = $price_impact[1];
 
  875    $newcomb->variation_weight = $weight_impact;
 
  876    $newcomb->variation_ref_ext = $this->db->escape($ref_ext);
 
  881      for ($i = 1; $i <= $maxi; $i++) {
 
  883        $productCombinationLevel->fk_product_attribute_combination = $newcomb->id;
 
  884        $productCombinationLevel->fk_price_level = $i;
 
  885        $productCombinationLevel->variation_price = $price_impact[$i];
 
  887        if (is_array($price_var_percent)) {
 
  888          $productCombinationLevel->variation_price_percentage = (bool) $price_var_percent[$i] ;
 
  890          $productCombinationLevel->variation_price_percentage = $price_var_percent;
 
  893        $newcomb->combination_price_levels[$i] = $productCombinationLevel;
 
  898    $newproduct->weight += $weight_impact;
 
  902    if ($existingProduct === 
false) {
 
  904      $newproduct->price = 0;
 
  905      $newproduct->price_ttc = 0;
 
  906      $newproduct->price_min = 0;
 
  907      $newproduct->price_min_ttc = 0;
 
  910      $newproduct->barcode = -1;
 
  911      $result = $newproduct->create($user);
 
  915        if ($newproduct->error != 
'ErrorProductAlreadyExists') {
 
  916          $this->error = $newproduct->error;
 
  917          $this->errors = $newproduct->errors;
 
  918          $this->db->rollback();
 
  927        if ($newcomb->fk_product_child) {
 
  928          $res = $newproduct->fetch($existingCombination->fk_product_child);
 
  930          $orig_prod_ref = $newproduct->ref;
 
  934            $newproduct->ref = $orig_prod_ref.$i;
 
  935            $res = $newproduct->create($user);
 
  937            if ($newproduct->error != 
'ErrorProductAlreadyExists') {
 
  938              $this->errors[] = $newproduct->error;
 
  947          $this->db->rollback();
 
  952      $result = $newproduct->update($newproduct->id, $user);
 
  954        $this->db->rollback();
 
  959    $newcomb->fk_product_child = $newproduct->id;
 
  961    if ($newcomb->update($user) < 0) {
 
  962      $this->error = $newcomb->error;
 
  963      $this->errors = $newcomb->errors;
 
  964      $this->db->rollback();
 
  969    return $newproduct->id;
 
 
  982    require_once DOL_DOCUMENT_ROOT.
'/variants/class/ProductCombination2ValuePair.class.php';
 
  985    if ($origProductId == $destProduct->id) {
 
  994    foreach ($combinations as $combination) {
 
  995      $variations = array();
 
  997      foreach ($prodcomb2val->fetchByFkCombination($combination->id) as $tmp_pc2v) {
 
  998        $variations[$tmp_pc2v->fk_prod_attr] = $tmp_pc2v->fk_prod_attr_val;
 
 1001      $variation_price_percentage = $combination->variation_price_percentage;
 
 1002      $variation_price = $combination->variation_price;
 
 1005        $variation_price_percentage = [ ];
 
 1006        $variation_price = [ ];
 
 1008        foreach ($combination->combination_price_levels as $productCombinationLevel) {
 
 1009          $variation_price_percentage[$productCombinationLevel->fk_price_level] = $productCombinationLevel->variation_price_percentage;
 
 1010          $variation_price[$productCombinationLevel->fk_price_level] = $productCombinationLevel->variation_price;
 
 1019        $variation_price_percentage,
 
 1021        $combination->variation_weight