dolibarr 23.0.3
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-2025 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' => 'isModEnabled("product")', '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 $datec = '';
68
72 public $fk_product;
73
77 public $fk_soc;
78
82 public $ref_customer;
83
87 public $price;
91 public $price_ttc;
95 public $price_min;
99 public $price_min_ttc;
103 public $price_base_type;
107 public $default_vat_code;
111 public $tva_tx;
115 public $recuperableonly;
119 public $localtax1_type;
123 public $localtax1_tx;
127 public $localtax2_type;
131 public $localtax2_tx;
135 public $price_label;
139 public $discount_percent;
143 public $date_begin = '';
147 public $date_end = '';
148
152 public $fk_user;
153
157 public $lines = array();
158
159
165 public function __construct($db)
166 {
167 $this->db = $db;
168 }
169
175 public function verifyDates()
176 {
177 global $langs;
178
179 $sql = "SELECT COUNT(*) AS nb";
180 $sql .= " FROM " . $this->db->prefix() . "product_customer_price as t";
181 $sql .= " WHERE (t.date_begin = '" . $this->db->idate($this->date_begin) . "' OR t.date_end = '" . $this->db->idate($this->date_begin) . "'";
182 $sql .= " OR t.date_begin = '" . $this->db->idate($this->date_end) . "' OR t.date_end = '" . $this->db->idate($this->date_end) . "'";
183 $sql .= " OR (t.date_begin <= '" . $this->db->idate($this->date_begin) . "' AND '" . $this->db->idate($this->date_begin) . "' <= t.date_end)";
184 $sql .= " OR (t.date_begin <= '" . $this->db->idate($this->date_end) . "' AND '" . $this->db->idate($this->date_end) . "' <= t.date_end))";
185 if ($this->fk_product > 0) {
186 $sql .= " AND t.fk_product = " . ((int) $this->fk_product);
187 }
188 if ($this->fk_soc > 0) {
189 $sql .= " AND t.fk_soc = " . ((int) $this->fk_soc);
190 }
191 if ($this->id > 0) {
192 $sql .= " AND t.rowid != " . ((int) $this->id);
193 }
194
195 dol_syslog(get_class($this) . "::fetch", LOG_DEBUG);
196 $resql = $this->db->query($sql);
197 if (!$resql) {
198 $this->errors[] = "Error " . $this->db->lasterror();
199 return -1;
200 }
201
202 $nb = 0;
203 if ($obj = $this->db->fetch_object($resql)) {
204 $nb = (int) $obj->nb;
205 }
206 $this->db->free($resql);
207
208 if ($nb > 0) {
209 $this->errors[] = $langs->trans('ErrorAppliedPricesIntersectAnotherPeriod');
210 return -1;
211 }
212
213 return 1;
214 }
215
224 public function create($user, $notrigger = 0, $forceupdateaffiliate = 0)
225 {
226 global $conf;
227 $error = 0;
228 $now = dol_now();
229
230 // Clean parameters
231
232 if (isset($this->entity)) {
233 $this->entity = (int) $this->entity;
234 }
235 if (isset($this->fk_product)) {
236 $this->fk_product = (int) $this->fk_product;
237 }
238 if (isset($this->fk_soc)) {
239 $this->fk_soc = (int) $this->fk_soc;
240 }
241 if (isset($this->ref_customer)) {
242 $this->ref_customer = trim($this->ref_customer);
243 }
244 if (isset($this->price)) {
245 $this->price = trim($this->price);
246 }
247 if (isset($this->price_ttc)) {
248 $this->price_ttc = trim($this->price_ttc);
249 }
250 if (isset($this->price_min)) {
251 $this->price_min = trim($this->price_min);
252 }
253 if (isset($this->price_min_ttc)) {
254 $this->price_min_ttc = trim($this->price_min_ttc);
255 }
256 if (isset($this->price_base_type)) {
257 $this->price_base_type = trim($this->price_base_type);
258 }
259 if (isset($this->tva_tx)) {
260 $this->tva_tx = trim($this->tva_tx);
261 }
262 if (isset($this->recuperableonly)) {
263 $this->recuperableonly = trim($this->recuperableonly);
264 }
265 if (isset($this->localtax1_tx)) {
266 $this->localtax1_tx = trim($this->localtax1_tx);
267 }
268 if (isset($this->localtax2_tx)) {
269 $this->localtax2_tx = trim($this->localtax2_tx);
270 }
271 if (empty($this->discount_percent) || !is_numeric($this->discount_percent)) {
272 $this->discount_percent = 0;
273 }
274 if (empty($this->date_begin)) {
275 $this->date_begin = $now;
276 }
277 if (isset($this->fk_user)) {
278 $this->fk_user = (int) $this->fk_user;
279 }
280 if (isset($this->price_label)) {
281 $this->price_label = trim($this->price_label);
282 }
283 if (isset($this->import_key)) {
284 $this->import_key = trim($this->import_key);
285 }
286
287 // Check parameters
288 // Put here code to add control on parameters values
289 $result = $this->verifyDates();
290 if ($result < 0) {
291 return -1;
292 }
293
294 if ($this->price != '' || $this->price == 0) {
295 $vatRate = (float) $this->tva_tx;
296 if ($this->price_base_type == 'TTC') {
297 $this->price_ttc = price2num($this->price, 'MU');
298 $this->price = (float) price2num($this->price) / (1 + ($vatRate / 100));
299 $this->price = price2num($this->price, 'MU');
300
301 if ($this->price_min != '' || $this->price_min == 0) {
302 $this->price_min_ttc = price2num($this->price_min, 'MU');
303 $this->price_min = (float) price2num($this->price_min) / (1 + ($vatRate / 100));
304 $this->price_min = price2num($this->price_min, 'MU');
305 } else {
306 $this->price_min = 0;
307 $this->price_min_ttc = 0;
308 }
309 } else {
310 $this->price = price2num($this->price, 'MU');
311 $this->price_ttc = ($this->recuperableonly != 1) ? (float) price2num($this->price) * (1 + ($vatRate / 100)) : $this->price;
312 $this->price_ttc = price2num($this->price_ttc, 'MU');
313
314 if ($this->price_min != '' || $this->price_min == 0) {
315 $this->price_min = price2num($this->price_min, 'MU');
316 $this->price_min_ttc = (float) price2num($this->price_min) * (1 + ($vatRate / 100));
317 $this->price_min_ttc = price2num($this->price_min_ttc, 'MU');
318 // print 'X'.$newminprice.'-'.$price_min;
319 } else {
320 $this->price_min = 0;
321 $this->price_min_ttc = 0;
322 }
323 }
324 }
325
326 // Insert request
327 $sql = "INSERT INTO ".$this->db->prefix()."product_customer_price(";
328 $sql .= "entity,";
329 $sql .= "datec,";
330 $sql .= "fk_product,";
331 $sql .= "fk_soc,";
332 $sql .= 'ref_customer,';
333 $sql .= "price,";
334 $sql .= "price_ttc,";
335 $sql .= "price_min,";
336 $sql .= "price_min_ttc,";
337 $sql .= "price_base_type,";
338 $sql .= "default_vat_code,";
339 $sql .= "tva_tx,";
340 $sql .= "recuperableonly,";
341 $sql .= "localtax1_type,";
342 $sql .= "localtax1_tx,";
343 $sql .= "localtax2_type,";
344 $sql .= "localtax2_tx,";
345 $sql .= "discount_percent,";
346 $sql .= "date_begin,";
347 $sql .= "date_end,";
348 $sql .= "fk_user,";
349 $sql .= "price_label,";
350 $sql .= "import_key";
351 $sql .= ") VALUES (";
352 $sql .= " ".((int) $conf->entity).",";
353 $sql .= " '".$this->db->idate($now)."',";
354 $sql .= " ".(!isset($this->fk_product) ? 'NULL' : ((int) $this->fk_product)).",";
355 $sql .= " ".(!isset($this->fk_soc) ? 'NULL' : ((int) $this->fk_soc)).",";
356 $sql .= " ".(!isset($this->ref_customer) ? 'NULL' : "'".$this->db->escape($this->ref_customer)."'").",";
357 $sql .= " ".(empty($this->price) ? '0' : "'".$this->db->escape($this->price)."'").",";
358 $sql .= " ".(empty($this->price_ttc) ? '0' : "'".$this->db->escape($this->price_ttc)."'").",";
359 $sql .= " ".(empty($this->price_min) ? '0' : "'".$this->db->escape($this->price_min)."'").",";
360 $sql .= " ".(empty($this->price_min_ttc) ? '0' : "'".$this->db->escape($this->price_min_ttc)."'").",";
361 $sql .= " ".(!isset($this->price_base_type) ? 'NULL' : "'".$this->db->escape($this->price_base_type)."'").",";
362 $sql .= " ".($this->default_vat_code ? "'".$this->db->escape($this->default_vat_code)."'" : "null").",";
363 $sql .= " ".(!isset($this->tva_tx) ? 'NULL' : (empty($this->tva_tx) ? 0 : $this->tva_tx)).",";
364 $sql .= " ".(!isset($this->recuperableonly) ? 'NULL' : "'".$this->db->escape($this->recuperableonly)."'").",";
365 $sql .= " ".(empty($this->localtax1_type) ? "'0'" : "'".$this->db->escape($this->localtax1_type)."'").",";
366 $sql .= " ".(!isset($this->localtax1_tx) ? 'NULL' : (empty($this->localtax1_tx) ? "'0'" : "'".$this->db->escape($this->localtax1_tx)."'")).",";
367 $sql .= " ".(empty($this->localtax2_type) ? "'0'" : "'".$this->db->escape($this->localtax2_type)."'").",";
368 $sql .= " ".(!isset($this->localtax2_tx) ? 'NULL' : (empty($this->localtax2_tx) ? "'0'" : "'".$this->db->escape($this->localtax2_tx)."'")).",";
369 $sql .= " ".(empty($this->discount_percent) ? '0' : "'".$this->db->escape(price2num($this->discount_percent))."'").",";
370 $sql .= " '".$this->db->idate($this->date_begin)."',";
371 $sql .= " ".(empty($this->date_end) ? 'NULL' : "'".$this->db->idate($this->date_end)."'").",";
372 $sql .= " ".((int) $user->id).",";
373 $sql .= " ".(!isset($this->price_label) ? 'NULL' : "'".$this->db->escape($this->price_label)."'").",";
374 $sql .= " ".(!isset($this->import_key) ? 'NULL' : "'".$this->db->escape($this->import_key)."'");
375 $sql .= ")";
376
377 $this->db->begin();
378
379 dol_syslog(get_class($this)."::create", LOG_DEBUG);
380 $resql = $this->db->query($sql);
381 if (!$resql) {
382 $error++;
383 $this->errors [] = "Error ".$this->db->lasterror();
384 }
385
386 if (!$error) {
387 $this->id = $this->db->last_insert_id($this->db->prefix()."product_customer_price");
388
389 if (!$notrigger) {
390 $result = $this->call_trigger('PRODUCT_CUSTOMER_PRICE_CREATE', $user);
391 if ($result < 0) {
392 $error++;
393 }
394 }
395 }
396
397 if (!$error) {
398 $result = $this->setPriceOnAffiliateThirdparty($user, $forceupdateaffiliate);
399 if ($result < 0) {
400 $error++;
401 }
402 }
403
404 // Commit or rollback
405 if ($error) {
406 foreach ($this->errors as $errmsg) {
407 dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR);
408 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
409 }
410 $this->db->rollback();
411 return -1 * $error;
412 } else {
413 $this->db->commit();
414 return $this->id;
415 }
416 }
417
424 public function fetch($id)
425 {
426 $sql = "SELECT";
427 $sql .= " t.rowid,";
428 $sql .= " t.entity,";
429 $sql .= " t.datec,";
430 $sql .= " t.tms,";
431 $sql .= " t.fk_product,";
432 $sql .= " t.fk_soc,";
433 $sql .= " t.ref_customer,";
434 $sql .= " t.price,";
435 $sql .= " t.price_ttc,";
436 $sql .= " t.price_min,";
437 $sql .= " t.price_min_ttc,";
438 $sql .= " t.price_base_type,";
439 $sql .= " t.default_vat_code,";
440 $sql .= " t.tva_tx,";
441 $sql .= " t.recuperableonly,";
442 $sql .= " t.localtax1_tx,";
443 $sql .= " t.localtax2_tx,";
444 $sql .= " t.discount_percent,";
445 $sql .= " t.date_begin,";
446 $sql .= " t.date_end,";
447 $sql .= " t.fk_user,";
448 $sql .= " t.price_label,";
449 $sql .= " t.import_key";
450 $sql .= " FROM ".$this->db->prefix()."product_customer_price as t";
451 $sql .= " WHERE t.rowid = ".((int) $id);
452
453 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
454 $resql = $this->db->query($sql);
455 if ($resql) {
456 if ($this->db->num_rows($resql)) {
457 $obj = $this->db->fetch_object($resql);
458
459 $this->id = $obj->rowid;
460
461 $this->entity = $obj->entity;
462 $this->datec = $this->db->jdate($obj->datec);
463 $this->tms = $this->db->jdate($obj->tms);
464 $this->date_modification = $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->date_modification = $this->db->jdate($obj->tms);
605 $line->fk_product = $obj->fk_product;
606 $line->fk_soc = $obj->fk_soc;
607 $line->ref_customer = $obj->ref_customer;
608 $line->price = $obj->price;
609 $line->price_ttc = $obj->price_ttc;
610 $line->price_min = $obj->price_min;
611 $line->price_min_ttc = $obj->price_min_ttc;
612 $line->price_base_type = $obj->price_base_type;
613 $line->default_vat_code = $obj->default_vat_code;
614 $line->tva_tx = $obj->tva_tx;
615 $line->recuperableonly = $obj->recuperableonly;
616 $line->localtax1_tx = $obj->localtax1_tx;
617 $line->localtax2_tx = $obj->localtax2_tx;
618 $line->localtax1_type = $obj->localtax1_type;
619 $line->localtax2_type = $obj->localtax2_type;
620 $line->discount_percent = $obj->discount_percent;
621 $line->date_begin = $this->db->jdate($obj->date_begin);
622 $line->date_end = $this->db->jdate($obj->date_end);
623 $line->fk_user = $obj->fk_user;
624 $line->price_label = $obj->price_label;
625 $line->import_key = $obj->import_key;
626 $line->socname = $obj->socname;
627 $line->prodref = $obj->prodref;
628
629 $this->lines[] = $line;
630 }
631 $this->db->free($resql);
632
633 return $num;
634 } else {
635 $this->error = "Error ".$this->db->lasterror();
636 return -1;
637 }
638 }
639
650 public function fetchAllLog($sortorder, $sortfield, $limit, $offset, $filter = array())
651 {
652 if (empty($sortfield)) {
653 $sortfield = "t.date_begin";
654 }
655 if (empty($sortorder)) {
656 $sortorder = "DESC";
657 }
658
659 $sql = "SELECT";
660 $sql .= " t.rowid,";
661 $sql .= " t.entity,";
662 $sql .= " t.datec,";
663 $sql .= " t.fk_product,";
664 $sql .= " t.fk_soc,";
665 $sql .= " t.ref_customer,";
666 $sql .= " t.price,";
667 $sql .= " t.price_ttc,";
668 $sql .= " t.price_min,";
669 $sql .= " t.price_min_ttc,";
670 $sql .= " t.price_base_type,";
671 $sql .= " t.default_vat_code,";
672 $sql .= " t.tva_tx,";
673 $sql .= " t.recuperableonly,";
674 $sql .= " t.localtax1_tx,";
675 $sql .= " t.localtax2_tx,";
676 $sql .= " t.discount_percent,";
677 $sql .= " t.date_begin,";
678 $sql .= " t.date_end,";
679 $sql .= " t.fk_user,";
680 $sql .= " t.price_label,";
681 $sql .= " t.import_key,";
682 $sql .= " soc.nom as socname,";
683 $sql .= " prod.ref as prodref";
684 $sql .= " FROM ".$this->db->prefix()."product_customer_price_log as t";
685 $sql .= " ,".$this->db->prefix()."product as prod";
686 $sql .= " ,".$this->db->prefix()."societe as soc";
687 $sql .= " WHERE soc.rowid=t.fk_soc";
688 $sql .= " AND prod.rowid=t.fk_product ";
689 $sql .= " AND prod.entity IN (".getEntity('product').")";
690 $sql .= " AND t.entity IN (".getEntity('productprice').")";
691 // Manage filter
692 if (count($filter) > 0) {
693 foreach ($filter as $key => $value) {
694 if (strpos($key, 'date')) { // To allow $filter['YEAR(s.dated)']=>$year
695 $sql .= " AND ".$this->db->sanitize($key)." = '".$this->db->escape($value)."'";
696 } elseif ($key == 'soc.nom') {
697 $sql .= " AND ".$this->db->sanitize($key)." LIKE '%".$this->db->escape($value)."%'";
698 } else {
699 $sql .= " AND ".$this->db->sanitize($key)." = ".((int) $value);
700 }
701 }
702 }
703 $sql .= $this->db->order($sortfield, $sortorder);
704 if (!empty($limit)) {
705 $sql .= $this->db->plimit($limit + 1, $offset);
706 }
707
708 dol_syslog(get_class($this)."::fetchAllLog", LOG_DEBUG);
709 $resql = $this->db->query($sql);
710 if ($resql) {
711 $this->lines = array();
712 $num = $this->db->num_rows($resql);
713
714 while ($obj = $this->db->fetch_object($resql)) {
715 $line = new PriceByCustomerLine($this->db);
716
717 $line->id = $obj->rowid;
718
719 $line->entity = $obj->entity;
720 $line->datec = $this->db->jdate($obj->datec);
721 $line->tms = $this->db->jdate($obj->tms);
722 $line->date_modification = $this->db->jdate($obj->tms);
723 $line->fk_product = $obj->fk_product;
724 $line->fk_soc = $obj->fk_soc;
725 $line->ref_customer = $obj->ref_customer;
726 $line->price = $obj->price;
727 $line->price_ttc = $obj->price_ttc;
728 $line->price_min = $obj->price_min;
729 $line->price_min_ttc = $obj->price_min_ttc;
730 $line->price_base_type = $obj->price_base_type;
731 $line->default_vat_code = $obj->default_vat_code;
732 $line->tva_tx = $obj->tva_tx;
733 $line->recuperableonly = $obj->recuperableonly;
734 $line->localtax1_tx = $obj->localtax1_tx;
735 $line->localtax2_tx = $obj->localtax2_tx;
736 $line->discount_percent = $obj->discount_percent;
737 $line->date_begin = $this->db->jdate($obj->date_begin);
738 $line->date_end = $this->db->jdate($obj->date_end);
739 $line->fk_user = $obj->fk_user;
740 $line->price_label = $obj->price_label;
741 $line->import_key = $obj->import_key;
742 $line->socname = $obj->socname;
743 $line->prodref = $obj->prodref;
744
745 $this->lines [] = $line;
746 }
747 $this->db->free($resql);
748
749 return $num;
750 } else {
751 $this->error = "Error ".$this->db->lasterror();
752 return -1;
753 }
754 }
755
764 public function update(User $user, $notrigger = 0, $forceupdateaffiliate = 0)
765 {
766 global $conf;
767 $error = 0;
768 $now = dol_now();
769
770 // Clean parameters
771
772 if (isset($this->entity)) {
773 $this->entity = (int) $this->entity;
774 }
775 if (isset($this->fk_product)) {
776 $this->fk_product = (int) $this->fk_product;
777 }
778 if (isset($this->fk_soc)) {
779 $this->fk_soc = (int) $this->fk_soc;
780 }
781 if (isset($this->ref_customer)) {
782 $this->ref_customer = trim($this->ref_customer);
783 }
784 if (isset($this->price)) {
785 $this->price = trim((string) $this->price);
786 }
787 if (isset($this->price_ttc)) {
788 $this->price_ttc = trim((string) $this->price_ttc);
789 }
790 if (isset($this->price_min)) {
791 $this->price_min = trim((string) $this->price_min);
792 }
793 if (isset($this->price_min_ttc)) {
794 $this->price_min_ttc = trim((string) $this->price_min_ttc);
795 }
796 if (isset($this->price_base_type)) {
797 $this->price_base_type = trim($this->price_base_type);
798 }
799 if (isset($this->tva_tx)) {
800 $this->tva_tx = trim($this->tva_tx);
801 }
802 if (isset($this->recuperableonly)) {
803 $this->recuperableonly = trim((string) $this->recuperableonly);
804 }
805 if (isset($this->localtax1_tx)) {
806 $this->localtax1_tx = trim((string) $this->localtax1_tx);
807 }
808 if (isset($this->localtax2_tx)) {
809 $this->localtax2_tx = trim((string) $this->localtax2_tx);
810 }
811 if (empty($this->discount_percent) || !is_numeric($this->discount_percent)) {
812 $this->discount_percent = 0;
813 }
814 if (empty($this->date_begin)) {
815 $this->date_begin = $now;
816 }
817 if (isset($this->fk_user)) {
818 $this->fk_user = (int) $this->fk_user;
819 }
820 if (isset($this->price_label)) {
821 $this->price_label = trim($this->price_label);
822 }
823 if (isset($this->import_key)) {
824 $this->import_key = trim($this->import_key);
825 }
826
827 // Check parameters
828 // Put here code to add a control on parameters values
829 $result = $this->verifyDates();
830 if ($result < 0) {
831 return -1;
832 }
833
834 if ($this->price != '' || $this->price == 0) {
835 $vatRate = (float) $this->tva_tx;
836 if ($this->price_base_type == 'TTC') {
837 $this->price_ttc = price2num($this->price, 'MU');
838 $this->price = (float) price2num($this->price) / (1 + ($vatRate / 100));
839 $this->price = price2num($this->price, 'MU');
840
841 if ($this->price_min != '' || $this->price_min == 0) {
842 $this->price_min_ttc = price2num($this->price_min, 'MU');
843 $this->price_min = (float) price2num($this->price_min) / (1 + ($vatRate / 100));
844 $this->price_min = price2num($this->price_min, 'MU');
845 } else {
846 $this->price_min = 0;
847 $this->price_min_ttc = 0;
848 }
849 } else {
850 $this->price = price2num($this->price, 'MU');
851 $this->price_ttc = ($this->recuperableonly != 1) ? (float) price2num($this->price) * (1 + ($vatRate / 100)) : $this->price;
852 $this->price_ttc = price2num($this->price_ttc, 'MU');
853
854 if ($this->price_min != '' || $this->price_min == 0) {
855 $this->price_min = price2num($this->price_min, 'MU');
856 $this->price_min_ttc = (float) price2num($this->price_min) * (1 + ($vatRate / 100));
857 $this->price_min_ttc = price2num($this->price_min_ttc, 'MU');
858 // print 'X'.$newminprice.'-'.$price_min;
859 } else {
860 $this->price_min = 0;
861 $this->price_min_ttc = 0;
862 }
863 }
864 }
865
866 // Do a copy of current record into log table
867 // Insert request
868 $sql = "INSERT INTO ".$this->db->prefix()."product_customer_price_log(";
869 $sql .= "entity,";
870 $sql .= "datec,";
871 $sql .= "fk_product,";
872 $sql .= "fk_soc,";
873 $sql .= "ref_customer,";
874 $sql .= "price,";
875 $sql .= "price_ttc,";
876 $sql .= "price_min,";
877 $sql .= "price_min_ttc,";
878 $sql .= "price_base_type,";
879 $sql .= "default_vat_code,";
880 $sql .= "tva_tx,";
881 $sql .= "recuperableonly,";
882 $sql .= "localtax1_tx,";
883 $sql .= "localtax2_tx,";
884 $sql .= "localtax1_type,";
885 $sql .= "localtax2_type,";
886 $sql .= "discount_percent,";
887 $sql .= "date_begin,";
888 $sql .= "date_end,";
889 $sql .= "fk_user,";
890 $sql .= "price_label,";
891 $sql .= "import_key";
892 $sql .= ") ";
893 $sql .= "SELECT";
894 $sql .= " t.entity,";
895 $sql .= " t.datec,";
896 $sql .= " t.fk_product,";
897 $sql .= " t.fk_soc,";
898 $sql .= " t.ref_customer,";
899 $sql .= " t.price,";
900 $sql .= " t.price_ttc,";
901 $sql .= " t.price_min,";
902 $sql .= " t.price_min_ttc,";
903 $sql .= " t.price_base_type,";
904 $sql .= " t.default_vat_code,";
905 $sql .= " t.tva_tx,";
906 $sql .= " t.recuperableonly,";
907 $sql .= " t.localtax1_tx,";
908 $sql .= " t.localtax2_tx,";
909 $sql .= " t.localtax1_type,";
910 $sql .= " t.localtax2_type,";
911 $sql .= " t.discount_percent,";
912 $sql .= " t.date_begin,";
913 $sql .= " t.date_end,";
914 $sql .= " t.fk_user,";
915 $sql .= " t.price_label,";
916 $sql .= " t.import_key";
917 $sql .= " FROM ".$this->db->prefix()."product_customer_price as t";
918 $sql .= " WHERE t.rowid = ".((int) $this->id);
919
920 $this->db->begin();
921 dol_syslog(get_class($this)."::update", LOG_DEBUG);
922 $resql = $this->db->query($sql);
923 if (!$resql) {
924 $error++;
925 $this->errors [] = "Error ".$this->db->lasterror();
926 }
927
928 // Update request
929 $sql = "UPDATE ".$this->db->prefix()."product_customer_price SET";
930 $sql .= " entity=".((int) $conf->entity).",";
931 $sql .= " datec='".$this->db->idate($now)."',";
932 $sql .= " tms=".(dol_strlen((string) $this->tms) != 0 ? "'".$this->db->idate($this->tms)."'" : 'null').",";
933 $sql .= " fk_product=".(isset($this->fk_product) ? $this->fk_product : "null").",";
934 $sql .= " fk_soc=".(isset($this->fk_soc) ? $this->fk_soc : "null").",";
935 $sql .= " ref_customer=".(isset($this->ref_customer) ? "'".$this->db->escape($this->ref_customer)."'" : "null").",";
936 $sql .= " price=".(isset($this->price) ? $this->price : "null").",";
937 $sql .= " price_ttc=".(isset($this->price_ttc) ? $this->price_ttc : "null").",";
938 $sql .= " price_min=".(isset($this->price_min) ? $this->price_min : "null").",";
939 $sql .= " price_min_ttc=".(isset($this->price_min_ttc) ? $this->price_min_ttc : "null").",";
940 $sql .= " price_base_type=".(isset($this->price_base_type) ? "'".$this->db->escape($this->price_base_type)."'" : "null").",";
941 $sql .= " default_vat_code = ".($this->default_vat_code ? "'".$this->db->escape($this->default_vat_code)."'" : "null").",";
942 $sql .= " tva_tx=".(isset($this->tva_tx) ? (empty($this->tva_tx) ? 0 : $this->tva_tx) : "null").",";
943 $sql .= " recuperableonly=".(isset($this->recuperableonly) ? $this->recuperableonly : "null").",";
944 $sql .= " localtax1_tx=".(isset($this->localtax1_tx) ? (empty($this->localtax1_tx) ? "'0'" : "'".$this->db->escape($this->localtax1_tx)."'") : "null").",";
945 $sql .= " localtax2_tx=".(isset($this->localtax2_tx) ? (empty($this->localtax2_tx) ? "'0'" : "'".$this->db->escape($this->localtax2_tx)."'") : "null").",";
946 $sql .= " localtax1_type=".(!empty($this->localtax1_type) ? "'".$this->db->escape($this->localtax1_type)."'" : "'0'").",";
947 $sql .= " localtax2_type=".(!empty($this->localtax2_type) ? "'".$this->db->escape($this->localtax2_type)."'" : "'0'").",";
948 $sql .= " discount_percent=".(!empty($this->discount_percent) ? "'".price2num($this->discount_percent)."'" : "0").",";
949 $sql .= " date_begin='".$this->db->idate($this->date_begin)."',";
950 $sql .= " date_end=".(!empty($this->date_end) ? "'".$this->db->idate($this->date_end)."'" : "null").",";
951 $sql .= " fk_user=".((int) $user->id).",";
952 $sql .= " price_label=".(isset($this->price_label) ? "'".$this->db->escape($this->price_label)."'" : "null").",";
953 $sql .= " import_key=".(isset($this->import_key) ? "'".$this->db->escape($this->import_key)."'" : "null");
954
955 $sql .= " WHERE rowid=".((int) $this->id);
956
957 dol_syslog(get_class($this)."::update", LOG_DEBUG);
958 $resql = $this->db->query($sql);
959 if (!$resql) {
960 $error++;
961 $this->errors [] = "Error ".$this->db->lasterror();
962 }
963
964 if (!$error && !$notrigger) {
965 // Call trigger
966 $result = $this->call_trigger('PRODUCT_CUSTOMER_PRICE_MODIFY', $user);
967 if ($result < 0) {
968 $error++;
969 }
970 // End call triggers
971 }
972
973 if (!$error) {
974 $result = $this->setPriceOnAffiliateThirdparty($user, $forceupdateaffiliate);
975 if ($result < 0) {
976 $error++;
977 }
978 }
979
980 // Commit or rollback
981 if ($error) {
982 foreach ($this->errors as $errmsg) {
983 dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
984 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
985 }
986 $this->db->rollback();
987 return -1 * $error;
988 } else {
989 $this->db->commit();
990 return 1;
991 }
992 }
993
1001 public function setPriceOnAffiliateThirdparty($user, $forceupdateaffiliate)
1002 {
1003 if (getDolGlobalString('PRODUCT_DISABLE_PROPAGATE_CUSTOMER_PRICES_ON_CHILD_COMPANIES')) {
1004 return 0;
1005 }
1006
1007 $error = 0;
1008
1009 // Find all susidiaries
1010 $sql = "SELECT s.rowid";
1011 $sql .= " FROM ".$this->db->prefix()."societe as s";
1012 $sql .= " WHERE s.parent = ".((int) $this->fk_soc);
1013 $sql .= " AND s.entity IN (".getEntity('societe').")";
1014
1015 dol_syslog(get_class($this)."::setPriceOnAffiliateThirdparty", LOG_DEBUG);
1016 $resql = $this->db->query($sql);
1017
1018 if ($resql) {
1019 $this->lines = array();
1020 $num = $this->db->num_rows($resql);
1021
1022 while (($obj = $this->db->fetch_object($resql)) && (empty($error))) {
1023 // find if there is an existing line for the product and the subsidiaries
1024 $prodsocprice = new ProductCustomerPrice($this->db);
1025
1026 $filter = array(
1027 't.fk_product' => (string) $this->fk_product, 't.fk_soc' => (string) $obj->rowid
1028 );
1029
1030 $result = $prodsocprice->fetchAll('', '', 0, 0, $filter);
1031 if ($result < 0) {
1032 $error++;
1033 $this->error = $prodsocprice->error;
1034 } else {
1035 // There is one line
1036 if (count($prodsocprice->lines) > 0) {
1037 // If force update => Update
1038 if (!empty($forceupdateaffiliate)) {
1039 $prodsocpriceupd = new ProductCustomerPrice($this->db);
1040 $prodsocpriceupd->fetch($prodsocprice->lines [0]->id);
1041
1042 $prodsocpriceupd->price = $this->price;
1043 $prodsocpriceupd->price_min = $this->price_min;
1044 $prodsocpriceupd->price_base_type = $this->price_base_type;
1045 $prodsocpriceupd->tva_tx = $this->tva_tx;
1046 $prodsocpriceupd->recuperableonly = $this->recuperableonly;
1047 $prodsocpriceupd->price_label = $this->price_label;
1048 $prodsocpriceupd->discount_percent = $this->discount_percent;
1049 $prodsocpriceupd->date_begin = $this->date_begin;
1050 $prodsocpriceupd->date_end = $this->date_end;
1051
1052 $resultupd = $prodsocpriceupd->update($user, 0, $forceupdateaffiliate);
1053 if ($resultupd < 0) {
1054 $error++;
1055 $this->error = $prodsocpriceupd->error;
1056 }
1057 }
1058 } else {
1059 // If line do not exits then create it
1060 $prodsocpricenew = new ProductCustomerPrice($this->db);
1061 $prodsocpricenew->fk_soc = $obj->rowid;
1062 $prodsocpricenew->ref_customer = $obj->ref_customer;
1063 $prodsocpricenew->fk_product = $this->fk_product;
1064 $prodsocpricenew->price = $this->price;
1065 $prodsocpricenew->price_min = $this->price_min;
1066 $prodsocpricenew->price_base_type = $this->price_base_type;
1067 $prodsocpricenew->tva_tx = $this->tva_tx;
1068 $prodsocpricenew->recuperableonly = $this->recuperableonly;
1069 $prodsocpricenew->price_label = $this->price_label;
1070 $prodsocpricenew->discount_percent = $this->discount_percent;
1071 $prodsocpricenew->date_begin = $this->date_begin;
1072 $prodsocpricenew->date_end = $this->date_end;
1073
1074 $resultupd = $prodsocpricenew->create($user, 0, $forceupdateaffiliate);
1075 if ($resultupd < 0) {
1076 $error++;
1077 $this->error = $prodsocpricenew->error;
1078 }
1079 }
1080 }
1081 }
1082 $this->db->free($resql);
1083
1084 if (empty($error)) {
1085 return 1;
1086 } else {
1087 return -1;
1088 }
1089 } else {
1090 $this->error = "Error ".$this->db->lasterror();
1091 return -1;
1092 }
1093 }
1094
1102 public function delete($user, $notrigger = 0)
1103 {
1104 global $conf, $langs;
1105 $error = 0;
1106
1107 $this->db->begin();
1108
1109 if (!$notrigger) {
1110 $result = $this->call_trigger('PRODUCT_CUSTOMER_PRICE_DELETE', $user);
1111 if ($result < 0) {
1112 $error++;
1113 }
1114 }
1115
1116 if (!$error) {
1117 $sql = "DELETE FROM ".$this->db->prefix()."product_customer_price";
1118 $sql .= " WHERE rowid=".((int) $this->id);
1119
1120 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1121 $resql = $this->db->query($sql);
1122 if (!$resql) {
1123 $error++;
1124 $this->errors [] = "Error ".$this->db->lasterror();
1125 }
1126 }
1127
1128 // Commit or rollback
1129 if ($error) {
1130 foreach ($this->errors as $errmsg) {
1131 dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
1132 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1133 }
1134 $this->db->rollback();
1135 return -1 * $error;
1136 } else {
1137 $this->db->commit();
1138 return 1;
1139 }
1140 }
1141
1149 public function createFromClone(User $user, $fromid)
1150 {
1151 $error = 0;
1152
1153 $object = new ProductCustomerPrice($this->db);
1154
1155 $this->db->begin();
1156
1157 // Load source object
1158 $object->fetch($fromid);
1159 $object->id = 0;
1160 $object->statut = 0;
1161
1162 // Clear fields
1163 // ...
1164
1165 // Create clone
1166 $object->context['createfromclone'] = 'createfromclone';
1167 $result = $object->create($user);
1168
1169 // Other options
1170 if ($result < 0) {
1172 $error++;
1173 }
1174
1175 if (!$error) {
1176 }
1177
1178 unset($object->context['createfromclone']);
1179
1180 // End
1181 if (!$error) {
1182 $this->db->commit();
1183 return $object->id;
1184 } else {
1185 $this->db->rollback();
1186 return -1;
1187 }
1188 }
1189
1196 public function initAsSpecimen()
1197 {
1198 $this->id = 0;
1199
1200 $this->entity = 0;
1201 $this->datec = '';
1202 $this->tms = dol_now();
1203 $this->fk_product = 0;
1204 $this->fk_soc = 0;
1205 $this->ref_customer = '';
1206 $this->price = '';
1207 $this->price_ttc = '';
1208 $this->price_min = '';
1209 $this->price_min_ttc = '';
1210 $this->price_base_type = '';
1211 $this->default_vat_code = '';
1212 $this->tva_tx = '';
1213 $this->recuperableonly = '';
1214 $this->localtax1_tx = '';
1215 $this->localtax2_tx = '';
1216 $this->discount_percent = '';
1217 $this->date_begin = '';
1218 $this->date_end = '';
1219 $this->fk_user = 0;
1220 $this->price_label = '';
1221 $this->import_key = '';
1222
1223 return 1;
1224 }
1225}
1226
1231{
1235 public $id;
1236
1240 public $entity;
1241
1245 public $datec = '';
1246
1250 public $fk_product;
1251
1255 public $ref_customer;
1256
1260 public $fk_soc;
1261
1265 public $price;
1269 public $price_ttc;
1273 public $price_min;
1277 public $price_min_ttc;
1281 public $price_base_type;
1285 public $default_vat_code;
1289 public $tva_tx;
1293 public $recuperableonly;
1297 public $localtax1_tx;
1301 public $localtax2_tx;
1305 public $discount_percent;
1309 public $date_begin = '';
1313 public $date_end = '';
1314
1318 public $fk_user;
1322 public $price_label;
1323
1327 public $import_key;
1331 public $socname;
1335 public $prodref;
1336}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
Parent class of all other business classes (invoices, contracts, proposals, orders,...
setErrorsFromObject($object)
setErrorsFromObject
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.
dol_now($mode='gmt')
Return date for now.
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
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.