Passed
Branch develop (623006)
by
unknown
32:40
created

ProductFournisseur::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 7
rs 10
1
<?php
2
/* Copyright (C) 2005		Rodolphe Quiedeville  <[email protected]>
3
 * Copyright (C) 2006-2011	Laurent Destailleur	  <[email protected]>
4
 * Copyright (C) 2009-2014	Regis Houssin		  <[email protected]>
5
 * Copyright (C) 2011		Juanjo Menent		  <[email protected]>
6
 * Copyright (C) 2012		Christophe Battarel	  <[email protected]>
7
 * Copyright (C) 2015		Marcos García         <[email protected]>
8
 * Copyright (C) 2016		Charlie Benke         <[email protected]>
9
 * Copyright (C) 2019       Frédéric France       <[email protected]>
10
 * Copyright (C) 2020       Pierre Ardoin         <[email protected]>
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 3 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24
 */
25
26
/**
27
 * 	\file       htdocs/fourn/class/fournisseur.product.class.php
28
 * 	\ingroup    produit
29
 * 	\brief      File of class to manage predefined suppliers products
30
 */
31
32
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
33
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php';
34
require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php';
35
36
37
/**
38
 * 	Class to manage predefined suppliers products
39
 */
40
class ProductFournisseur extends Product
41
{
42
	/**
43
	 * @var DoliDB Database handler.
44
	 */
45
	public $db;
46
47
	/**
48
	 * @var string Error code (or message)
49
	 */
50
	public $error = '';
51
52
	public $product_fourn_price_id; // id of ligne product-supplier
53
54
	/**
55
	 * @var int ID
56
	 */
57
	public $id;
58
59
	/**
60
	 * @deprecated
61
	 * @see $ref_supplier
62
	 */
63
	public $fourn_ref;
64
65
	public $delivery_time_days;
66
	public $ref_supplier; // ref supplier (can be set by get_buyprice)
67
	public $desc_supplier;
68
	public $vatrate_supplier; // default vat rate for this supplier/qty/product (can be set by get_buyprice)
69
70
	public $product_id;
71
	public $product_ref;
72
73
	public $fourn_id; //supplier id
74
	public $fourn_qty; // quantity for price (can be set by get_buyprice)
75
	public $fourn_pu; // unit price for quantity (can be set by get_buyprice)
76
77
	public $fourn_price; // price for quantity
78
	public $fourn_remise_percent; // discount for quantity (percent)
79
	public $fourn_remise; // discount for quantity (amount)
80
81
	public $product_fourn_id; // product-supplier id
82
	public $product_fourn_entity;
83
84
	/**
85
	 * @var int ID user_id - user who created/updated supplier price
86
	 */
87
	public $user_id;
88
89
	/**
90
	 * @var int ID availability delay - visible/used if option FOURN_PRODUCT_AVAILABILITY is on (duplicate information compared to delivery delay)
91
	 */
92
	public $fk_availability;
93
94
	public $fourn_unitprice;
95
	public $fourn_tva_tx;
96
	public $fourn_tva_npr;
97
98
	/**
99
	 * @var int ID
100
	 */
101
	public $fk_supplier_price_expression;
102
103
	public $supplier_reputation; // reputation of supplier
104
	public $reputations = array(); // list of available supplier reputations
105
106
	// Multicurreny
107
	public $fourn_multicurrency_id;
108
	public $fourn_multicurrency_code;
109
	public $fourn_multicurrency_tx;
110
	public $fourn_multicurrency_price;
111
	public $fourn_multicurrency_unitprice;
112
113
	/**
114
	 * @deprecated
115
	 * @see $supplier_barcode
116
	 */
117
	public $fourn_barcode;
118
119
	/**
120
	 * @var string $supplier_barcode - Supplier barcode
121
	 */
122
	public $supplier_barcode;
123
124
	/**
125
	 * @deprecated
126
	 * @see $supplier_fk_barcode_type
127
	 */
128
	public $fourn_fk_barcode_type;
129
130
	/**
131
	 * @var string $supplier_fk_barcode_type - Supplier barcode type
132
	 */
133
	public $supplier_fk_barcode_type;
134
135
	public $packaging;
136
137
138
	/**
139
	 *	Constructor
140
	 *
141
	 *  @param		DoliDB		$db      Database handler
142
	 */
143
	public function __construct($db)
144
	{
145
		global $langs;
146
147
		$this->db = $db;
148
		$langs->load("suppliers");
149
		$this->reputations = array('-1'=>'', 'FAVORITE'=>$langs->trans('Favorite'), 'NOTTHGOOD'=>$langs->trans('NotTheGoodQualitySupplier'), 'DONOTORDER'=>$langs->trans('DoNotOrderThisProductToThisSupplier'));
150
	}
151
152
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
153
	/**
154
	 *    Remove all prices for this couple supplier-product
155
	 *
156
	 *    @param	int		$id_fourn   Supplier Id
157
	 *    @return   int         		< 0 if error, > 0 if ok
158
	 */
159
	public function remove_fournisseur($id_fourn)
160
	{
161
		// phpcs:enable
162
		$ok = 1;
163
164
		$this->db->begin();
165
166
		$sql = "DELETE FROM ".MAIN_DB_PREFIX."product_fournisseur_price";
167
		$sql .= " WHERE fk_product = ".$this->id." AND fk_soc = ".$id_fourn;
168
169
		dol_syslog(get_class($this)."::remove_fournisseur", LOG_DEBUG);
170
		$resql2 = $this->db->query($sql);
171
		if (!$resql2)
172
		{
173
			$this->error = $this->db->lasterror();
174
			$ok = 0;
175
		}
176
177
		if ($ok)
178
		{
179
			$this->db->commit();
180
			return 1;
181
		} else {
182
			$this->db->rollback();
183
			return -1;
184
		}
185
	}
186
187
188
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
189
	/**
190
	 * 	Remove a price for a couple supplier-product
191
	 *
192
	 * 	@param	int		$rowid		Line id of price
193
	 *	@return	int					<0 if KO, >0 if OK
194
	 */
195
	public function remove_product_fournisseur_price($rowid)
196
	{
197
		// phpcs:enable
198
		global $conf, $user;
199
200
		$error = 0;
201
202
		$this->db->begin();
203
204
		// Call trigger
205
		$result = $this->call_trigger('SUPPLIER_PRODUCT_BUYPRICE_DELETE', $user);
206
		if ($result < 0) $error++;
207
		// End call triggers
208
209
		if (empty($error))
210
		{
211
			$sql = "DELETE FROM ".MAIN_DB_PREFIX."product_fournisseur_price";
212
			$sql .= " WHERE rowid = ".$rowid;
213
214
			dol_syslog(get_class($this)."::remove_product_fournisseur_price", LOG_DEBUG);
215
			$resql = $this->db->query($sql);
216
			if (!$resql)
217
			{
218
				$this->error = $this->db->lasterror();
219
				$error++;
220
			}
221
		}
222
223
		if (empty($error)) {
224
			$this->db->commit();
225
			return 1;
226
		} else {
227
			$this->db->rollback();
228
			return -1;
229
		}
230
	}
231
232
233
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
234
	/**
235
	 *    Modify the purchase price for a supplier
236
	 *
237
	 *    @param  	float		$qty				            Min quantity for which price is valid
238
	 *    @param  	float		$buyprice			            Purchase price for the quantity min
239
	 *    @param  	User		$user				            Object user user made changes
240
	 *    @param  	string		$price_base_type	            HT or TTC
241
	 *    @param  	Societe		$fourn				            Supplier
242
	 *    @param  	int			$availability		            Product availability
243
	 *    @param	string		$ref_fourn			            Supplier ref
244
	 *    @param	float		$tva_tx				            New VAT Rate (For example 8.5. Should not be a string)
245
	 *    @param  	string		$charges			            costs affering to product
246
	 *    @param  	float		$remise_percent		            Discount  regarding qty (percent)
247
	 *    @param  	float		$remise				            Discount  regarding qty (amount)
248
	 *    @param  	int			$newnpr				            Set NPR or not
249
	 *    @param	int			$delivery_time_days	            Delay in days for delivery (max). May be '' if not defined.
250
	 * 	  @param    string      $supplier_reputation            Reputation with this product to the defined supplier (empty, FAVORITE, DONOTORDER)
251
	 *	  @param    array		$localtaxes_array	            Array with localtaxes info array('0'=>type1,'1'=>rate1,'2'=>type2,'3'=>rate2) (loaded by getLocalTaxesFromRate(vatrate, 0, ...) function).
252
	 *    @param    string  	$newdefaultvatcode              Default vat code
253
	 *    @param  	float		$multicurrency_buyprice 	    Purchase price for the quantity min in currency
254
	 *    @param  	string		$multicurrency_price_base_type	HT or TTC in currency
255
	 *    @param  	float		$multicurrency_tx	            Rate currency
256
	 *    @param  	string		$multicurrency_code	            Currency code
257
	 *    @param  	string		$desc_fourn     	            Custom description for product_fourn_price
258
	 *    @param  	string		$barcode     	                Barcode
259
	 *    @param  	int		    $fk_barcode_type     	        Barcode type
260
	 *    @return	int											<0 if KO, >=0 if OK
261
	 */
262
	public function update_buyprice($qty, $buyprice, $user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx, $charges = 0, $remise_percent = 0, $remise = 0, $newnpr = 0, $delivery_time_days = 0, $supplier_reputation = '', $localtaxes_array = array(), $newdefaultvatcode = '', $multicurrency_buyprice = 0, $multicurrency_price_base_type = 'HT', $multicurrency_tx = 1, $multicurrency_code = '', $desc_fourn = '', $barcode = '', $fk_barcode_type = '')
263
	{
264
		// phpcs:enable
265
		global $conf, $langs;
266
		//global $mysoc;
267
268
		// Clean parameter
269
		if (empty($qty)) $qty = 0;
270
		if (empty($buyprice)) $buyprice = 0;
271
		if (empty($charges)) $charges = 0;
272
		if (empty($availability)) $availability = 0;
273
		if (empty($remise_percent)) $remise_percent = 0;
274
		if (empty($supplier_reputation) || $supplier_reputation == -1) $supplier_reputation = '';
275
		if ($delivery_time_days != '' && !is_numeric($delivery_time_days)) $delivery_time_days = '';
276
		if ($price_base_type == 'TTC')
277
		{
278
			$ttx = $tva_tx;
279
			$buyprice = $buyprice / (1 + ($ttx / 100));
280
		}
281
282
		// Multicurrency
283
		$multicurrency_buyprice = null;
284
		$multicurrency_unitBuyPrice = null;
285
		$fk_multicurrency = null;
286
		if (!empty($conf->multicurrency->enabled)) {
287
			if (empty($multicurrency_tx)) $multicurrency_tx = 1;
288
			if (empty($multicurrency_buyprice)) $multicurrency_buyprice = 0;
0 ignored issues
show
introduced by
The condition empty($multicurrency_buyprice) is always false.
Loading history...
289
290
			if (empty($multicurrency_buyprice)) $multicurrency_buyprice = 0;
0 ignored issues
show
introduced by
The condition empty($multicurrency_buyprice) is always false.
Loading history...
291
			if ($multicurrency_price_base_type == 'TTC')
292
			{
293
				$ttx = $tva_tx;
294
				$multicurrency_buyprice = $multicurrency_buyprice / (1 + ($ttx / 100));
295
			}
296
			$multicurrency_buyprice = price2num($multicurrency_buyprice, 'MU');
297
			$multicurrency_unitBuyPrice = price2num($multicurrency_buyprice / $qty, 'MU');
298
299
			$buyprice = $multicurrency_buyprice / $multicurrency_tx;
300
			$fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $multicurrency_code);
301
		}
302
303
		$buyprice = price2num($buyprice, 'MU');
304
		$charges = price2num($charges, 'MU');
305
		$qty = price2num($qty, 'MS');
306
		$unitBuyPrice = price2num($buyprice / $qty, 'MU');
307
308
		$packaging = price2num(((empty($this->packaging) || $this->packaging < $qty) ? $qty : $this->packaging), 'MS');
309
310
		$error = 0;
311
		$now = dol_now();
312
313
		$newvat = $tva_tx;
314
315
		if (count($localtaxes_array) > 0)
316
		{
317
			$localtaxtype1 = $localtaxes_array['0'];
318
			$localtax1 = $localtaxes_array['1'];
319
			$localtaxtype2 = $localtaxes_array['2'];
320
			$localtax2 = $localtaxes_array['3'];
321
		} else { // old method. deprecated because ot can't retrieve type
322
			$localtaxtype1 = '0';
323
			$localtax1 = get_localtax($newvat, 1);
324
			$localtaxtype2 = '0';
325
			$localtax2 = get_localtax($newvat, 2);
326
		}
327
		if (empty($localtax1)) $localtax1 = 0; // If = '' then = 0
328
		if (empty($localtax2)) $localtax2 = 0; // If = '' then = 0
329
330
		// Check parameters
331
		if ($buyprice != '' && !is_numeric($buyprice))
332
		{
333
		}
334
335
		$this->db->begin();
336
337
		if ($this->product_fourn_price_id > 0)
338
		{
339
			// check if price already logged, if not first log current price
340
			$logPrices = $this->listProductFournisseurPriceLog($this->product_fourn_price_id);
341
			if (is_array($logPrices) && count($logPrices) == 0)
342
			{
343
				$currentPfp = new self($this->db);
344
				$result = $currentPfp->fetch_product_fournisseur_price($this->product_fourn_price_id);
345
				if ($result > 0 && $currentPfp->fourn_price != 0)
346
				{
347
					$currentPfpUser = new User($this->db);
348
					$result = $currentPfpUser->fetch($currentPfp->user_id);
349
					if ($result > 0) {
350
						$currentPfp->logPrice(
351
							$currentPfpUser,
352
							$currentPfp->date_creation,
353
							$currentPfp->fourn_price,
354
							$currentPfp->fourn_qty,
355
							$currentPfp->fourn_multicurrency_price,
356
							$currentPfp->fourn_multicurrency_unitprice,
357
							$currentPfp->fourn_multicurrency_tx,
358
							$currentPfp->fourn_multicurrency_id,
359
							$currentPfp->fourn_multicurrency_code
360
						);
361
					}
362
				}
363
			}
364
			$sql = "UPDATE ".MAIN_DB_PREFIX."product_fournisseur_price";
365
			$sql .= " SET fk_user = ".$user->id." ,";
366
			$sql .= " ref_fourn = '".$this->db->escape($ref_fourn)."',";
367
			$sql .= " desc_fourn = '".$this->db->escape($desc_fourn)."',";
368
			$sql .= " price = ".$buyprice.",";
369
			$sql .= " quantity = ".$qty.",";
370
			$sql .= " remise_percent = ".$remise_percent.",";
371
			$sql .= " remise = ".$remise.",";
372
			$sql .= " unitprice = ".$unitBuyPrice.",";
373
			$sql .= " fk_availability = ".$availability.",";
374
			$sql .= " multicurrency_price = ".(isset($multicurrency_buyprice) ? "'".$this->db->escape(price2num($multicurrency_buyprice))."'" : 'null').",";
375
			$sql .= " multicurrency_unitprice = ".(isset($multicurrency_unitBuyPrice) ? "'".$this->db->escape(price2num($multicurrency_unitBuyPrice))."'" : 'null').",";
376
			$sql .= " multicurrency_tx = ".(isset($multicurrency_tx) ? "'".$this->db->escape($multicurrency_tx)."'" : '1').",";
377
			$sql .= " fk_multicurrency = ".(isset($fk_multicurrency) ? "'".$this->db->escape($fk_multicurrency)."'" : 'null').",";
378
			$sql .= " multicurrency_code = ".(isset($multicurrency_code) ? "'".$this->db->escape($multicurrency_code)."'" : 'null').",";
379
			$sql .= " entity = ".$conf->entity.",";
380
			$sql .= " tva_tx = ".price2num($tva_tx).",";
381
			// TODO Add localtax1 and localtax2
382
			//$sql.= " localtax1_tx=".($localtax1>=0?$localtax1:'NULL').",";
383
			//$sql.= " localtax2_tx=".($localtax2>=0?$localtax2:'NULL').",";
384
			//$sql.= " localtax1_type=".($localtaxtype1!=''?"'".$this->db->escape($localtaxtype1)."'":"'0'").",";
385
			//$sql.= " localtax2_type=".($localtaxtype2!=''?"'".$this->db->escape($localtaxtype2)."'":"'0'").",";
386
			$sql .= " default_vat_code=".($newdefaultvatcode ? "'".$this->db->escape($newdefaultvatcode)."'" : "null").",";
387
			$sql .= " info_bits = ".$newnpr.",";
388
			$sql .= " charges = ".$charges.","; // deprecated
389
			$sql .= " delivery_time_days = ".($delivery_time_days != '' ? $delivery_time_days : 'null').",";
390
			$sql .= " supplier_reputation = ".(empty($supplier_reputation) ? 'NULL' : "'".$this->db->escape($supplier_reputation)."'").",";
391
			$sql .= " barcode = ".(empty($barcode) ? 'NULL' : "'".$this->db->escape($barcode)."'").",";
392
			$sql .= " fk_barcode_type = ".(empty($fk_barcode_type) ? 'NULL' : "'".$this->db->escape($fk_barcode_type)."'");
393
			if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) $sql .= ", packaging = ".(empty($packaging) ? 1 : $packaging);
394
			$sql .= " WHERE rowid = ".$this->product_fourn_price_id;
395
			// TODO Add price_base_type and price_ttc
396
397
			dol_syslog(get_class($this).'::update_buyprice update knowing id of line = product_fourn_price_id = '.$this->product_fourn_price_id, LOG_DEBUG);
398
			$resql = $this->db->query($sql);
399
			if ($resql)
400
			{
401
				// Call trigger
402
				$result = $this->call_trigger('SUPPLIER_PRODUCT_BUYPRICE_UPDATE', $user);
403
				if ($result < 0) $error++;
404
				// End call triggers
405
				if (!$error && empty($conf->global->PRODUCT_PRICE_SUPPLIER_NO_LOG))
406
				{
407
					$result = $this->logPrice($user, $now, $buyprice, $qty, $multicurrency_buyprice, $multicurrency_unitBuyPrice, $multicurrency_tx, $fk_multicurrency, $multicurrency_code);
408
					if ($result < 0) {
409
						$error++;
410
					}
411
				}
412
				if (empty($error))
413
				{
414
					$this->db->commit();
415
					return $this->product_fourn_price_id;
416
				} else {
417
					$this->db->rollback();
418
					return -1;
419
				}
420
			} else {
421
				$this->error = $this->db->error()." sql=".$sql;
422
				$this->db->rollback();
423
				return -2;
424
			}
425
		} else {
426
			dol_syslog(get_class($this).'::update_buyprice without knowing id of line, so we delete from company, quantity and supplier_ref and insert again', LOG_DEBUG);
427
428
			// Delete price for this quantity
429
			$sql = "DELETE FROM  ".MAIN_DB_PREFIX."product_fournisseur_price";
430
			$sql .= " WHERE fk_soc = ".$fourn->id." AND ref_fourn = '".$this->db->escape($ref_fourn)."' AND quantity = ".$qty." AND entity = ".$conf->entity;
431
			$resql = $this->db->query($sql);
432
			if ($resql) {
433
				// Add price for this quantity to supplier
434
				$sql = "INSERT INTO ".MAIN_DB_PREFIX."product_fournisseur_price(";
435
				$sql .= " multicurrency_price, multicurrency_unitprice, multicurrency_tx, fk_multicurrency, multicurrency_code,";
436
				$sql .= "datec, fk_product, fk_soc, ref_fourn, desc_fourn, fk_user, price, quantity, remise_percent, remise, unitprice, tva_tx, charges, fk_availability, default_vat_code, info_bits, entity, delivery_time_days, supplier_reputation, barcode, fk_barcode_type)";
437
				if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) $sql .= ", packaging";
438
				$sql .= " values(";
439
				$sql .= (isset($multicurrency_buyprice) ? "'".$this->db->escape(price2num($multicurrency_buyprice))."'" : 'null').",";
440
				$sql .= (isset($multicurrency_unitBuyPrice) ? "'".$this->db->escape(price2num($multicurrency_unitBuyPrice))."'" : 'null').",";
441
				$sql .= (isset($multicurrency_tx) ? "'".$this->db->escape($multicurrency_tx)."'" : '1').",";
442
				$sql .= (isset($fk_multicurrency) ? "'".$this->db->escape($fk_multicurrency)."'" : 'null').",";
443
				$sql .= (isset($multicurrency_code) ? "'".$this->db->escape($multicurrency_code)."'" : 'null').",";
444
				$sql .= " '".$this->db->idate($now)."',";
445
				$sql .= " ".$this->id.",";
446
				$sql .= " ".$fourn->id.",";
447
				$sql .= " '".$this->db->escape($ref_fourn)."',";
448
				$sql .= " '".$this->db->escape($desc_fourn)."',";
449
				$sql .= " ".$user->id.",";
450
				$sql .= " ".$buyprice.",";
451
				$sql .= " ".$qty.",";
452
				$sql .= " ".$remise_percent.",";
453
				$sql .= " ".$remise.",";
454
				$sql .= " ".$unitBuyPrice.",";
455
				$sql .= " ".$tva_tx.",";
456
				$sql .= " ".$charges.",";
457
				$sql .= " ".$availability.",";
458
				$sql .= " ".($newdefaultvatcode ? "'".$this->db->escape($newdefaultvatcode)."'" : "null").",";
459
				$sql .= " ".$newnpr.",";
460
				$sql .= $conf->entity.",";
461
				$sql .= ($delivery_time_days != '' ? $delivery_time_days : 'null').",";
462
				$sql .= (empty($supplier_reputation) ? 'NULL' : "'".$this->db->escape($supplier_reputation)."'").",";
463
				$sql .= (empty($barcode) ? 'NULL' : "'".$this->db->escape($barcode)."'").",";
464
				$sql .= (empty($fk_barcode_type) ? 'NULL' : "'".$this->db->escape($fk_barcode_type)."'");
465
				if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) $sql .= ", ".(empty($this->packaging) ? 1 : $this->db->escape($this->packaging));
466
				$sql .= ")";
467
468
				$this->product_fourn_price_id = 0;
469
470
				$resql = $this->db->query($sql);
471
				if ($resql) {
472
					$this->product_fourn_price_id = $this->db->last_insert_id(MAIN_DB_PREFIX."product_fournisseur_price");
473
				} else {
474
					$error++;
475
				}
476
477
				if (!$error && empty($conf->global->PRODUCT_PRICE_SUPPLIER_NO_LOG)) {
478
					// Add record into log table
479
					// $this->product_fourn_price_id must be set
480
					$result = $this->logPrice($user, $now, $buyprice, $qty, $multicurrency_buyprice, $multicurrency_unitBuyPrice, $multicurrency_tx, $fk_multicurrency, $multicurrency_code);
481
					if ($result < 0) {
482
						$error++;
483
					}
484
				}
485
486
				if (!$error) {
487
					// Call trigger
488
					$result = $this->call_trigger('SUPPLIER_PRODUCT_BUYPRICE_CREATE', $user);
489
					if ($result < 0)
490
						$error++;
491
						// End call triggers
492
493
					if (empty($error)) {
494
						$this->db->commit();
495
						return $this->product_fourn_price_id;
496
					} else {
497
						$this->db->rollback();
498
						return -1;
499
					}
500
				} else {
501
					$this->error = $this->db->lasterror()." sql=".$sql;
502
					$this->db->rollback();
503
					return -2;
504
				}
505
			} else {
506
				$this->error = $this->db->lasterror()." sql=".$sql;
507
				$this->db->rollback();
508
				return -1;
509
			}
510
		}
511
	}
512
513
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
514
	/**
515
	 *    Loads the price information of a provider
516
	 *
517
	 *    @param    int     $rowid              Line id
518
	 *    @param    int     $ignore_expression  Ignores the math expression for calculating price and uses the db value instead
519
	 *    @return   int 					    < 0 if KO, 0 if OK but not found, > 0 if OK
520
	 */
521
	public function fetch_product_fournisseur_price($rowid, $ignore_expression = 0)
522
	{
523
		// phpcs:enable
524
		global $conf;
525
526
		$sql = "SELECT pfp.rowid, pfp.price, pfp.quantity, pfp.unitprice, pfp.remise_percent, pfp.remise, pfp.tva_tx, pfp.default_vat_code, pfp.info_bits as fourn_tva_npr, pfp.fk_availability,";
527
		$sql .= " pfp.fk_soc, pfp.ref_fourn, pfp.desc_fourn, pfp.fk_product, pfp.charges, pfp.fk_supplier_price_expression, pfp.delivery_time_days,";
528
		$sql .= " pfp.supplier_reputation, pfp.fk_user, pfp.datec,";
529
		$sql .= " pfp.multicurrency_price, pfp.multicurrency_unitprice, pfp.multicurrency_tx, pfp.fk_multicurrency, pfp.multicurrency_code,";
530
		$sql .= " pfp.barcode, pfp.fk_barcode_type, pfp.packaging,";
531
		$sql .= " p.ref as product_ref";
532
		$sql .= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp, ".MAIN_DB_PREFIX."product as p";
533
		$sql .= " WHERE pfp.rowid = ".(int) $rowid;
534
		$sql .= " AND pfp.fk_product = p.rowid";
535
536
		dol_syslog(get_class($this)."::fetch_product_fournisseur_price", LOG_DEBUG);
537
		$resql = $this->db->query($sql);
538
		if ($resql)
539
		{
540
			$obj = $this->db->fetch_object($resql);
541
			if ($obj)
542
			{
543
				$this->product_fourn_price_id = $rowid;
544
				$this->id = $obj->fk_product;
545
546
				$this->fk_product				= $obj->fk_product;
547
				$this->product_id				= $obj->fk_product;
548
				$this->product_ref				= $obj->product_ref;
549
550
				$this->fourn_id					= $obj->fk_soc;
551
				$this->fourn_ref				= $obj->ref_fourn; // deprecated
552
				$this->ref_supplier             = $obj->ref_fourn;
553
				$this->desc_supplier            = $obj->desc_fourn;
554
				$this->fourn_price = $obj->price;
555
				$this->fourn_charges            = $obj->charges; // deprecated
556
				$this->fourn_qty                = $obj->quantity;
557
				$this->fourn_remise_percent     = $obj->remise_percent;
558
				$this->fourn_remise             = $obj->remise;
559
				$this->fourn_unitprice          = $obj->unitprice;
560
				$this->fourn_tva_tx				= $obj->tva_tx;
561
				$this->fourn_tva_npr			= $obj->fourn_tva_npr;
562
				// Add also localtaxes
563
				$this->fk_availability = $obj->fk_availability;
564
				$this->delivery_time_days = $obj->delivery_time_days;
565
				$this->fk_supplier_price_expression = $obj->fk_supplier_price_expression;
566
				$this->supplier_reputation      = $obj->supplier_reputation;
567
				$this->default_vat_code         = $obj->default_vat_code;
568
				$this->user_id                  = $obj->fk_user;
569
				$this->date_creation            = $this->db->jdate($obj->datec);
570
				$this->fourn_multicurrency_price       = $obj->multicurrency_price;
571
				$this->fourn_multicurrency_unitprice   = $obj->multicurrency_unitprice;
572
				$this->fourn_multicurrency_tx          = $obj->multicurrency_tx;
573
				$this->fourn_multicurrency_id          = $obj->fk_multicurrency;
574
				$this->fourn_multicurrency_code        = $obj->multicurrency_code;
575
				if (!empty($conf->barcode->enabled)) {
576
					$this->fourn_barcode = $obj->barcode; // deprecated
577
					$this->fourn_fk_barcode_type = $obj->fk_barcode_type; // deprecated
578
					$this->supplier_barcode = $obj->barcode;
579
					$this->supplier_fk_barcode_type = $obj->fk_barcode_type;
580
				}
581
582
				if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) {
583
					$this->packaging = $obj->packaging;
584
					if ($this->packaging < $this->fourn_qty) $this->packaging = $this->fourn_qty;
585
				}
586
587
				if (empty($ignore_expression) && !empty($this->fk_supplier_price_expression))
588
				{
589
					$priceparser = new PriceParser($this->db);
590
					$price_result = $priceparser->parseProductSupplier($this);
591
					if ($price_result >= 0) {
592
						$this->fourn_price = $price_result;
593
						//recalculation of unitprice, as probably the price changed...
594
						if ($this->fourn_qty != 0)
595
						{
596
							$this->fourn_unitprice = price2num($this->fourn_price / $this->fourn_qty, 'MU');
597
						} else {
598
							$this->fourn_unitprice = "";
599
						}
600
					}
601
				}
602
603
				return 1;
604
			} else {
605
				return 0;
606
			}
607
		} else {
608
			$this->error = $this->db->lasterror();
609
			return -1;
610
		}
611
	}
612
613
614
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
615
	/**
616
	 *    List all supplier prices of a product
617
	 *
618
	 *    @param    int		$prodid	    Id of product
619
	 *    @param	string	$sortfield	Sort field
620
	 *    @param	string	$sortorder	Sort order
621
	 *    @param	int		$limit		Limit
622
	 *    @param	int		$offset		Offset
623
	 *    @return	array				Array of Products with new properties to define supplier price
624
	 */
625
	public function list_product_fournisseur_price($prodid, $sortfield = '', $sortorder = '', $limit = 0, $offset = 0)
626
	{
627
		// phpcs:enable
628
		global $conf;
629
630
		$sql = "SELECT s.nom as supplier_name, s.rowid as fourn_id, p.ref as product_ref,";
631
		$sql .= " pfp.rowid as product_fourn_pri_id, pfp.entity, pfp.ref_fourn, pfp.desc_fourn, pfp.fk_product as product_fourn_id, pfp.fk_supplier_price_expression,";
632
		$sql .= " pfp.price, pfp.quantity, pfp.unitprice, pfp.remise_percent, pfp.remise, pfp.tva_tx, pfp.fk_availability, pfp.charges, pfp.info_bits, pfp.delivery_time_days, pfp.supplier_reputation,";
633
		$sql .= " pfp.multicurrency_price, pfp.multicurrency_unitprice, pfp.multicurrency_tx, pfp.fk_multicurrency, pfp.multicurrency_code, pfp.datec, pfp.tms,";
634
		$sql .= " pfp.barcode, pfp.fk_barcode_type";
635
		if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) $sql .= ", pfp.packaging";
636
		$sql .= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp, ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."societe as s";
637
		$sql .= " WHERE pfp.entity IN (".getEntity('productsupplierprice').")";
638
		$sql .= " AND pfp.fk_soc = s.rowid AND pfp.fk_product = p.rowid";
639
		$sql .= " AND s.status=1"; // only enabled company selected
640
		$sql .= " AND pfp.fk_product = ".$prodid;
641
		if (empty($sortfield)) $sql .= " ORDER BY s.nom, pfp.quantity, pfp.price";
642
		else $sql .= $this->db->order($sortfield, $sortorder);
643
		$sql .= $this->db->plimit($limit, $offset);
644
		dol_syslog(get_class($this)."::list_product_fournisseur_price", LOG_DEBUG);
645
646
		$resql = $this->db->query($sql);
647
		if ($resql)
648
		{
649
			$retarray = array();
650
651
			while ($record = $this->db->fetch_array($resql))
652
			{
653
				//define base attribute
654
				$prodfourn = new ProductFournisseur($this->db);
655
656
				$prodfourn->product_ref = $record["product_ref"];
657
				$prodfourn->product_fourn_price_id = $record["product_fourn_pri_id"];
658
				$prodfourn->product_fourn_id = $record["product_fourn_id"];
659
				$prodfourn->product_fourn_entity = $record["entity"];
660
				$prodfourn->ref_supplier			= $record["ref_fourn"];
661
				$prodfourn->fourn_ref = $record["ref_fourn"];
662
				$prodfourn->desc_supplier = $record["desc_fourn"];
663
				$prodfourn->fourn_price				= $record["price"];
664
				$prodfourn->fourn_qty = $record["quantity"];
665
				$prodfourn->fourn_remise_percent = $record["remise_percent"];
666
				$prodfourn->fourn_remise = $record["remise"];
667
				$prodfourn->fourn_unitprice = $record["unitprice"];
668
				$prodfourn->fourn_charges = $record["charges"]; // deprecated
669
				$prodfourn->fourn_tva_tx = $record["tva_tx"];
670
				$prodfourn->fourn_id = $record["fourn_id"];
671
				$prodfourn->fourn_name = $record["supplier_name"];
672
				$prodfourn->fk_availability			= $record["fk_availability"];
673
				$prodfourn->delivery_time_days = $record["delivery_time_days"];
674
				$prodfourn->id = $prodid;
675
				$prodfourn->fourn_tva_npr					= $record["info_bits"];
676
				$prodfourn->fk_supplier_price_expression = $record["fk_supplier_price_expression"];
677
				$prodfourn->supplier_reputation = $record["supplier_reputation"];
678
				$prodfourn->fourn_date_creation          = $this->db->jdate($record['datec']);
679
				$prodfourn->fourn_date_modification      = $this->db->jdate($record['tms']);
680
681
				$prodfourn->fourn_multicurrency_price       = $record["multicurrency_price"];
682
				$prodfourn->fourn_multicurrency_unitprice   = $record["multicurrency_unitprice"];
683
				$prodfourn->fourn_multicurrency_tx          = $record["multicurrency_tx"];
684
				$prodfourn->fourn_multicurrency_id          = $record["fk_multicurrency"];
685
				$prodfourn->fourn_multicurrency_code        = $record["multicurrency_code"];
686
687
				if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) {
688
					$prodfourn->packaging = $record["packaging"];
689
					if ($prodfourn->packaging < $prodfourn->fourn_qty) $prodfourn->packaging = $prodfourn->fourn_qty;
690
				}
691
692
				if (!empty($conf->barcode->enabled)) {
693
					$prodfourn->supplier_barcode = $record["barcode"];
694
					$prodfourn->supplier_fk_barcode_type = $record["fk_barcode_type"];
695
				}
696
697
				if (!empty($conf->dynamicprices->enabled) && !empty($prodfourn->fk_supplier_price_expression)) {
698
					$priceparser = new PriceParser($this->db);
699
					$price_result = $priceparser->parseProductSupplier($prodfourn);
700
					if ($price_result >= 0) {
701
						$prodfourn->fourn_price = $price_result;
702
						$prodfourn->fourn_unitprice = null; //force recalculation of unitprice, as probably the price changed...
703
					}
704
				}
705
706
				if (!isset($prodfourn->fourn_unitprice))
707
				{
708
					if ($prodfourn->fourn_qty != 0)
709
					{
710
						$prodfourn->fourn_unitprice = price2num($prodfourn->fourn_price / $prodfourn->fourn_qty, 'MU');
711
					} else {
712
						$prodfourn->fourn_unitprice = "";
713
					}
714
				}
715
716
				$retarray[] = $prodfourn;
717
			}
718
719
			$this->db->free($resql);
720
			return $retarray;
721
		} else {
722
			$this->error = $this->db->error();
723
			return -1;
724
		}
725
	}
726
727
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
728
	/**
729
	 *  Load properties for minimum price
730
	 *
731
	 *  @param	int		$prodid	    Product id
732
	 *  @param	int		$qty		Minimum quantity
733
	 *  @param	int		$socid		get min price for specific supplier
734
	 *  @return int					<0 if KO, 0=Not found of no product id provided, >0 if OK
735
	 */
736
	public function find_min_price_product_fournisseur($prodid, $qty = 0, $socid = 0)
737
	{
738
		// phpcs:enable
739
		global $conf;
740
741
		if (empty($prodid))
742
		{
743
			dol_syslog("Warning function find_min_price_product_fournisseur were called with prodid empty. May be a bug.", LOG_WARNING);
744
			return 0;
745
		}
746
747
		$this->product_fourn_price_id = '';
748
		$this->product_fourn_id       = '';
749
		$this->fourn_ref              = '';
1 ignored issue
show
Deprecated Code introduced by
The property ProductFournisseur::$fourn_ref has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

749
		/** @scrutinizer ignore-deprecated */ $this->fourn_ref              = '';
Loading history...
750
		$this->fourn_price            = '';
751
		$this->fourn_qty              = '';
752
		$this->fourn_remise_percent   = '';
753
		$this->fourn_remise           = '';
754
		$this->fourn_unitprice        = '';
755
		$this->fourn_id               = '';
756
		$this->fourn_name             = '';
757
		$this->delivery_time_days = '';
758
		$this->id                     = '';
759
760
		$this->fourn_multicurrency_price       = '';
761
		$this->fourn_multicurrency_unitprice   = '';
762
		$this->fourn_multicurrency_tx          = '';
763
		$this->fourn_multicurrency_id          = '';
764
		$this->fourn_multicurrency_code        = '';
765
766
		$sql = "SELECT s.nom as supplier_name, s.rowid as fourn_id,";
767
		$sql .= " pfp.rowid as product_fourn_price_id, pfp.ref_fourn,";
768
		$sql .= " pfp.price, pfp.quantity, pfp.unitprice, pfp.tva_tx, pfp.charges,";
769
		$sql .= " pfp.remise, pfp.remise_percent, pfp.fk_supplier_price_expression, pfp.delivery_time_days";
770
		$sql .= " ,pfp.multicurrency_price, pfp.multicurrency_unitprice, pfp.multicurrency_tx, pfp.fk_multicurrency, pfp.multicurrency_code";
771
		$sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."product_fournisseur_price as pfp";
772
		$sql .= " WHERE s.entity IN (".getEntity('societe').")";
773
		$sql .= " AND pfp.entity = ".$conf->entity; // only current entity
774
		$sql .= " AND pfp.fk_product = ".$prodid;
775
		$sql .= " AND pfp.fk_soc = s.rowid";
776
		$sql .= " AND s.status = 1"; // only enabled society
777
		if ($qty > 0) $sql .= " AND pfp.quantity <= ".$qty;
778
		if ($socid > 0) $sql .= ' AND pfp.fk_soc = '.$socid;
779
780
		dol_syslog(get_class($this)."::find_min_price_product_fournisseur", LOG_DEBUG);
781
782
		$resql = $this->db->query($sql);
783
		if ($resql)
784
		{
785
			$record_array = array();
786
787
			//Store each record to array for later search of min
788
			while ($record = $this->db->fetch_array($resql))
789
			{
790
				$record_array[] = $record;
791
			}
792
793
			if (count($record_array) == 0)
794
			{
795
				$this->db->free($resql);
796
				return 0;
797
			} else {
798
				$min = -1;
799
				foreach ($record_array as $record)
800
				{
801
					$fourn_price = $record["price"];
802
					// discount calculated buy price
803
					$fourn_unitprice = $record["unitprice"] * (1 - $record["remise_percent"] / 100) - $record["remise"];
804
					if (!empty($conf->dynamicprices->enabled) && !empty($record["fk_supplier_price_expression"])) {
805
						$prod_supplier = new ProductFournisseur($this->db);
806
						$prod_supplier->product_fourn_price_id = $record["product_fourn_price_id"];
807
						$prod_supplier->id = $prodid;
808
						$prod_supplier->fourn_qty = $record["quantity"];
809
						$prod_supplier->fourn_tva_tx = $record["tva_tx"];
810
						$prod_supplier->fk_supplier_price_expression = $record["fk_supplier_price_expression"];
811
						$priceparser = new PriceParser($this->db);
812
						$price_result = $priceparser->parseProductSupplier($prod_supplier);
813
						if ($price_result >= 0) {
814
							$fourn_price = price2num($price_result, 'MU');
815
							if ($record["quantity"] != 0)
816
							{
817
								$fourn_unitprice = price2num($fourn_price / $record["quantity"], 'MU');
818
							} else {
819
								$fourn_unitprice = $fourn_price;
820
							}
821
						}
822
					}
823
					if ($fourn_unitprice < $min || $min == -1)
824
					{
825
						$this->product_fourn_price_id   = $record["product_fourn_price_id"];
826
						$this->ref_supplier             = $record["ref_fourn"];
827
						$this->ref_fourn                = $record["ref_fourn"]; // deprecated
828
						$this->fourn_ref                = $record["ref_fourn"]; // deprecated
829
						$this->fourn_price              = $fourn_price;
830
						$this->fourn_qty                = $record["quantity"];
831
						$this->fourn_remise_percent     = $record["remise_percent"];
832
						$this->fourn_remise             = $record["remise"];
833
						$this->fourn_unitprice          = $record["unitprice"];
834
						$this->fourn_charges            = $record["charges"]; // deprecated
835
						$this->fourn_tva_tx             = $record["tva_tx"];
836
						$this->fourn_id                 = $record["fourn_id"];
837
						$this->fourn_name               = $record["supplier_name"];
838
						$this->delivery_time_days = $record["delivery_time_days"];
839
						$this->fk_supplier_price_expression = $record["fk_supplier_price_expression"];
840
						$this->id                       = $prodid;
841
						$this->fourn_multicurrency_price       = $record["multicurrency_price"];
842
						$this->fourn_multicurrency_unitprice   = $record["multicurrency_unitprice"];
843
						$this->fourn_multicurrency_tx          = $record["multicurrency_tx"];
844
						$this->fourn_multicurrency_id          = $record["fk_multicurrency"];
845
						$this->fourn_multicurrency_code        = $record["multicurrency_code"];
846
						$min = $fourn_unitprice;
847
					}
848
				}
849
			}
850
851
			$this->db->free($resql);
852
			return 1;
853
		} else {
854
			$this->error = $this->db->error();
855
			return -1;
856
		}
857
	}
858
859
	/**
860
	 *  Sets the supplier price expression
861
	 *
862
	 *  @param  int     $expression_id	Expression
863
	 *  @return int                 	<0 if KO, >0 if OK
864
	 */
865
	public function setSupplierPriceExpression($expression_id)
866
	{
867
		global $conf;
868
869
		// Clean parameters
870
		$this->db->begin();
871
		$expression_id = $expression_id != 0 ? $expression_id : 'NULL';
872
873
		$sql = "UPDATE ".MAIN_DB_PREFIX."product_fournisseur_price";
874
		$sql .= " SET fk_supplier_price_expression = ".$expression_id;
875
		$sql .= " WHERE rowid = ".$this->product_fourn_price_id;
876
877
		dol_syslog(get_class($this)."::setSupplierPriceExpression", LOG_DEBUG);
878
879
		$resql = $this->db->query($sql);
880
		if ($resql)
881
		{
882
			$this->db->commit();
883
			return 1;
884
		} else {
885
			$this->error = $this->db->error()." sql=".$sql;
886
			$this->db->rollback();
887
			return -1;
888
		}
889
	}
890
891
	/**
892
	 *	Display supplier of product
893
	 *
894
	 *	@param	int		$withpicto		Add picto
895
	 *	@param	string	$option			Target of link ('', 'customer', 'prospect', 'supplier')
896
	 *	@param	int		$maxlen			Max length of name
897
	 *  @param	integer	$notooltip		1=Disable tooltip
898
	 *	@return	string					String with supplier price
899
	 *  TODO Remove this method. Use getNomUrl directly.
900
	 */
901
	public function getSocNomUrl($withpicto = 0, $option = 'supplier', $maxlen = 0, $notooltip = 0)
902
	{
903
		$thirdparty = new Fournisseur($this->db);
904
		$thirdparty->fetch($this->fourn_id);
905
906
		return $thirdparty->getNomUrl($withpicto, $option, $maxlen, $notooltip);
907
	}
908
909
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
910
	/**
911
	 *	Display price of product
912
	 *
913
	 *  @param  int     $showunitprice    Show "Unit price" into output string
914
	 *  @param  int     $showsuptitle     Show "Supplier" into output string
915
	 *  @param  int     $maxlen           Max length of name
916
	 *  @param  integer $notooltip        1=Disable tooltip
917
	 *  @param  array   $productFournList list of ProductFournisseur objects
918
	 *                                    to display in table format.
919
	 *  @return string                    String with supplier price
920
	 */
921
	public function display_price_product_fournisseur($showunitprice = 1, $showsuptitle = 1, $maxlen = 0, $notooltip = 0, $productFournList = array())
922
	{
923
		// phpcs:enable
924
		global $langs;
925
926
		$out = '';
927
		$langs->load("suppliers");
928
		if (count($productFournList) > 0) {
929
			$out .= '<table class="nobordernopadding" width="100%">';
930
			$out .= '<tr><td class="liste_titre right">'.($showunitprice ? $langs->trans("Price").' '.$langs->trans("HT") : '').'</td>';
931
			$out .= '<td class="liste_titre right">'.($showunitprice ? $langs->trans("QtyMin") : '').'</td>';
932
			$out .= '<td class="liste_titre">'.$langs->trans("Supplier").'</td>';
933
			$out .= '<td class="liste_titre">'.$langs->trans("SupplierRef").'</td></tr>';
934
			foreach ($productFournList as $productFourn) {
935
				$out .= '<tr><td class="right">'.($showunitprice ?price($productFourn->fourn_unitprice * (1 - $productFourn->fourn_remise_percent / 100) - $productFourn->fourn_remise) : '').'</td>';
936
				$out .= '<td class="right">'.($showunitprice ? $productFourn->fourn_qty : '').'</td>';
937
				$out .= '<td>'.$productFourn->getSocNomUrl(1, 'supplier', $maxlen, $notooltip).'</td>';
938
				$out .= '<td>'.$productFourn->fourn_ref.'<td></tr>';
939
			}
940
			$out .= '</table>';
941
		} else {
942
			$out = ($showunitprice ?price($this->fourn_unitprice * (1 - $this->fourn_remise_percent / 100) + $this->fourn_remise).' '.$langs->trans("HT").' &nbsp; (' : '').($showsuptitle ? $langs->trans("Supplier").': ' : '').$this->getSocNomUrl(1, 'supplier', $maxlen, $notooltip).' / '.$langs->trans("SupplierRef").': '.$this->fourn_ref.($showunitprice ? ')' : '');
1 ignored issue
show
Deprecated Code introduced by
The property ProductFournisseur::$fourn_ref has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

942
			$out = ($showunitprice ?price($this->fourn_unitprice * (1 - $this->fourn_remise_percent / 100) + $this->fourn_remise).' '.$langs->trans("HT").' &nbsp; (' : '').($showsuptitle ? $langs->trans("Supplier").': ' : '').$this->getSocNomUrl(1, 'supplier', $maxlen, $notooltip).' / '.$langs->trans("SupplierRef").': './** @scrutinizer ignore-deprecated */ $this->fourn_ref.($showunitprice ? ')' : '');
Loading history...
943
		}
944
		return $out;
945
	}
946
947
	/**
948
	 * Function used to replace a thirdparty id with another one.
949
	 *
950
	 * @param DoliDB $db Database handler
951
	 * @param int $origin_id Old thirdparty id
952
	 * @param int $dest_id New thirdparty id
953
	 * @return bool
954
	 */
955
	public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
956
	{
957
		$tables = array(
958
			'product_fournisseur_price'
959
		);
960
961
		return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
962
	}
963
964
	/**
965
	 *    List supplier prices log of a supplier price
966
	 *
967
	 *    @param    int     $product_fourn_price_id Id of supplier price
968
	 *    @param	string  $sortfield	            Sort field
969
	 *    @param	string  $sortorder              Sort order
970
	 *    @param	int     $limit                  Limit
971
	 *    @param	int     $offset                 Offset
972
	 *    @return	array   Array of Log prices
973
	 */
974
	public function listProductFournisseurPriceLog($product_fourn_price_id, $sortfield = '', $sortorder = '', $limit = 0, $offset = 0)
975
	{
976
		$sql = "SELECT";
977
		$sql .= " u.lastname,";
978
		$sql .= " pfpl.rowid, pfp.ref_fourn as supplier_ref, pfpl.datec,";
979
		$sql .= " pfpl.price, pfpl.quantity,";
980
		$sql .= " pfpl.fk_multicurrency, pfpl.multicurrency_code, pfpl.multicurrency_tx, pfpl.multicurrency_price, pfpl.multicurrency_unitprice";
981
		$sql .= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price_log as pfpl,";
982
		$sql .= " ".MAIN_DB_PREFIX."product_fournisseur_price as pfp,";
983
		$sql .= " ".MAIN_DB_PREFIX."user as u";
984
		$sql .= " WHERE pfp.entity IN (".getEntity('productprice').")";
985
		$sql .= " AND pfpl.fk_user = u.rowid";
986
		$sql .= " AND pfp.rowid = pfpl.fk_product_fournisseur";
987
		$sql .= " AND pfpl.fk_product_fournisseur = ".$product_fourn_price_id;
988
		if (empty($sortfield)) $sql .= " ORDER BY pfpl.datec";
989
		else $sql .= $this->db->order($sortfield, $sortorder);
990
		$sql .= $this->db->plimit($limit, $offset);
991
		dol_syslog(get_class($this)."::list_product_fournisseur_price_log", LOG_DEBUG);
992
993
		$resql = $this->db->query($sql);
994
		if ($resql)
995
		{
996
			$retarray = array();
997
998
			while ($obj = $this->db->fetch_object($resql))
999
			{
1000
				$tmparray = array();
1001
				$tmparray['rowid'] = $obj->rowid;
1002
				$tmparray['supplier_ref'] = $obj->supplier_ref;
1003
				$tmparray['datec'] = $this->db->jdate($obj->datec);
1004
				$tmparray['lastname'] = $obj->lastname;
1005
				$tmparray['price'] = $obj->price;
1006
				$tmparray['quantity'] = $obj->quantity;
1007
				$tmparray['fk_multicurrency'] = $obj->fk_multicurrency;
1008
				$tmparray['multicurrency_code'] = $obj->multicurrency_code;
1009
				$tmparray['multicurrency_tx'] = $obj->multicurrency_tx;
1010
				$tmparray['multicurrency_price'] = $obj->multicurrency_price;
1011
				$tmparray['multicurrency_unitprice'] = $obj->multicurrency_unitprice;
1012
1013
				$retarray[] = $tmparray;
1014
			}
1015
1016
			$this->db->free($resql);
1017
			return $retarray;
1018
		} else {
1019
			$this->error = $this->db->error();
1020
			return -1;
1021
		}
1022
	}
1023
1024
	/**
1025
	 *	Display log price of product supplier price
1026
	 *
1027
	 *  @param  array   $productFournLogList    list of ProductFournisseur price log objects
1028
	 *                                          to display in table format.
1029
	 *  @return string  HTML String with supplier price
1030
	 */
1031
	public function displayPriceProductFournisseurLog($productFournLogList = array())
1032
	{
1033
		global $conf, $langs;
1034
1035
		$out = '';
1036
		$langs->load("suppliers");
1037
		if (count($productFournLogList) > 0) {
1038
			$out .= '<table class="noborder centpercent">';
1039
			$out .= '<tr class="liste_titre"><td class="liste_titre">'.$langs->trans("Date").'</td>';
1040
			$out .= '<td class="liste_titre right">'.$langs->trans("Price").'</td>';
1041
			//$out .= '<td class="liste_titre right">'.$langs->trans("QtyMin").'</td>';
1042
			$out .= '<td class="liste_titre">'.$langs->trans("User").'</td></tr>';
1043
			foreach ($productFournLogList as $productFournLog) {
1044
				$out .= '<tr><td class="right">'.dol_print_date($productFournLog['datec'], 'dayhour', 'tzuser').'</td>';
1045
				$out .= '<td class="right">'.price($productFournLog['price'], 0, $langs, 1, -1, -1, $conf->currency);
1046
				if ($productFournLog['multicurrency_code'] != $conf->currency) {
1047
					$out .= ' ('.price($productFournLog['multicurrency_price'], 0, $langs, 1, -1, -1, $productFournLog['multicurrency_code']).')';
1048
				}
1049
				$out .= '</td>';
1050
				//$out.= '<td class="right">'.$productFournLog['quantity'].'</td>';
1051
				$out .= '<td>'.$productFournLog['lastname'].'</td></tr>';
1052
			}
1053
			$out .= '</table>';
1054
		}
1055
		return $out;
1056
	}
1057
1058
1059
	/**
1060
	 *  Return a link to the object card (with optionaly the picto).
1061
	 *  Used getNomUrl of ProductFournisseur if a specific supplier ref is loaded. Otherwise use Product->getNomUrl().
1062
	 *
1063
	 *	@param	int		$withpicto					Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto)
1064
	 *	@param	string	$option						On what the link point to ('nolink', ...)
1065
	 *  @param	int  	$notooltip					1=Disable tooltip
1066
	 *  @param  string  $morecss            		Add more css on link
1067
	 *  @param  int     $save_lastsearch_value    	-1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
1068
	 *	@return	string								String with URL
1069
	 */
1070
	public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
1071
	{
1072
		global $db, $conf, $langs;
1073
1074
		if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips
1075
1076
		$result = '';
1077
1078
		if (!empty($this->entity)) {
1079
			$tmpphoto = $this->show_photos('product', $conf->product->multidir_output[$this->entity], 1, 1, 0, 0, 0, 80);
1080
			if ($this->nbphoto > 0) {
1081
				$label .= '<div class="photointooltip">';
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $label seems to be never defined.
Loading history...
1082
				$label .= $tmpphoto;
1083
				$label .= '</div><div style="clear: both;"></div>';
1084
			}
1085
		}
1086
1087
		if ($this->type == Product::TYPE_PRODUCT) {
1088
			$label .= img_picto('', 'product').' <u class="paddingrightonly">'.$langs->trans("Product").'</u>';
1089
		} elseif ($this->type == Product::TYPE_SERVICE) {
1090
			$label .= img_picto('', 'service').' <u class="paddingrightonly">'.$langs->trans("Service").'</u>';
1091
		}
1092
		if (isset($this->status) && isset($this->status_buy)) {
1093
			$label .= ' '.$this->getLibStatut(5, 0);
1094
			$label .= ' '.$this->getLibStatut(5, 1);
1095
		}
1096
1097
		if (!empty($this->ref)) {
1098
			$label .= '<br><b>'.$langs->trans('ProductRef').':</b> '.($this->ref ? $this->ref : $this->product_ref);
1099
		}
1100
		if (!empty($this->label)) {
1101
			$label .= '<br><b>'.$langs->trans('ProductLabel').':</b> '.$this->label;
1102
		}
1103
		$label .= '<br><b>'.$langs->trans('RefSupplier').':</b> '.$this->ref_supplier;
1104
1105
		if ($this->type == Product::TYPE_PRODUCT || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
1106
			if (!empty($conf->productbatch->enabled)) {
1107
				$langs->load("productbatch");
1108
				$label .= "<br><b>".$langs->trans("ManageLotSerial").'</b>: '.$this->getLibStatut(0, 2);
1109
			}
1110
		}
1111
		if (!empty($conf->barcode->enabled)) {
1112
			$label .= '<br><b>'.$langs->trans('BarCode').':</b> '.$this->barcode;
1113
		}
1114
1115
		if ($this->type == Product::TYPE_PRODUCT)
1116
		{
1117
			if ($this->weight) {
1118
				$label .= "<br><b>".$langs->trans("Weight").'</b>: '.$this->weight.' '.measuringUnitString(0, "weight", $this->weight_units);
1119
			}
1120
			$labelsize = "";
1121
			if ($this->length) {
1122
				$labelsize .= ($labelsize ? " - " : "")."<b>".$langs->trans("Length").'</b>: '.$this->length.' '.measuringUnitString(0, 'size', $this->length_units);
1123
			}
1124
			if ($this->width) {
1125
				$labelsize .= ($labelsize ? " - " : "")."<b>".$langs->trans("Width").'</b>: '.$this->width.' '.measuringUnitString(0, 'size', $this->width_units);
1126
			}
1127
			if ($this->height) {
1128
				$labelsize .= ($labelsize ? " - " : "")."<b>".$langs->trans("Height").'</b>: '.$this->height.' '.measuringUnitString(0, 'size', $this->height_units);
1129
			}
1130
			if ($labelsize) $label .= "<br>".$labelsize;
1131
1132
			$labelsurfacevolume = "";
1133
			if ($this->surface) {
1134
				$labelsurfacevolume .= ($labelsurfacevolume ? " - " : "")."<b>".$langs->trans("Surface").'</b>: '.$this->surface.' '.measuringUnitString(0, 'surface', $this->surface_units);
1135
			}
1136
			if ($this->volume) {
1137
				$labelsurfacevolume .= ($labelsurfacevolume ? " - " : "")."<b>".$langs->trans("Volume").'</b>: '.$this->volume.' '.measuringUnitString(0, 'volume', $this->volume_units);
1138
			}
1139
			if ($labelsurfacevolume) $label .= "<br>".$labelsurfacevolume;
1140
		}
1141
1142
		if (!empty($conf->accounting->enabled) && $this->status) {
1143
			include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
1144
			$label .= '<br><b>'.$langs->trans('ProductAccountancySellCode').':</b> '.length_accountg($this->accountancy_code_sell);
1145
			$label .= '<br><b>'.$langs->trans('ProductAccountancySellIntraCode').':</b> '.length_accountg($this->accountancy_code_sell_intra);
1146
			$label .= '<br><b>'.$langs->trans('ProductAccountancySellExportCode').':</b> '.length_accountg($this->accountancy_code_sell_export);
1147
		}
1148
		if (!empty($conf->accounting->enabled) && $this->status_buy) {
1149
			include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
1150
			$label .= '<br><b>'.$langs->trans('ProductAccountancyBuyCode').':</b> '.length_accountg($this->accountancy_code_buy);
1151
			$label .= '<br><b>'.$langs->trans('ProductAccountancyBuyIntraCode').':</b> '.length_accountg($this->accountancy_code_buy_intra);
1152
			$label .= '<br><b>'.$langs->trans('ProductAccountancyBuyExportCode').':</b> '.length_accountg($this->accountancy_code_buy_export);
1153
		}
1154
1155
		$logPrices = $this->listProductFournisseurPriceLog($this->product_fourn_price_id, 'pfpl.datec', 'DESC'); // set sort order here
1156
		if (is_array($logPrices) && count($logPrices) > 0) {
1157
			$label .= '<br><br>';
1158
			$label .= '<u>'.$langs->trans("History").'</u>';
1159
			$label .= $this->displayPriceProductFournisseurLog($logPrices);
1160
		}
1161
1162
		$url = dol_buildpath('/product/fournisseurs.php', 1).'?id='.$this->id.'&action=add_price&socid='.$this->fourn_id.'&rowid='.$this->product_fourn_price_id;
1163
1164
		if ($option != 'nolink')
1165
		{
1166
			// Add param to save lastsearch_values or not
1167
			$add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1168
			if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1;
1169
			if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1';
1170
		}
1171
1172
		$linkclose = '';
1173
		if (empty($notooltip))
1174
		{
1175
			if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
1176
			{
1177
				$label = $langs->trans("SupplierRef");
1178
				$linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1179
			}
1180
			$linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $label does not seem to be defined for all execution paths leading up to this point.
Loading history...
1181
			$linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
1182
		} else $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1183
1184
		$linkstart = '<a href="'.$url.'"';
1185
		$linkstart .= $linkclose.'>';
1186
		$linkend = '</a>';
1187
1188
		$result .= $linkstart;
1189
		if ($withpicto) $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
1190
		if ($withpicto != 2) $result .= $this->ref.($this->ref_supplier ? ' ('.$this->ref_supplier.')' : '');
1191
		$result .= $linkend;
1192
		//if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
1193
1194
		return $result;
1195
	}
1196
1197
	/**
1198
	 * Private function to log price history
1199
	 *
1200
	 * @param User      $user                           Object user who adds/changes price
1201
	 * @param integer   $datec                          date create
1202
	 * @param float     $buyprice                       price for qty
1203
	 * @param float     $qty                            qty for price
1204
	 * @param float     $multicurrency_buyprice         Purchase price for the quantity min in currency
1205
	 * @param float     $multicurrency_unitBuyPrice     Unit Purchase price in currency
1206
	 * @param float     $multicurrency_tx               Rate currency
1207
	 * @param int       $fk_multicurrency               key multi currency
1208
	 * @param string    $multicurrency_code	            Currency code
1209
	 *
1210
	 * @return int < 0 NOK > 0 OK
1211
	 */
1212
	private function logPrice($user, $datec, $buyprice, $qty, $multicurrency_buyprice = null, $multicurrency_unitBuyPrice = null, $multicurrency_tx = null, $fk_multicurrency = null, $multicurrency_code = null)
1213
	{
1214
		// Add record into log table
1215
		$sql = "INSERT INTO ".MAIN_DB_PREFIX."product_fournisseur_price_log(";
1216
		$sql .= " multicurrency_price, multicurrency_unitprice, multicurrency_tx, fk_multicurrency, multicurrency_code,";
1217
		$sql .= "datec, fk_product_fournisseur,fk_user,price,quantity)";
1218
		$sql .= "values(";
1219
		$sql .= (isset($multicurrency_buyprice) ? "'".$this->db->escape(price2num($multicurrency_buyprice))."'" : 'null').",";
1220
		$sql .= (isset($multicurrency_unitBuyPrice) ? "'".$this->db->escape(price2num($multicurrency_unitBuyPrice))."'" : 'null').",";
1221
		$sql .= (isset($multicurrency_tx) ? "'".$this->db->escape($multicurrency_tx)."'" : '1').",";
1222
		$sql .= (isset($fk_multicurrency) ? "'".$this->db->escape($fk_multicurrency)."'" : 'null').",";
1223
		$sql .= (isset($multicurrency_code) ? "'".$this->db->escape($multicurrency_code)."'" : 'null').",";
1224
		$sql .= "'".$this->db->idate($datec)."',";
1225
		$sql .= " ".$this->product_fourn_price_id.",";
1226
		$sql .= " ".$user->id.",";
1227
		$sql .= " ".price2num($buyprice).",";
1228
		$sql .= " ".$qty;
1229
		$sql .= ")";
1230
1231
		$resql = $this->db->query($sql);
1232
		if (!$resql) {
1233
			return -1;
1234
		} else {
1235
			return 1;
1236
		}
1237
	}
1238
}
1239