dolibarr  16.0.1
ProductAttributeValue.class.php
1 <?php
2 
3 /* Copyright (C) 2016 Marcos GarcĂ­a <marcosgdf@gmail.com>
4  * Copyright (C) 2022 Open-Dsi <support@open-dsi.fr>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
26 {
30  public $module = 'variants';
31 
35  public $element = 'productattributevalue';
36 
40  public $table_element = 'product_attribute_value';
41 
46  public $ismultientitymanaged = 1;
47 
51  public $isextrafieldmanaged = 0;
52 
81  public $fields=array(
82  'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"),
83  'fk_product_attribute' => array('type'=>'integer:ProductAttribute:variants/class/ProductAttribute.class.php', 'label'=>'ProductAttribute', 'enabled'=>1, 'visible'=>0, 'position'=>10, 'notnull'=>1, 'index'=>1,),
84  'ref' => array('type'=>'varchar(255)', 'label'=>'Ref', 'visible'=>1, 'enabled'=>1, 'position'=>20, 'notnull'=>1, 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of object", 'css'=>''),
85  'value' => array('type'=>'varchar(255)', 'label'=>'Value', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'help'=>"", 'showoncombobox'=>'1',),
86  'position' => array('type'=>'integer', 'label'=>'Rank', 'enabled'=>1, 'visible'=>0, 'default'=>0, 'position'=>200, 'notnull'=>1,),
87  );
88  public $id;
89  public $fk_product_attribute;
90  public $ref;
91  public $value;
92  public $position;
93 
99  public function __construct(DoliDB $db)
100  {
101  global $conf, $langs;
102 
103  $this->db = $db;
104  $this->entity = $conf->entity;
105 
106  if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) {
107  $this->fields['rowid']['visible'] = 0;
108  }
109  if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) {
110  $this->fields['entity']['enabled'] = 0;
111  }
112 
113  // Unset fields that are disabled
114  foreach ($this->fields as $key => $val) {
115  if (isset($val['enabled']) && empty($val['enabled'])) {
116  unset($this->fields[$key]);
117  }
118  }
119 
120  // Translate some data of arrayofkeyval
121  if (is_object($langs)) {
122  foreach ($this->fields as $key => $val) {
123  if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
124  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
125  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
126  }
127  }
128  }
129  }
130  }
131 
139  public function create(User $user, $notrigger = 0)
140  {
141  global $langs;
142  $error = 0;
143 
144  // Clean parameters
145  $this->fk_product_attribute = $this->fk_product_attribute > 0 ? $this->fk_product_attribute : 0;
146  $this->ref = strtoupper(dol_sanitizeFileName(dol_string_nospecial(trim($this->ref)))); // Ref must be uppercase
147  $this->value = trim($this->value);
148 
149  // Check parameters
150  if (empty($this->fk_product_attribute)) {
151  $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductAttribute"));
152  $error++;
153  }
154  if (empty($this->ref)) {
155  $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
156  $error++;
157  }
158  if (empty($this->value)) {
159  $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Value"));
160  $error++;
161  }
162  if ($error) {
163  dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
164  return -1;
165  }
166 
167  $this->db->begin();
168 
169  $sql = "INSERT INTO " . MAIN_DB_PREFIX . $this->table_element . " (";
170  $sql .= " fk_product_attribute, ref, value, entity, position";
171  $sql .= ")";
172  $sql .= " VALUES (";
173  $sql .= " " . ((int) $this->fk_product_attribute);
174  $sql .= ", '" . $this->db->escape($this->ref) . "'";
175  $sql .= ", '" . $this->db->escape($this->value) . "'";
176  $sql .= ", " . ((int) $this->entity);
177  $sql .= ", " . ((int) $this->position);
178  $sql .= ")";
179 
180  dol_syslog(__METHOD__, LOG_DEBUG);
181  $resql = $this->db->query($sql);
182  if (!$resql) {
183  $this->errors[] = "Error " . $this->db->lasterror();
184  $error++;
185  }
186 
187  if (!$error) {
188  $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element);
189  }
190 
191  if (!$error && !$notrigger) {
192  // Call trigger
193  $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_CREATE', $user);
194  if ($result < 0) {
195  $error++;
196  }
197  // End call triggers
198  }
199 
200  if ($error) {
201  $this->db->rollback();
202  return -1 * $error;
203  } else {
204  $this->db->commit();
205  return $this->id;
206  }
207  }
208 
215  public function fetch($id)
216  {
217  global $langs;
218  $error = 0;
219 
220  // Clean parameters
221  $id = $id > 0 ? $id : 0;
222 
223  // Check parameters
224  if (empty($id)) {
225  $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("TechnicalID"));
226  $error++;
227  }
228  if ($error) {
229  dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
230  return -1;
231  }
232 
233  $sql = "SELECT rowid, fk_product_attribute, ref, value";
234  $sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
235  $sql .= " WHERE rowid = " . ((int) $id);
236  $sql .= " AND entity IN (" . getEntity('product') . ")";
237 
238  dol_syslog(__METHOD__, LOG_DEBUG);
239  $resql = $this->db->query($sql);
240  if (!$resql) {
241  $this->errors[] = "Error " . $this->db->lasterror();
242  dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
243  return -1;
244  }
245 
246  $numrows = $this->db->num_rows($resql);
247  if ($numrows) {
248  $obj = $this->db->fetch_object($resql);
249 
250  $this->id = $obj->rowid;
251  $this->fk_product_attribute = $obj->fk_product_attribute;
252  $this->ref = $obj->ref;
253  $this->value = $obj->value;
254  }
255  $this->db->free($resql);
256 
257  return $numrows;
258  }
259 
267  public function fetchAllByProductAttribute($prodattr_id, $only_used = false)
268  {
269  $return = array();
270 
271  $sql = "SELECT ";
272 
273  if ($only_used) {
274  $sql .= "DISTINCT ";
275  }
276 
277  $sql .= "v.fk_product_attribute, v.rowid, v.ref, v.value FROM " . MAIN_DB_PREFIX . "product_attribute_value v ";
278 
279  if ($only_used) {
280  $sql .= "LEFT JOIN " . MAIN_DB_PREFIX . "product_attribute_combination2val c2v ON c2v.fk_prod_attr_val = v.rowid ";
281  $sql .= "LEFT JOIN " . MAIN_DB_PREFIX . "product_attribute_combination c ON c.rowid = c2v.fk_prod_combination ";
282  $sql .= "LEFT JOIN " . MAIN_DB_PREFIX . "product p ON p.rowid = c.fk_product_child ";
283  }
284 
285  $sql .= "WHERE v.fk_product_attribute = " . ((int) $prodattr_id);
286 
287  if ($only_used) {
288  $sql .= " AND c2v.rowid IS NOT NULL AND p.tosell = 1";
289  }
290 
291  $query = $this->db->query($sql);
292 
293  while ($result = $this->db->fetch_object($query)) {
294  $tmp = new ProductAttributeValue($this->db);
295  $tmp->fk_product_attribute = $result->fk_product_attribute;
296  $tmp->id = $result->rowid;
297  $tmp->ref = $result->ref;
298  $tmp->value = $result->value;
299 
300  $return[] = $tmp;
301  }
302 
303  return $return;
304  }
305 
313  public function update(User $user, $notrigger = 0)
314  {
315  global $langs;
316  $error = 0;
317 
318  // Clean parameters
319  $this->fk_product_attribute = $this->fk_product_attribute > 0 ? $this->fk_product_attribute : 0;
320  $this->ref = strtoupper(dol_sanitizeFileName(dol_string_nospecial(trim($this->ref)))); // Ref must be uppercase
321  $this->value = trim($this->value);
322 
323  // Check parameters
324  if (empty($this->fk_product_attribute)) {
325  $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductAttribute"));
326  $error++;
327  }
328  if (empty($this->ref)) {
329  $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
330  $error++;
331  }
332  if (empty($this->value)) {
333  $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Value"));
334  $error++;
335  }
336  if ($error) {
337  dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
338  return -1;
339  }
340 
341  $this->db->begin();
342 
343  $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element . " SET";
344 
345  $sql .= " fk_product_attribute = " . ((int) $this->fk_product_attribute);
346  $sql .= ", ref = '" . $this->db->escape($this->ref) . "'";
347  $sql .= ", value = '" . $this->db->escape($this->value) . "'";
348  $sql .= ", position = " . ((int) $this->position);
349 
350  $sql .= " WHERE rowid = " . ((int) $this->id);
351 
352  dol_syslog(__METHOD__, LOG_DEBUG);
353  $resql = $this->db->query($sql);
354  if (!$resql) {
355  $this->errors[] = "Error " . $this->db->lasterror();
356  $error++;
357  }
358 
359  if (!$error && !$notrigger) {
360  // Call trigger
361  $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_MODIFY', $user);
362  if ($result < 0) {
363  $error++;
364  }
365  // End call triggers
366  }
367 
368  if (!$error) {
369  $this->db->commit();
370  return 1;
371  } else {
372  $this->db->rollback();
373  return -1 * $error;
374  }
375  }
376 
384  public function delete(User $user, $notrigger = 0)
385  {
386  global $langs;
387  $error = 0;
388 
389  // Clean parameters
390  $this->id = $this->id > 0 ? $this->id : 0;
391 
392  // Check parameters
393  if (empty($this->id)) {
394  $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("TechnicalID"));
395  $error++;
396  }
397  if ($error) {
398  dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
399  return -1;
400  }
401 
402  $result = $this->isUsed();
403  if ($result < 0) {
404  return -1;
405  } elseif ($result > 0) {
406  $this->errors[] = $langs->trans('ErrorAttributeValueIsUsedIntoProduct');
407  return -1;
408  }
409 
410  $this->db->begin();
411 
412  if (!$error && !$notrigger) {
413  // Call trigger
414  $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_DELETE', $user);
415  if ($result < 0) {
416  $error++;
417  }
418  // End call triggers
419  }
420 
421  if (!$error) {
422  $sql = "DELETE FROM " . MAIN_DB_PREFIX . $this->table_element . " WHERE rowid = " . ((int) $this->id);
423 
424  dol_syslog(__METHOD__, LOG_DEBUG);
425  $resql = $this->db->query($sql);
426  if (!$resql) {
427  $this->errors[] = "Error " . $this->db->lasterror();
428  $error++;
429  }
430  }
431 
432  if (!$error) {
433  $this->db->commit();
434  return 1;
435  } else {
436  $this->db->rollback();
437  return -1 * $error;
438  }
439  }
440 
446  public function isUsed()
447  {
448  global $langs;
449  $error = 0;
450 
451  // Clean parameters
452  $this->id = $this->id > 0 ? $this->id : 0;
453 
454  // Check parameters
455  if (empty($this->id)) {
456  $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("TechnicalID"));
457  $error++;
458  }
459  if ($error) {
460  dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
461  return -1;
462  }
463 
464  $sql = "SELECT COUNT(*) AS nb FROM " . MAIN_DB_PREFIX . "product_attribute_combination2val WHERE fk_prod_attr_val = " . ((int) $this->id);
465 
466  dol_syslog(__METHOD__, LOG_DEBUG);
467  $resql = $this->db->query($sql);
468  if (!$resql) {
469  $this->errors[] = "Error " . $this->db->lasterror();
470  return -1;
471  }
472 
473  $used = 0;
474  if ($obj = $this->db->fetch_object($resql)) {
475  $used = $obj->nb;
476  }
477 
478  return $used ? 1 : 0;
479  }
480 }
$conf db
API class for accounts.
Definition: inc.php:41
Class to manage Dolibarr users.
Definition: user.class.php:44
Class to manage Dolibarr database access.
dol_string_nospecial($str, $newstr= '_', $badcharstoreplace= '', $badcharstoremove= '')
Clean a string from all punctuation characters to use it as a ref or login.
isUsed()
Test if used by a product.
Class ProductAttributeValue Used to represent a product attribute value.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
update(User $user, $notrigger=0)
Updates a product attribute value.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
fetch($id)
Gets a product attribute value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename= '', $restricttologhandler= '', $logcontext=null)
Write log message into outputs.
dol_sanitizeFileName($str, $newstr= '_', $unaccent=1)
Clean a string to use it as a file name.
fetchAllByProductAttribute($prodattr_id, $only_used=false)
Returns all product attribute values of a product attribute.
if(isModEnabled('facture')&&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur')&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)&&$user->rights->fournisseur->facture->lire)||(isModEnabled('supplier_invoice')&&$user->rights->supplier_invoice->lire)) if(isModEnabled('don')&&!empty($user->rights->don->lire)) if(isModEnabled('tax')&&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture')&&isModEnabled('commande')&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:742
call_trigger($triggerName, $user)
Call trigger based on this instance.
$object ref
Definition: info.php:77
__construct(DoliDB $db)
Constructor.
errorsToString()
Method to output saved errors.
create(User $user, $notrigger=0)
Creates a value for a product attribute.