dolibarr 22.0.5
productcustomerprice.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2007-2012 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro>
4 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
5 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
26require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
27require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
28
33{
37 public $fields = array(
38 'ref' => array('type' => 'varchar(128)', 'label' => 'Ref', 'enabled' => 1, 'visible' => 4, 'position' => 10, 'notnull' => 1, 'default' => '(PROV)', 'index' => 1, 'searchall' => 1, 'comment' => "Reference of object", 'showoncombobox' => 1, 'noteditable' => 1),
39 'fk_product' => array('type' => 'integer:Product:product/class/product.class.php:0', 'label' => 'Product', 'enabled' => '$conf->product->enabled', 'visible' => 1, 'position' => 35, 'notnull' => 1, 'index' => 1, 'comment' => "Product to produce", 'css' => 'maxwidth300', 'csslist' => 'tdoverflowmax100', 'picto' => 'product'),
40 'ref_customer' => array('type' => 'varchar(128)', 'label' => 'RefCustomer', 'enabled' => 1, 'visible' => 4, 'position' => 10, 'notnull' => 1,),
41 'date_begin' => array('type' => 'date', 'label' => 'AppliedPricesFrom', 'enabled' => 1, 'visible' => 1, 'position' => 500, 'notnull' => 1,),
42 'date_end' => array('type' => 'date', 'label' => 'AppliedPricesTo', 'enabled' => 1, 'visible' => 1, 'position' => 501, 'notnull' => 1,),
43 'price_base_type' => array('type' => 'varchar(255)', 'label' => 'PriceBase', 'enabled' => 1, 'visible' => 1, 'position' => 11, 'notnull' => -1, 'comment' => 'Price Base Type'),
44 'tva_tx' => array('type' => 'decimal(20,6)', 'label' => 'VAT', 'enabled' => 1, 'visible' => 1, 'position' => 12, 'notnull' => -1, 'comment' => 'TVA Tax Rate'),
45 'price' => array('type' => 'decimal(20,6)', 'label' => 'HT', 'enabled' => 1, 'visible' => 1, 'position' => 8, 'notnull' => -1, 'comment' => 'Price HT'),
46 'price_ttc' => array('type' => 'decimal(20,6)', 'label' => 'TTC', 'enabled' => 1, 'visible' => 1, 'position' => 8, 'notnull' => -1, 'comment' => 'Price TTC'),
47 'price_min' => array('type' => 'decimal(20,6)', 'label' => 'MinPriceHT', 'enabled' => 1, 'visible' => 1, 'position' => 9, 'notnull' => -1, 'comment' => 'Minimum Price'),
48 'price_min_ttc' => array('type' => 'decimal(20,6)', 'label' => 'MinPriceTTC', 'enabled' => 1, 'visible' => 1, 'position' => 10, 'notnull' => -1, 'comment' => 'Minimum Price TTC'),
49 'price_label' => array('type' => 'varchar(255)', 'label' => 'PriceLabel', 'enabled' => 1, 'visible' => 1, 'position' => 20, 'notnull' => -1, 'comment' => 'Price Label'),
50 'discount_percent' => array('type' => 'decimal(20,6)', 'label' => 'Discount', 'enabled' => 1, 'visible' => 1, 'position' => 30, 'notnull' => -1, 'comment' => 'Discount'),
51 'fk_user' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'visible' => 1, 'position' => 510, 'notnull' => 1, 'foreignkey' => 'user.rowid', 'csslist' => 'tdoverflowmax100'),
52 );
53
57 public $element = 'product_customer_price';
58
62 public $table_element = 'product_customer_price';
63
67 public $entity;
68
72 public $datec = '';
73
77 public $fk_product;
78
82 public $fk_soc;
83
87 public $ref_customer;
88
92 public $price;
96 public $price_ttc;
100 public $price_min;
104 public $price_min_ttc;
108 public $price_base_type;
112 public $default_vat_code;
116 public $tva_tx;
120 public $recuperableonly;
124 public $localtax1_type;
128 public $localtax1_tx;
132 public $localtax2_type;
136 public $localtax2_tx;
140 public $price_label;
144 public $discount_percent;
148 public $date_begin = '';
152 public $date_end = '';
153
157 public $fk_user;
158
162 public $lines = array();
163
164
170 public function __construct($db)
171 {
172 $this->db = $db;
173 }
174
180 public function verifyDates()
181 {
182 global $langs;
183
184 $sql = "SELECT COUNT(*) AS nb";
185 $sql .= " FROM " . $this->db->prefix() . "product_customer_price as t";
186 $sql .= " WHERE (t.date_begin = '" . $this->db->idate($this->date_begin) . "' OR t.date_end = '" . $this->db->idate($this->date_begin) . "'";
187 $sql .= " OR t.date_begin = '" . $this->db->idate($this->date_end) . "' OR t.date_end = '" . $this->db->idate($this->date_end) . "'";
188 $sql .= " OR (t.date_begin <= '" . $this->db->idate($this->date_begin) . "' AND '" . $this->db->idate($this->date_begin) . "' <= t.date_end)";
189 $sql .= " OR (t.date_begin <= '" . $this->db->idate($this->date_end) . "' AND '" . $this->db->idate($this->date_end) . "' <= t.date_end))";
190 if ($this->fk_product > 0) $sql .= " AND t.fk_product = " . ((int) $this->fk_product);
191 if ($this->fk_soc > 0) $sql .= " AND t.fk_soc = " . ((int) $this->fk_soc);
192 if ($this->id > 0) $sql .= " AND t.rowid != " . ((int) $this->id);
193
194 dol_syslog(get_class($this) . "::fetch", LOG_DEBUG);
195 $resql = $this->db->query($sql);
196 if (!$resql) {
197 $this->errors[] = "Error " . $this->db->lasterror();
198 return -1;
199 }
200
201 $nb = 0;
202 if ($obj = $this->db->fetch_object($resql)) {
203 $nb = (int) $obj->nb;
204 }
205 $this->db->free($resql);
206
207 if ($nb > 0) {
208 $this->errors[] = $langs->trans('ErrorAppliedPricesIntersectAnotherPeriod');
209 return -1;
210 }
211
212 return 1;
213 }
214
223 public function create($user, $notrigger = 0, $forceupdateaffiliate = 0)
224 {
225 global $conf, $langs;
226 $error = 0;
227 $now = dol_now();
228
229 // Clean parameters
230
231 if (isset($this->entity)) {
232 $this->entity = (int) $this->entity;
233 }
234 if (isset($this->fk_product)) {
235 $this->fk_product = (int) $this->fk_product;
236 }
237 if (isset($this->fk_soc)) {
238 $this->fk_soc = (int) $this->fk_soc;
239 }
240 if (isset($this->ref_customer)) {
241 $this->ref_customer = trim($this->ref_customer);
242 }
243 if (isset($this->price)) {
244 $this->price = trim($this->price);
245 }
246 if (isset($this->price_ttc)) {
247 $this->price_ttc = trim($this->price_ttc);
248 }
249 if (isset($this->price_min)) {
250 $this->price_min = trim($this->price_min);
251 }
252 if (isset($this->price_min_ttc)) {
253 $this->price_min_ttc = trim($this->price_min_ttc);
254 }
255 if (isset($this->price_base_type)) {
256 $this->price_base_type = trim($this->price_base_type);
257 }
258 if (isset($this->tva_tx)) {
259 $this->tva_tx = trim($this->tva_tx);
260 }
261 if (isset($this->recuperableonly)) {
262 $this->recuperableonly = trim($this->recuperableonly);
263 }
264 if (isset($this->localtax1_tx)) {
265 $this->localtax1_tx = trim($this->localtax1_tx);
266 }
267 if (isset($this->localtax2_tx)) {
268 $this->localtax2_tx = trim($this->localtax2_tx);
269 }
270 if (empty($this->discount_percent) || !is_numeric($this->discount_percent)) {
271 $this->discount_percent = 0;
272 }
273 if (empty($this->date_begin)) {
274 $this->date_begin = $now;
275 }
276 if (isset($this->fk_user)) {
277 $this->fk_user = (int) $this->fk_user;
278 }
279 if (isset($this->price_label)) {
280 $this->price_label = trim($this->price_label);
281 }
282 if (isset($this->import_key)) {
283 $this->import_key = trim($this->import_key);
284 }
285
286 // Check parameters
287 // Put here code to add control on parameters values
288 $result = $this->verifyDates();
289 if ($result < 0) {
290 return -1;
291 }
292
293 if ($this->price != '' || $this->price == 0) {
294 $vatRate = (float) $this->tva_tx;
295 if ($this->price_base_type == 'TTC') {
296 $this->price_ttc = price2num($this->price, 'MU');
297 $this->price = (float) price2num($this->price) / (1 + ($vatRate / 100));
298 $this->price = price2num($this->price, 'MU');
299
300 if ($this->price_min != '' || $this->price_min == 0) {
301 $this->price_min_ttc = price2num($this->price_min, 'MU');
302 $this->price_min = (float) price2num($this->price_min) / (1 + ($vatRate / 100));
303 $this->price_min = price2num($this->price_min, 'MU');
304 } else {
305 $this->price_min = 0;
306 $this->price_min_ttc = 0;
307 }
308 } else {
309 $this->price = price2num($this->price, 'MU');
310 $this->price_ttc = ($this->recuperableonly != 1) ? (float) price2num($this->price) * (1 + ($vatRate / 100)) : $this->price;
311 $this->price_ttc = price2num($this->price_ttc, 'MU');
312
313 if ($this->price_min != '' || $this->price_min == 0) {
314 $this->price_min = price2num($this->price_min, 'MU');
315 $this->price_min_ttc = (float) price2num($this->price_min) * (1 + ($vatRate / 100));
316 $this->price_min_ttc = price2num($this->price_min_ttc, 'MU');
317 // print 'X'.$newminprice.'-'.$price_min;
318 } else {
319 $this->price_min = 0;
320 $this->price_min_ttc = 0;
321 }
322 }
323 }
324
325 // Insert request
326 $sql = "INSERT INTO ".$this->db->prefix()."product_customer_price(";
327 $sql .= "entity,";
328 $sql .= "datec,";
329 $sql .= "fk_product,";
330 $sql .= "fk_soc,";
331 $sql .= 'ref_customer,';
332 $sql .= "price,";
333 $sql .= "price_ttc,";
334 $sql .= "price_min,";
335 $sql .= "price_min_ttc,";
336 $sql .= "price_base_type,";
337 $sql .= "default_vat_code,";
338 $sql .= "tva_tx,";
339 $sql .= "recuperableonly,";
340 $sql .= "localtax1_type,";
341 $sql .= "localtax1_tx,";
342 $sql .= "localtax2_type,";
343 $sql .= "localtax2_tx,";
344 $sql .= "discount_percent,";
345 $sql .= "date_begin,";
346 $sql .= "date_end,";
347 $sql .= "fk_user,";
348 $sql .= "price_label,";
349 $sql .= "import_key";
350 $sql .= ") VALUES (";
351 $sql .= " ".((int) $conf->entity).",";
352 $sql .= " '".$this->db->idate($now)."',";
353 $sql .= " ".(!isset($this->fk_product) ? 'NULL' : ((int) $this->fk_product)).",";
354 $sql .= " ".(!isset($this->fk_soc) ? 'NULL' : ((int) $this->fk_soc)).",";
355 $sql .= " ".(!isset($this->ref_customer) ? 'NULL' : "'".$this->db->escape($this->ref_customer)."'").",";
356 $sql .= " ".(empty($this->price) ? '0' : "'".$this->db->escape($this->price)."'").",";
357 $sql .= " ".(empty($this->price_ttc) ? '0' : "'".$this->db->escape($this->price_ttc)."'").",";
358 $sql .= " ".(empty($this->price_min) ? '0' : "'".$this->db->escape($this->price_min)."'").",";
359 $sql .= " ".(empty($this->price_min_ttc) ? '0' : "'".$this->db->escape($this->price_min_ttc)."'").",";
360 $sql .= " ".(!isset($this->price_base_type) ? 'NULL' : "'".$this->db->escape($this->price_base_type)."'").",";
361 $sql .= " ".($this->default_vat_code ? "'".$this->db->escape($this->default_vat_code)."'" : "null").",";
362 $sql .= " ".(!isset($this->tva_tx) ? 'NULL' : (empty($this->tva_tx) ? 0 : $this->tva_tx)).",";
363 $sql .= " ".(!isset($this->recuperableonly) ? 'NULL' : "'".$this->db->escape($this->recuperableonly)."'").",";
364 $sql .= " ".(empty($this->localtax1_type) ? "'0'" : "'".$this->db->escape($this->localtax1_type)."'").",";
365 $sql .= " ".(!isset($this->localtax1_tx) ? 'NULL' : (empty($this->localtax1_tx) ? 0 : $this->localtax1_tx)).",";
366 $sql .= " ".(empty($this->localtax2_type) ? "'0'" : "'".$this->db->escape($this->localtax2_type)."'").",";
367 $sql .= " ".(!isset($this->localtax2_tx) ? 'NULL' : (empty($this->localtax2_tx) ? 0 : $this->localtax2_tx)).",";
368 $sql .= " ".(empty($this->discount_percent) ? '0' : "'".$this->db->escape(price2num($this->discount_percent))."'").",";
369 $sql .= " '".$this->db->idate($this->date_begin)."',";
370 $sql .= " ".(empty($this->date_end) ? 'NULL' : "'".$this->db->idate($this->date_end)."'").",";
371 $sql .= " ".((int) $user->id).",";
372 $sql .= " ".(!isset($this->price_label) ? 'NULL' : "'".$this->db->escape($this->price_label)."'").",";
373 $sql .= " ".(!isset($this->import_key) ? 'NULL' : "'".$this->db->escape($this->import_key)."'");
374 $sql .= ")";
375
376 $this->db->begin();
377
378 dol_syslog(get_class($this)."::create", LOG_DEBUG);
379 $resql = $this->db->query($sql);
380 if (!$resql) {
381 $error++;
382 $this->errors [] = "Error ".$this->db->lasterror();
383 }
384
385 if (!$error) {
386 $this->id = $this->db->last_insert_id($this->db->prefix()."product_customer_price");
387
388 if (!$notrigger) {
389 $result = $this->call_trigger('PRODUCT_CUSTOMER_PRICE_CREATE', $user);
390 if ($result < 0) {
391 $error++;
392 }
393 }
394 }
395
396 if (!$error) {
397 $result = $this->setPriceOnAffiliateThirdparty($user, $forceupdateaffiliate);
398 if ($result < 0) {
399 $error++;
400 }
401 }
402
403 // Commit or rollback
404 if ($error) {
405 foreach ($this->errors as $errmsg) {
406 dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR);
407 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
408 }
409 $this->db->rollback();
410 return -1 * $error;
411 } else {
412 $this->db->commit();
413 return $this->id;
414 }
415 }
416
423 public function fetch($id)
424 {
425 global $langs;
426
427 $sql = "SELECT";
428 $sql .= " t.rowid,";
429 $sql .= " t.entity,";
430 $sql .= " t.datec,";
431 $sql .= " t.tms,";
432 $sql .= " t.fk_product,";
433 $sql .= " t.fk_soc,";
434 $sql .= " t.ref_customer,";
435 $sql .= " t.price,";
436 $sql .= " t.price_ttc,";
437 $sql .= " t.price_min,";
438 $sql .= " t.price_min_ttc,";
439 $sql .= " t.price_base_type,";
440 $sql .= " t.default_vat_code,";
441 $sql .= " t.tva_tx,";
442 $sql .= " t.recuperableonly,";
443 $sql .= " t.localtax1_tx,";
444 $sql .= " t.localtax2_tx,";
445 $sql .= " t.discount_percent,";
446 $sql .= " t.date_begin,";
447 $sql .= " t.date_end,";
448 $sql .= " t.fk_user,";
449 $sql .= " t.price_label,";
450 $sql .= " t.import_key";
451 $sql .= " FROM ".$this->db->prefix()."product_customer_price as t";
452 $sql .= " WHERE t.rowid = ".((int) $id);
453
454 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
455 $resql = $this->db->query($sql);
456 if ($resql) {
457 if ($this->db->num_rows($resql)) {
458 $obj = $this->db->fetch_object($resql);
459
460 $this->id = $obj->rowid;
461
462 $this->entity = $obj->entity;
463 $this->datec = $this->db->jdate($obj->datec);
464 $this->tms = $this->db->jdate($obj->tms);
465 $this->fk_product = $obj->fk_product;
466 $this->fk_soc = $obj->fk_soc;
467 $this->ref_customer = $obj->ref_customer;
468 $this->price = $obj->price;
469 $this->price_ttc = $obj->price_ttc;
470 $this->price_min = $obj->price_min;
471 $this->price_min_ttc = $obj->price_min_ttc;
472 $this->price_base_type = $obj->price_base_type;
473 $this->default_vat_code = $obj->default_vat_code;
474 $this->tva_tx = $obj->tva_tx;
475 $this->recuperableonly = $obj->recuperableonly;
476 $this->localtax1_tx = $obj->localtax1_tx;
477 $this->localtax2_tx = $obj->localtax2_tx;
478 $this->discount_percent = $obj->discount_percent;
479 $this->date_begin = $this->db->jdate($obj->date_begin);
480 $this->date_end = $this->db->jdate($obj->date_end);
481 $this->fk_user = $obj->fk_user;
482 $this->price_label = $obj->price_label;
483 $this->import_key = $obj->import_key;
484
485 $this->db->free($resql);
486
487 return 1;
488 } else {
489 $this->db->free($resql);
490
491 return 0;
492 }
493 } else {
494 $this->error = "Error ".$this->db->lasterror();
495 return -1;
496 }
497 }
498
510 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '')
511 {
512 if (empty($sortfield)) {
513 $sortfield = "t.date_begin";
514 }
515 if (empty($sortorder)) {
516 $sortorder = "DESC";
517 }
518
519 $sql = "SELECT";
520 $sql .= " t.rowid,";
521 $sql .= " t.entity,";
522 $sql .= " t.datec,";
523 $sql .= " t.tms,";
524 $sql .= " t.fk_product,";
525 $sql .= " t.fk_soc,";
526 $sql .= " t.ref_customer,";
527 $sql .= " t.price,";
528 $sql .= " t.price_ttc,";
529 $sql .= " t.price_min,";
530 $sql .= " t.price_min_ttc,";
531 $sql .= " t.price_base_type,";
532 $sql .= " t.default_vat_code,";
533 $sql .= " t.tva_tx,";
534 $sql .= " t.recuperableonly,";
535 $sql .= " t.localtax1_tx,";
536 $sql .= " t.localtax2_tx,";
537 $sql .= " t.localtax1_type,";
538 $sql .= " t.localtax2_type,";
539 $sql .= " t.discount_percent,";
540 $sql .= " t.date_begin,";
541 $sql .= " t.date_end,";
542 $sql .= " t.fk_user,";
543 $sql .= " t.price_label,";
544 $sql .= " t.import_key,";
545 $sql .= " soc.nom as socname,";
546 $sql .= " prod.ref as prodref";
547 $sql .= " FROM ".$this->db->prefix()."product_customer_price as t,";
548 $sql .= " ".$this->db->prefix()."product as prod,";
549 $sql .= " ".$this->db->prefix()."societe as soc";
550 $sql .= " WHERE soc.rowid=t.fk_soc ";
551 $sql .= " AND prod.rowid=t.fk_product ";
552 $sql .= " AND prod.entity IN (".getEntity('product').")";
553 $sql .= " AND t.entity IN (".getEntity('productprice').")";
554
555 // Manage filter
556 if (is_array($filter)) {
557 if (count($filter) > 0) {
558 foreach ($filter as $key => $value) {
559 if (strpos($key, 'date')) { // To allow $filter['YEAR(s.dated)']=>$year
560 $sql .= " AND ".$this->db->sanitize($key)." = '".$this->db->escape($value)."'";
561 } elseif ($key == 'soc.nom') {
562 $sql .= " AND ".$this->db->sanitize($key)." LIKE '%".$this->db->escape($this->db->escapeforlike($value))."%'";
563 } elseif ($key == 'prod.ref' || $key == 'prod.label') {
564 $sql .= " AND ".$this->db->sanitize($key)." LIKE '%".$this->db->escape($this->db->escapeforlike($value))."%'";
565 } elseif ($key == 't.price' || $key == 't.price_ttc' || $key == 't.discount_percent') {
566 $sql .= " AND ".$this->db->sanitize($key)." = ".((float) price2num($value));
567 } else {
568 $sql .= " AND ".$this->db->sanitize($key)." = ".((int) $value);
569 }
570 }
571 }
572
573 $filter = '';
574 }
575
576 // Manage filter
577 $errormessage = '';
578 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
579 if ($errormessage) {
580 $this->errors[] = $errormessage;
581 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
582 return -1;
583 }
584
585 $sql .= $this->db->order($sortfield, $sortorder);
586 if (!empty($limit)) {
587 $sql .= $this->db->plimit($limit + 1, $offset);
588 }
589
590 dol_syslog(get_class($this)."::fetchAll", LOG_DEBUG);
591 $resql = $this->db->query($sql);
592 if ($resql) {
593 $this->lines = array();
594 $num = $this->db->num_rows($resql);
595
596 while ($obj = $this->db->fetch_object($resql)) {
597 $line = new PriceByCustomerLine($this->db);
598
599 $line->id = $obj->rowid;
600
601 $line->entity = $obj->entity;
602 $line->datec = $this->db->jdate($obj->datec);
603 $line->tms = $this->db->jdate($obj->tms);
604 $line->fk_product = $obj->fk_product;
605 $line->fk_soc = $obj->fk_soc;
606 $line->ref_customer = $obj->ref_customer;
607 $line->price = $obj->price;
608 $line->price_ttc = $obj->price_ttc;
609 $line->price_min = $obj->price_min;
610 $line->price_min_ttc = $obj->price_min_ttc;
611 $line->price_base_type = $obj->price_base_type;
612 $line->default_vat_code = $obj->default_vat_code;
613 $line->tva_tx = $obj->tva_tx;
614 $line->recuperableonly = $obj->recuperableonly;
615 $line->localtax1_tx = $obj->localtax1_tx;
616 $line->localtax2_tx = $obj->localtax2_tx;
617 $line->localtax1_type = $obj->localtax1_type;
618 $line->localtax2_type = $obj->localtax2_type;
619 $line->discount_percent = $obj->discount_percent;
620 $line->date_begin = $this->db->jdate($obj->date_begin);
621 $line->date_end = $this->db->jdate($obj->date_end);
622 $line->fk_user = $obj->fk_user;
623 $line->price_label = $obj->price_label;
624 $line->import_key = $obj->import_key;
625 $line->socname = $obj->socname;
626 $line->prodref = $obj->prodref;
627
628 $this->lines[] = $line;
629 }
630 $this->db->free($resql);
631
632 return $num;
633 } else {
634 $this->error = "Error ".$this->db->lasterror();
635 return -1;
636 }
637 }
638
649 public function fetchAllLog($sortorder, $sortfield, $limit, $offset, $filter = array())
650 {
651 if (empty($sortfield)) {
652 $sortfield = "t.date_begin";
653 }
654 if (empty($sortorder)) {
655 $sortorder = "DESC";
656 }
657
658 $sql = "SELECT";
659 $sql .= " t.rowid,";
660 $sql .= " t.entity,";
661 $sql .= " t.datec,";
662 $sql .= " t.fk_product,";
663 $sql .= " t.fk_soc,";
664 $sql .= " t.ref_customer,";
665 $sql .= " t.price,";
666 $sql .= " t.price_ttc,";
667 $sql .= " t.price_min,";
668 $sql .= " t.price_min_ttc,";
669 $sql .= " t.price_base_type,";
670 $sql .= " t.default_vat_code,";
671 $sql .= " t.tva_tx,";
672 $sql .= " t.recuperableonly,";
673 $sql .= " t.localtax1_tx,";
674 $sql .= " t.localtax2_tx,";
675 $sql .= " t.discount_percent,";
676 $sql .= " t.date_begin,";
677 $sql .= " t.date_end,";
678 $sql .= " t.fk_user,";
679 $sql .= " t.price_label,";
680 $sql .= " t.import_key,";
681 $sql .= " soc.nom as socname,";
682 $sql .= " prod.ref as prodref";
683 $sql .= " FROM ".$this->db->prefix()."product_customer_price_log as t";
684 $sql .= " ,".$this->db->prefix()."product as prod";
685 $sql .= " ,".$this->db->prefix()."societe as soc";
686 $sql .= " WHERE soc.rowid=t.fk_soc";
687 $sql .= " AND prod.rowid=t.fk_product ";
688 $sql .= " AND prod.entity IN (".getEntity('product').")";
689 $sql .= " AND t.entity IN (".getEntity('productprice').")";
690 // Manage filter
691 if (count($filter) > 0) {
692 foreach ($filter as $key => $value) {
693 if (strpos($key, 'date')) { // To allow $filter['YEAR(s.dated)']=>$year
694 $sql .= " AND ".$this->db->sanitize($key)." = '".$this->db->escape($value)."'";
695 } elseif ($key == 'soc.nom') {
696 $sql .= " AND ".$this->db->sanitize($key)." LIKE '%".$this->db->escape($value)."%'";
697 } else {
698 $sql .= " AND ".$this->db->sanitize($key)." = ".((int) $value);
699 }
700 }
701 }
702 $sql .= $this->db->order($sortfield, $sortorder);
703 if (!empty($limit)) {
704 $sql .= $this->db->plimit($limit + 1, $offset);
705 }
706
707 dol_syslog(get_class($this)."::fetchAllLog", LOG_DEBUG);
708 $resql = $this->db->query($sql);
709 if ($resql) {
710 $this->lines = array();
711 $num = $this->db->num_rows($resql);
712
713 while ($obj = $this->db->fetch_object($resql)) {
714 $line = new PriceByCustomerLine($this->db);
715
716 $line->id = $obj->rowid;
717
718 $line->entity = $obj->entity;
719 $line->datec = $this->db->jdate($obj->datec);
720 $line->tms = $this->db->jdate($obj->tms);
721 $line->fk_product = $obj->fk_product;
722 $line->fk_soc = $obj->fk_soc;
723 $line->ref_customer = $obj->ref_customer;
724 $line->price = $obj->price;
725 $line->price_ttc = $obj->price_ttc;
726 $line->price_min = $obj->price_min;
727 $line->price_min_ttc = $obj->price_min_ttc;
728 $line->price_base_type = $obj->price_base_type;
729 $line->default_vat_code = $obj->default_vat_code;
730 $line->tva_tx = $obj->tva_tx;
731 $line->recuperableonly = $obj->recuperableonly;
732 $line->localtax1_tx = $obj->localtax1_tx;
733 $line->localtax2_tx = $obj->localtax2_tx;
734 $line->discount_percent = $obj->discount_percent;
735 $line->date_begin = $this->db->jdate($obj->date_begin);
736 $line->date_end = $this->db->jdate($obj->date_end);
737 $line->fk_user = $obj->fk_user;
738 $line->price_label = $obj->price_label;
739 $line->import_key = $obj->import_key;
740 $line->socname = $obj->socname;
741 $line->prodref = $obj->prodref;
742
743 $this->lines [] = $line;
744 }
745 $this->db->free($resql);
746
747 return $num;
748 } else {
749 $this->error = "Error ".$this->db->lasterror();
750 return -1;
751 }
752 }
753
762 public function update(User $user, $notrigger = 0, $forceupdateaffiliate = 0)
763 {
764 global $conf, $langs;
765 $error = 0;
766 $now = dol_now();
767
768 // Clean parameters
769
770 if (isset($this->entity)) {
771 $this->entity = (int) $this->entity;
772 }
773 if (isset($this->fk_product)) {
774 $this->fk_product = (int) $this->fk_product;
775 }
776 if (isset($this->fk_soc)) {
777 $this->fk_soc = (int) $this->fk_soc;
778 }
779 if (isset($this->ref_customer)) {
780 $this->ref_customer = trim($this->ref_customer);
781 }
782 if (isset($this->price)) {
783 $this->price = trim((string) $this->price);
784 }
785 if (isset($this->price_ttc)) {
786 $this->price_ttc = trim((string) $this->price_ttc);
787 }
788 if (isset($this->price_min)) {
789 $this->price_min = trim((string) $this->price_min);
790 }
791 if (isset($this->price_min_ttc)) {
792 $this->price_min_ttc = trim((string) $this->price_min_ttc);
793 }
794 if (isset($this->price_base_type)) {
795 $this->price_base_type = trim($this->price_base_type);
796 }
797 if (isset($this->tva_tx)) {
798 $this->tva_tx = trim($this->tva_tx);
799 }
800 if (isset($this->recuperableonly)) {
801 $this->recuperableonly = trim((string) $this->recuperableonly);
802 }
803 if (isset($this->localtax1_tx)) {
804 $this->localtax1_tx = trim((string) $this->localtax1_tx);
805 }
806 if (isset($this->localtax2_tx)) {
807 $this->localtax2_tx = trim((string) $this->localtax2_tx);
808 }
809 if (empty($this->discount_percent) || !is_numeric($this->discount_percent)) {
810 $this->discount_percent = 0;
811 }
812 if (empty($this->date_begin)) {
813 $this->date_begin = $now;
814 }
815 if (isset($this->fk_user)) {
816 $this->fk_user = (int) $this->fk_user;
817 }
818 if (isset($this->price_label)) {
819 $this->price_label = trim($this->price_label);
820 }
821 if (isset($this->import_key)) {
822 $this->import_key = trim($this->import_key);
823 }
824
825 // Check parameters
826 // Put here code to add a control on parameters values
827 $result = $this->verifyDates();
828 if ($result < 0) {
829 return -1;
830 }
831
832 if ($this->price != '' || $this->price == 0) {
833 $vatRate = (float) $this->tva_tx;
834 if ($this->price_base_type == 'TTC') {
835 $this->price_ttc = price2num($this->price, 'MU');
836 $this->price = (float) price2num($this->price) / (1 + ($vatRate / 100));
837 $this->price = price2num($this->price, 'MU');
838
839 if ($this->price_min != '' || $this->price_min == 0) {
840 $this->price_min_ttc = price2num($this->price_min, 'MU');
841 $this->price_min = (float) price2num($this->price_min) / (1 + ($vatRate / 100));
842 $this->price_min = price2num($this->price_min, 'MU');
843 } else {
844 $this->price_min = 0;
845 $this->price_min_ttc = 0;
846 }
847 } else {
848 $this->price = price2num($this->price, 'MU');
849 $this->price_ttc = ($this->recuperableonly != 1) ? (float) price2num($this->price) * (1 + ($vatRate / 100)) : $this->price;
850 $this->price_ttc = price2num($this->price_ttc, 'MU');
851
852 if ($this->price_min != '' || $this->price_min == 0) {
853 $this->price_min = price2num($this->price_min, 'MU');
854 $this->price_min_ttc = (float) price2num($this->price_min) * (1 + ($vatRate / 100));
855 $this->price_min_ttc = price2num($this->price_min_ttc, 'MU');
856 // print 'X'.$newminprice.'-'.$price_min;
857 } else {
858 $this->price_min = 0;
859 $this->price_min_ttc = 0;
860 }
861 }
862 }
863
864 // Do a copy of current record into log table
865 // Insert request
866 $sql = "INSERT INTO ".$this->db->prefix()."product_customer_price_log(";
867
868 $sql .= "entity,";
869 $sql .= "datec,";
870 $sql .= "fk_product,";
871 $sql .= "fk_soc,";
872 $sql .= "ref_customer,";
873 $sql .= "price,";
874 $sql .= "price_ttc,";
875 $sql .= "price_min,";
876 $sql .= "price_min_ttc,";
877 $sql .= "price_base_type,";
878 $sql .= "default_vat_code,";
879 $sql .= "tva_tx,";
880 $sql .= "recuperableonly,";
881 $sql .= "localtax1_tx,";
882 $sql .= "localtax2_tx,";
883 $sql .= "localtax1_type,";
884 $sql .= "localtax2_type,";
885 $sql .= "discount_percent,";
886 $sql .= "date_begin,";
887 $sql .= "date_end,";
888 $sql .= "fk_user,";
889 $sql .= "price_label,";
890 $sql .= "import_key";
891
892 $sql .= ") ";
893 $sql .= "SELECT";
894
895 $sql .= " t.entity,";
896 $sql .= " t.datec,";
897 $sql .= " t.fk_product,";
898 $sql .= " t.fk_soc,";
899 $sql .= " t.ref_customer,";
900 $sql .= " t.price,";
901 $sql .= " t.price_ttc,";
902 $sql .= " t.price_min,";
903 $sql .= " t.price_min_ttc,";
904 $sql .= " t.price_base_type,";
905 $sql .= " t.default_vat_code,";
906 $sql .= " t.tva_tx,";
907 $sql .= " t.recuperableonly,";
908 $sql .= " t.localtax1_tx,";
909 $sql .= " t.localtax2_tx,";
910 $sql .= " t.localtax1_type,";
911 $sql .= " t.localtax2_type,";
912 $sql .= " t.discount_percent,";
913 $sql .= " t.date_begin,";
914 $sql .= " t.date_end,";
915 $sql .= " t.fk_user,";
916 $sql .= " t.price_label,";
917 $sql .= " t.import_key";
918
919 $sql .= " FROM ".$this->db->prefix()."product_customer_price as t";
920 $sql .= " WHERE t.rowid = ".((int) $this->id);
921
922 $this->db->begin();
923 dol_syslog(get_class($this)."::update", LOG_DEBUG);
924 $resql = $this->db->query($sql);
925 if (!$resql) {
926 $error++;
927 $this->errors [] = "Error ".$this->db->lasterror();
928 }
929
930 // Update request
931 $sql = "UPDATE ".$this->db->prefix()."product_customer_price SET";
932
933 $sql .= " entity=".((int) $conf->entity).",";
934 $sql .= " datec='".$this->db->idate($now)."',";
935 $sql .= " tms=".(dol_strlen((string) $this->tms) != 0 ? "'".$this->db->idate($this->tms)."'" : 'null').",";
936 $sql .= " fk_product=".(isset($this->fk_product) ? $this->fk_product : "null").",";
937 $sql .= " fk_soc=".(isset($this->fk_soc) ? $this->fk_soc : "null").",";
938 $sql .= " ref_customer=".(isset($this->ref_customer) ? "'".$this->db->escape($this->ref_customer)."'" : "null").",";
939 $sql .= " price=".(isset($this->price) ? $this->price : "null").",";
940 $sql .= " price_ttc=".(isset($this->price_ttc) ? $this->price_ttc : "null").",";
941 $sql .= " price_min=".(isset($this->price_min) ? $this->price_min : "null").",";
942 $sql .= " price_min_ttc=".(isset($this->price_min_ttc) ? $this->price_min_ttc : "null").",";
943 $sql .= " price_base_type=".(isset($this->price_base_type) ? "'".$this->db->escape($this->price_base_type)."'" : "null").",";
944 $sql .= " default_vat_code = ".($this->default_vat_code ? "'".$this->db->escape($this->default_vat_code)."'" : "null").",";
945 $sql .= " tva_tx=".(isset($this->tva_tx) ? (empty($this->tva_tx) ? 0 : $this->tva_tx) : "null").",";
946 $sql .= " recuperableonly=".(isset($this->recuperableonly) ? $this->recuperableonly : "null").",";
947 $sql .= " localtax1_tx=".(isset($this->localtax1_tx) ? (empty($this->localtax1_tx) ? 0 : $this->localtax1_tx) : "null").",";
948 $sql .= " localtax2_tx=".(isset($this->localtax2_tx) ? (empty($this->localtax2_tx) ? 0 : $this->localtax2_tx) : "null").",";
949 $sql .= " localtax1_type=".(!empty($this->localtax1_type) ? "'".$this->db->escape($this->localtax1_type)."'" : "'0'").",";
950 $sql .= " localtax2_type=".(!empty($this->localtax2_type) ? "'".$this->db->escape($this->localtax2_type)."'" : "'0'").",";
951 $sql .= " discount_percent=".(!empty($this->discount_percent) ? "'".price2num($this->discount_percent)."'" : "0").",";
952 $sql .= " date_begin='".$this->db->idate($this->date_begin)."',";
953 $sql .= " date_end=".(!empty($this->date_end) ? "'".$this->db->idate($this->date_end)."'" : "null").",";
954 $sql .= " fk_user=".((int) $user->id).",";
955 $sql .= " price_label=".(isset($this->price_label) ? "'".$this->db->escape($this->price_label)."'" : "null").",";
956 $sql .= " import_key=".(isset($this->import_key) ? "'".$this->db->escape($this->import_key)."'" : "null");
957
958 $sql .= " WHERE rowid=".((int) $this->id);
959
960 dol_syslog(get_class($this)."::update", LOG_DEBUG);
961 $resql = $this->db->query($sql);
962 if (!$resql) {
963 $error++;
964 $this->errors [] = "Error ".$this->db->lasterror();
965 }
966
967 if (!$error && !$notrigger) {
968 // Call trigger
969 $result = $this->call_trigger('PRODUCT_CUSTOMER_PRICE_MODIFY', $user);
970 if ($result < 0) {
971 $error++;
972 }
973 // End call triggers
974 }
975
976 if (!$error) {
977 $result = $this->setPriceOnAffiliateThirdparty($user, $forceupdateaffiliate);
978 if ($result < 0) {
979 $error++;
980 }
981 }
982
983 // Commit or rollback
984 if ($error) {
985 foreach ($this->errors as $errmsg) {
986 dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
987 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
988 }
989 $this->db->rollback();
990 return -1 * $error;
991 } else {
992 $this->db->commit();
993 return 1;
994 }
995 }
996
1004 public function setPriceOnAffiliateThirdparty($user, $forceupdateaffiliate)
1005 {
1006 if (getDolGlobalString('PRODUCT_DISABLE_PROPAGATE_CUSTOMER_PRICES_ON_CHILD_COMPANIES')) {
1007 return 0;
1008 }
1009
1010 $error = 0;
1011
1012 // Find all susidiaries
1013 $sql = "SELECT s.rowid";
1014 $sql .= " FROM ".$this->db->prefix()."societe as s";
1015 $sql .= " WHERE s.parent = ".((int) $this->fk_soc);
1016 $sql .= " AND s.entity IN (".getEntity('societe').")";
1017
1018 dol_syslog(get_class($this)."::setPriceOnAffiliateThirdparty", LOG_DEBUG);
1019 $resql = $this->db->query($sql);
1020
1021 if ($resql) {
1022 $this->lines = array();
1023 $num = $this->db->num_rows($resql);
1024
1025 while (($obj = $this->db->fetch_object($resql)) && (empty($error))) {
1026 // find if there is an existing line for the product and the subsidiaries
1027 $prodsocprice = new ProductCustomerPrice($this->db);
1028
1029 $filter = array(
1030 't.fk_product' => (string) $this->fk_product, 't.fk_soc' => (string) $obj->rowid
1031 );
1032
1033 $result = $prodsocprice->fetchAll('', '', 0, 0, $filter);
1034 if ($result < 0) {
1035 $error++;
1036 $this->error = $prodsocprice->error;
1037 } else {
1038 // There is one line
1039 if (count($prodsocprice->lines) > 0) {
1040 // If force update => Update
1041 if (!empty($forceupdateaffiliate)) {
1042 $prodsocpriceupd = new ProductCustomerPrice($this->db);
1043 $prodsocpriceupd->fetch($prodsocprice->lines [0]->id);
1044
1045 $prodsocpriceupd->price = $this->price;
1046 $prodsocpriceupd->price_min = $this->price_min;
1047 $prodsocpriceupd->price_base_type = $this->price_base_type;
1048 $prodsocpriceupd->tva_tx = $this->tva_tx;
1049 $prodsocpriceupd->recuperableonly = $this->recuperableonly;
1050 $prodsocpriceupd->price_label = $this->price_label;
1051 $prodsocpriceupd->discount_percent = $this->discount_percent;
1052 $prodsocpriceupd->date_begin = $this->date_begin;
1053 $prodsocpriceupd->date_end = $this->date_end;
1054
1055 $resultupd = $prodsocpriceupd->update($user, 0, $forceupdateaffiliate);
1056 if ($resultupd < 0) {
1057 $error++;
1058 $this->error = $prodsocpriceupd->error;
1059 }
1060 }
1061 } else {
1062 // If line do not exits then create it
1063 $prodsocpricenew = new ProductCustomerPrice($this->db);
1064 $prodsocpricenew->fk_soc = $obj->rowid;
1065 $prodsocpricenew->ref_customer = $obj->ref_customer;
1066 $prodsocpricenew->fk_product = $this->fk_product;
1067 $prodsocpricenew->price = $this->price;
1068 $prodsocpricenew->price_min = $this->price_min;
1069 $prodsocpricenew->price_base_type = $this->price_base_type;
1070 $prodsocpricenew->tva_tx = $this->tva_tx;
1071 $prodsocpricenew->recuperableonly = $this->recuperableonly;
1072 $prodsocpricenew->price_label = $this->price_label;
1073 $prodsocpricenew->discount_percent = $this->discount_percent;
1074 $prodsocpricenew->date_begin = $this->date_begin;
1075 $prodsocpricenew->date_end = $this->date_end;
1076
1077 $resultupd = $prodsocpricenew->create($user, 0, $forceupdateaffiliate);
1078 if ($resultupd < 0) {
1079 $error++;
1080 $this->error = $prodsocpricenew->error;
1081 }
1082 }
1083 }
1084 }
1085 $this->db->free($resql);
1086
1087 if (empty($error)) {
1088 return 1;
1089 } else {
1090 return -1;
1091 }
1092 } else {
1093 $this->error = "Error ".$this->db->lasterror();
1094 return -1;
1095 }
1096 }
1097
1105 public function delete($user, $notrigger = 0)
1106 {
1107 global $conf, $langs;
1108 $error = 0;
1109
1110 $this->db->begin();
1111
1112 if (!$notrigger) {
1113 $result = $this->call_trigger('PRODUCT_CUSTOMER_PRICE_DELETE', $user);
1114 if ($result < 0) {
1115 $error++;
1116 }
1117 }
1118
1119 if (!$error) {
1120 $sql = "DELETE FROM ".$this->db->prefix()."product_customer_price";
1121 $sql .= " WHERE rowid=".((int) $this->id);
1122
1123 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1124 $resql = $this->db->query($sql);
1125 if (!$resql) {
1126 $error++;
1127 $this->errors [] = "Error ".$this->db->lasterror();
1128 }
1129 }
1130
1131 // Commit or rollback
1132 if ($error) {
1133 foreach ($this->errors as $errmsg) {
1134 dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
1135 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1136 }
1137 $this->db->rollback();
1138 return -1 * $error;
1139 } else {
1140 $this->db->commit();
1141 return 1;
1142 }
1143 }
1144
1152 public function createFromClone(User $user, $fromid)
1153 {
1154 $error = 0;
1155
1156 $object = new ProductCustomerPrice($this->db);
1157
1158 $this->db->begin();
1159
1160 // Load source object
1161 $object->fetch($fromid);
1162 $object->id = 0;
1163 $object->statut = 0;
1164
1165 // Clear fields
1166 // ...
1167
1168 // Create clone
1169 $object->context['createfromclone'] = 'createfromclone';
1170 $result = $object->create($user);
1171
1172 // Other options
1173 if ($result < 0) {
1174 $this->error = $object->error;
1175 $this->errors = array_merge($this->errors, $object->errors);
1176 $error++;
1177 }
1178
1179 if (!$error) {
1180 }
1181
1182 unset($object->context['createfromclone']);
1183
1184 // End
1185 if (!$error) {
1186 $this->db->commit();
1187 return $object->id;
1188 } else {
1189 $this->db->rollback();
1190 return -1;
1191 }
1192 }
1193
1200 public function initAsSpecimen()
1201 {
1202 $this->id = 0;
1203
1204 $this->entity = 0;
1205 $this->datec = '';
1206 $this->tms = dol_now();
1207 $this->fk_product = 0;
1208 $this->fk_soc = 0;
1209 $this->ref_customer = '';
1210 $this->price = '';
1211 $this->price_ttc = '';
1212 $this->price_min = '';
1213 $this->price_min_ttc = '';
1214 $this->price_base_type = '';
1215 $this->default_vat_code = '';
1216 $this->tva_tx = '';
1217 $this->recuperableonly = '';
1218 $this->localtax1_tx = '';
1219 $this->localtax2_tx = '';
1220 $this->discount_percent = '';
1221 $this->date_begin = '';
1222 $this->date_end = '';
1223 $this->fk_user = 0;
1224 $this->price_label = '';
1225 $this->import_key = '';
1226
1227 return 1;
1228 }
1229}
1230
1235{
1239 public $id;
1240
1244 public $entity;
1245
1249 public $datec = '';
1250
1254 public $fk_product;
1255
1259 public $ref_customer;
1260
1264 public $fk_soc;
1265
1269 public $price;
1273 public $price_ttc;
1277 public $price_min;
1281 public $price_min_ttc;
1285 public $price_base_type;
1289 public $default_vat_code;
1293 public $tva_tx;
1297 public $recuperableonly;
1301 public $localtax1_tx;
1305 public $localtax2_tx;
1309 public $discount_percent;
1313 public $date_begin = '';
1317 public $date_end = '';
1318
1322 public $fk_user;
1326 public $price_label;
1327
1331 public $import_key;
1335 public $socname;
1339 public $prodref;
1340}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
Parent class of all other business classes (invoices, contracts, proposals, orders,...
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
File of class to manage predefined price products or services by customer lines.
File of class to manage predefined price products or services by customer.
create($user, $notrigger=0, $forceupdateaffiliate=0)
Create object into database.
fetch($id)
Load object in memory from the database.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
fetchAllLog($sortorder, $sortfield, $limit, $offset, $filter=array())
Load all objects in memory from database.
update(User $user, $notrigger=0, $forceupdateaffiliate=0)
Update object into database.
verifyDates()
Check if begin and end dates intersect other dates periods.
createFromClone(User $user, $fromid)
Load an object from its id and create a new one in database.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter='')
Load all customer prices in memory from database.
setPriceOnAffiliateThirdparty($user, $forceupdateaffiliate)
Force update price on child companies so child company has same prices than parent.
Class to manage Dolibarr users.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
dol_now($mode='auto')
Return date for now.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79