dolibarr  20.0.0-beta
price.lib.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2002-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2006-2008 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2010-2013 Juanjo Menent <jmenent@2byte.es>
5  * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
6  * Copyright (C) 2012 Cédric Salvador <csalvador@gpcsolutions.fr>
7  * Copyright (C) 2012-2014 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
8  * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
9  * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program. If not, see <https://www.gnu.org/licenses/>.
23  */
24 
88 function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller = '', $localtaxes_array = [], $progress = 100, $multicurrency_tx = 1, $pu_devise = 0, $multicurrency_code = '')
89 {
90  global $conf, $mysoc, $db;
91 
92  $result = array();
93 
94  // Clean parameters
95  if (empty($info_bits)) {
96  $info_bits = 0;
97  }
98  if (empty($txtva)) {
99  $txtva = 0;
100  }
101  if (empty($seller) || !is_object($seller)) {
102  dol_syslog("Price.lib::calcul_price_total Warning: function is called with parameter seller that is missing", LOG_WARNING);
103  if (!is_object($mysoc)) { // mysoc may be not defined (during migration process)
104  $mysoc = new Societe($db);
105  $mysoc->setMysoc($conf);
106  }
107  $seller = $mysoc; // If sell is done to a customer, $seller is not provided, we use $mysoc
108  //var_dump($seller->country_id);exit;
109  }
110  if (empty($localtaxes_array) || !is_array($localtaxes_array)) {
111  dol_syslog("Price.lib::calcul_price_total Warning: function is called with parameter localtaxes_array that is missing or empty", LOG_WARNING);
112  }
113  if (!is_numeric($txtva)) {
114  dol_syslog("Price.lib::calcul_price_total Warning: function was called with a parameter vat rate that is not a real numeric value. There is surely a bug.", LOG_ERR);
115  } elseif ($txtva >= 1000) {
116  dol_syslog("Price.lib::calcul_price_total Warning: function was called with a bad value for vat rate (should be often < 100, always < 1000). There is surely a bug.", LOG_ERR);
117  }
118  // Too verbose. Enable for debug only
119  // dol_syslog("Price.lib::calcul_price_total qty=".$qty." pu=".$pu." remiserpercent_ligne=".$remise_percent_ligne." txtva=".$txtva." uselocaltax1_rate=".$uselocaltax1_rate." uselocaltax2_rate=".$uselocaltax2_rate.' remise_percent_global='.$remise_percent_global.' price_base_type='.$ice_base_type.' type='.$type.' progress='.$progress);
120 
121  $countryid = $seller->country_id;
122 
123  if (is_numeric($uselocaltax1_rate)) {
124  $uselocaltax1_rate = (float) $uselocaltax1_rate;
125  }
126  if (is_numeric($uselocaltax2_rate)) {
127  $uselocaltax2_rate = (float) $uselocaltax2_rate;
128  }
129 
130  if ($uselocaltax1_rate < 0) {
131  $uselocaltax1_rate = $seller->localtax1_assuj;
132  }
133  if ($uselocaltax2_rate < 0) {
134  $uselocaltax2_rate = $seller->localtax2_assuj;
135  }
136 
137  //var_dump($uselocaltax1_rate.' - '.$uselocaltax2_rate);
138  dol_syslog('Price.lib::calcul_price_total qty='.$qty.' pu='.$pu.' remise_percent_ligne='.$remise_percent_ligne.' txtva='.$txtva.' uselocaltax1_rate='.$uselocaltax1_rate.' uselocaltax2_rate='.$uselocaltax2_rate.' remise_percent_global='.$remise_percent_global.' price_base_type='.$price_base_type.' type='.$type.' progress='.$progress);
139 
140  // Now we search localtaxes information ourself (rates and types).
141  $localtax1_type = 0;
142  $localtax2_type = 0;
143 
144  if (is_array($localtaxes_array) && count($localtaxes_array)) {
145  $localtax1_type = $localtaxes_array[0];
146  $localtax1_rate = $localtaxes_array[1];
147  $localtax2_type = $localtaxes_array[2];
148  $localtax2_rate = $localtaxes_array[3];
149  } else {
150  // deprecated method. values and type for localtaxes must be provided by caller and loaded with getLocalTaxesFromRate using the full vat rate (including text code)
151  // also, with this method, we may get several possible values (for example with localtax2 in spain), so we take the first one.
152  dol_syslog("Price.lib::calcul_price_total search vat information using old deprecated method", LOG_WARNING);
153 
154  $sql = "SELECT taux, localtax1, localtax2, localtax1_type, localtax2_type";
155  $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as cv";
156  $sql .= " WHERE cv.taux = ".((float) $txtva);
157  $sql .= " AND cv.fk_pays = ".((int) $countryid);
158  $sql .= " AND cv.entity IN (".getEntity('c_tva').")";
159  $resql = $db->query($sql);
160  if ($resql) {
161  $obj = $db->fetch_object($resql);
162  if ($obj) {
163  $localtax1_rate = (float) $obj->localtax1; // Use float to force to get first numeric value when value is x:y:z
164  $localtax2_rate = (float) $obj->localtax2; // Use float to force to get first numeric value when value is -19:-15:-9
165  $localtax1_type = $obj->localtax1_type;
166  $localtax2_type = $obj->localtax2_type;
167  //var_dump($localtax1_rate.' '.$localtax2_rate.' '.$localtax1_type.' '.$localtax2_type);
168  }
169  } else {
170  dol_print_error($db);
171  }
172  }
173 
174  // pu calculation from pu_devise if pu empty
175  if (empty($pu) && !empty($pu_devise)) {
176  if (!empty($multicurrency_tx)) {
177  $pu = $pu_devise / $multicurrency_tx;
178  } else {
179  dol_syslog('Price.lib::calcul_price_total function called with bad parameters combination (multicurrency_tx empty when pu_devise not) ', LOG_ERR);
180  return array();
181  }
182  }
183  if ($pu === '') {
184  $pu = 0;
185  }
186  // pu_devise calculation from pu
187  if (empty($pu_devise) && !empty($multicurrency_tx)) {
188  if (is_numeric($pu) && is_numeric($multicurrency_tx)) {
189  $pu_devise = $pu * $multicurrency_tx;
190  } else {
191  dol_syslog('Price.lib::calcul_price_total function called with bad parameters combination (pu or multicurrency_tx are not numeric)', LOG_ERR);
192  return array();
193  }
194  }
195 
196  // initialize total (may be HT or TTC depending on price_base_type)
197  $tot_sans_remise = $pu * $qty * $progress / 100;
198  $tot_avec_remise_ligne = $tot_sans_remise * (1 - ((float) $remise_percent_ligne / 100));
199  $tot_avec_remise = $tot_avec_remise_ligne * (1 - ((float) $remise_percent_global / 100));
200 
201  // initialize result array
202  for ($i = 0; $i <= 15; $i++) {
203  $result[$i] = 0;
204  }
205 
206  // if there's some localtax including vat, we calculate localtaxes (we will add later)
207 
208  // if input unit price is 'HT', we need to have the totals with main VAT for a correct calculation
209  if ($price_base_type != 'TTC') {
210  $tot_sans_remise_wt = price2num($tot_sans_remise * (1 + ($txtva / 100)), 'MU');
211  $tot_avec_remise_wt = price2num($tot_avec_remise * (1 + ($txtva / 100)), 'MU');
212  $pu_wt = price2num($pu * (1 + ($txtva / 100)), 'MU');
213  } else {
214  $tot_sans_remise_wt = $tot_sans_remise;
215  $tot_avec_remise_wt = $tot_avec_remise;
216  $pu_wt = $pu;
217  }
218 
219  //print 'rr'.$price_base_type.'-'.$txtva.'-'.$tot_sans_remise_wt."-".$pu_wt."-".$uselocaltax1_rate."-".$localtax1_rate."-".$localtax1_type."\n";
220 
221  $localtaxes = array(0, 0, 0);
222  $apply_tax = false;
223  switch ($localtax1_type) {
224  case '2': // localtax on product or service
225  $apply_tax = true;
226  break;
227  case '4': // localtax on product
228  if ($type == 0) {
229  $apply_tax = true;
230  }
231  break;
232  case '6': // localtax on service
233  if ($type == 1) {
234  $apply_tax = true;
235  }
236  break;
237  }
238 
239  if ($uselocaltax1_rate && $apply_tax) {
240  $result[14] = price2num(($tot_sans_remise_wt * (1 + ($localtax1_rate / 100))) - $tot_sans_remise_wt, 'MT');
241  $localtaxes[0] += $result[14];
242 
243  $result[9] = price2num(($tot_avec_remise_wt * (1 + ($localtax1_rate / 100))) - $tot_avec_remise_wt, 'MT');
244  $localtaxes[1] += $result[9];
245 
246  $result[11] = price2num(($pu_wt * (1 + ($localtax1_rate / 100))) - $pu_wt, 'MU');
247  $localtaxes[2] += $result[11];
248  }
249 
250  $apply_tax = false;
251  switch ($localtax2_type) {
252  case '2': // localtax on product or service
253  $apply_tax = true;
254  break;
255  case '4': // localtax on product
256  if ($type == 0) {
257  $apply_tax = true;
258  }
259  break;
260  case '6': // localtax on service
261  if ($type == 1) {
262  $apply_tax = true;
263  }
264  break;
265  }
266  if ($uselocaltax2_rate && $apply_tax) {
267  $result[15] = price2num(($tot_sans_remise_wt * (1 + ($localtax2_rate / 100))) - $tot_sans_remise_wt, 'MT');
268  $localtaxes[0] += $result[15];
269 
270  $result[10] = price2num(($tot_avec_remise_wt * (1 + ($localtax2_rate / 100))) - $tot_avec_remise_wt, 'MT');
271  $localtaxes[1] += $result[10];
272 
273  $result[12] = price2num(($pu_wt * (1 + ($localtax2_rate / 100))) - $pu_wt, 'MU');
274  $localtaxes[2] += $result[12];
275  }
276 
277  //dol_syslog("price.lib::calcul_price_total $qty, $pu, $remise_percent_ligne, $txtva, $price_base_type $info_bits");
278  if ($price_base_type == 'HT') {
279  // We work to define prices using the price without tax
280  $result[6] = price2num($tot_sans_remise, 'MT');
281  $result[8] = price2num($tot_sans_remise * (1 + ((($info_bits & 1) ? 0 : $txtva) / 100)) + $localtaxes[0], 'MT'); // Selon TVA NPR ou non
282  $result8bis = price2num($tot_sans_remise * (1 + ($txtva / 100)) + $localtaxes[0], 'MT'); // Si TVA consideree normal (non NPR)
283  $result[7] = price2num((float) $result8bis - ((float) $result[6] + $localtaxes[0]), 'MT');
284 
285  $result[0] = price2num($tot_avec_remise, 'MT');
286  $result[2] = price2num($tot_avec_remise * (1 + ((($info_bits & 1) ? 0 : $txtva) / 100)) + $localtaxes[1], 'MT'); // Selon TVA NPR ou non
287  $result2bis = price2num($tot_avec_remise * (1 + ($txtva / 100)) + $localtaxes[1], 'MT'); // Si TVA consideree normal (non NPR)
288  $result[1] = price2num((float) $result2bis - ((float) $result[0] + $localtaxes[1]), 'MT'); // Total VAT = TTC - (HT + localtax)
289 
290  $result[3] = price2num($pu, 'MU');
291  $result[5] = price2num($pu * (1 + ((($info_bits & 1) ? 0 : $txtva) / 100)) + $localtaxes[2], 'MU'); // Selon TVA NPR ou non
292  $result5bis = price2num($pu * (1 + ($txtva / 100)) + $localtaxes[2], 'MU'); // Si TVA consideree normal (non NPR)
293  $result[4] = price2num((float) $result5bis - ((float) $result[3] + $localtaxes[2]), 'MU');
294  } else {
295  // We work to define prices using the price with tax
296  $result[8] = price2num($tot_sans_remise + $localtaxes[0], 'MT');
297  $result[6] = price2num($tot_sans_remise / (1 + ((($info_bits & 1) ? 0 : $txtva) / 100)), 'MT'); // Selon TVA NPR ou non
298  $result6bis = price2num($tot_sans_remise / (1 + ($txtva / 100)), 'MT'); // Si TVA consideree normal (non NPR)
299  $result[7] = price2num((float) $result[8] - ((float) $result6bis + $localtaxes[0]), 'MT');
300 
301  $result[2] = price2num((float) $tot_avec_remise + (float) $localtaxes[1], 'MT');
302  $result[0] = price2num((float) $tot_avec_remise / (1 + ((($info_bits & 1) ? 0 : (float) $txtva) / 100)), 'MT'); // Selon TVA NPR ou non
303  $result0bis = price2num((float) $tot_avec_remise / (1 + ((float) $txtva / 100)), 'MT'); // Si TVA consideree normal (non NPR)
304  $result[1] = price2num((float) $result[2] - ((float) $result0bis + (float) $localtaxes[1]), 'MT'); // Total VAT = TTC - (HT + localtax)
305 
306  $result[5] = price2num($pu + $localtaxes[2], 'MU');
307  $result[3] = price2num($pu / (1 + ((($info_bits & 1) ? 0 : $txtva) / 100)), 'MU'); // Selon TVA NPR ou non
308  $result3bis = price2num($pu / (1 + ($txtva / 100)), 'MU'); // Si TVA consideree normal (non NPR)
309  $result[4] = price2num((float) $result[5] - ((float) $result3bis + (float) $localtaxes[2]), 'MU');
310  }
311 
312  // if there's some localtax without vat, we calculate localtaxes (we will add them at end)
313 
314  //If input unit price is 'TTC', we need to have the totals without main VAT for a correct calculation
315  if ($price_base_type == 'TTC') {
316  $tot_sans_remise = price2num($tot_sans_remise / (1 + ($txtva / 100)), 'MU');
317  $tot_avec_remise = price2num($tot_avec_remise / (1 + ($txtva / 100)), 'MU');
318  $pu = price2num($pu / (1 + ($txtva / 100)), 'MU');
319  }
320 
321  $apply_tax = false;
322  switch ($localtax1_type) {
323  case '1': // localtax on product or service
324  $apply_tax = true;
325  break;
326  case '3': // localtax on product
327  if ($type == 0) {
328  $apply_tax = true;
329  }
330  break;
331  case '5': // localtax on service
332  if ($type == 1) {
333  $apply_tax = true;
334  }
335  break;
336  }
337  if ($uselocaltax1_rate && $apply_tax) {
338  $result[14] = price2num(($tot_sans_remise * (1 + ($localtax1_rate / 100))) - $tot_sans_remise, 'MT'); // amount tax1 for total_ht_without_discount
339  $result[8] += $result[14]; // total_ttc_without_discount + tax1
340 
341  $result[9] = price2num(($tot_avec_remise * (1 + ($localtax1_rate / 100))) - $tot_avec_remise, 'MT'); // amount tax1 for total_ht
342  $result[2] += $result[9]; // total_ttc + tax1
343 
344  $result[11] = price2num(($pu * (1 + ($localtax1_rate / 100))) - $pu, 'MU'); // amount tax1 for pu_ht
345  $result[5] += $result[11]; // pu_ht + tax1
346  }
347 
348  $apply_tax = false;
349  switch ($localtax2_type) {
350  case '1': // localtax on product or service
351  $apply_tax = true;
352  break;
353  case '3': // localtax on product
354  if ($type == 0) {
355  $apply_tax = true;
356  }
357  break;
358  case '5': // localtax on service
359  if ($type == 1) {
360  $apply_tax = true;
361  }
362  break;
363  }
364  if ($uselocaltax2_rate && $apply_tax) {
365  $result[15] = price2num(($tot_sans_remise * (1 + ($localtax2_rate / 100))) - $tot_sans_remise, 'MT'); // amount tax2 for total_ht_without_discount
366  $result[8] += $result[15]; // total_ttc_without_discount + tax2
367 
368  $result[10] = price2num(($tot_avec_remise * (1 + ($localtax2_rate / 100))) - $tot_avec_remise, 'MT'); // amount tax2 for total_ht
369  $result[2] += $result[10]; // total_ttc + tax2
370 
371  $result[12] = price2num(($pu * (1 + ($localtax2_rate / 100))) - $pu, 'MU'); // amount tax2 for pu_ht
372  $result[5] += $result[12]; // pu_ht + tax2
373  }
374 
375  // If rounding is not using base 10 (rare)
376  if (getDolGlobalString('MAIN_ROUNDING_RULE_TOT')) {
377  if ($price_base_type == 'HT') {
378  $result[0] = price2num(round((float) $result[0] / (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 0) * (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 'MT');
379  $result[1] = price2num(round((float) $result[1] / (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 0) * (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 'MT');
380  $result[9] = price2num(round((float) $result[9] / (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 0) * (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 'MT');
381  $result[10] = price2num(round((float) $result[10] / (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 0) * (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 'MT');
382  $result[2] = price2num((float) $result[0] + (float) $result[1] + (float) $result[9] + (float) $result[10], 'MT');
383  } else {
384  $result[1] = price2num(round((float) $result[1] / (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 0) * (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 'MT');
385  $result[2] = price2num(round((float) $result[2] / (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 0) * (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 'MT');
386  $result[9] = price2num(round((float) $result[9] / (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 0) * (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 'MT');
387  $result[10] = price2num(round((float) $result[10] / (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 0) * (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 'MT');
388  $result[0] = price2num((float) $result[2] - (float) $result[1] - (float) $result[9] - (float) $result[10], 'MT');
389  }
390  }
391 
392  // Multicurrency
393  if ($multicurrency_tx != 1) {
394  if ($multicurrency_code) {
395  $savMAIN_MAX_DECIMALS_UNIT = getDolGlobalString('MAIN_MAX_DECIMALS_UNIT');
396  $savMAIN_MAX_DECIMALS_TOT = getDolGlobalString('MAIN_MAX_DECIMALS_TOT');
397  $savMAIN_ROUNDING_RULE_TOT = getDolGlobalString('MAIN_ROUNDING_RULE_TOT');
398 
399  // Set parameter for currency accurency according to the value of $multicurrency_code (this is because a foreign currency may have different rounding rules)
400  $keyforforeignMAIN_MAX_DECIMALS_UNIT = 'MAIN_MAX_DECIMALS_UNIT_'.$multicurrency_code;
401  $keyforforeignMAIN_MAX_DECIMALS_TOT = 'MAIN_MAX_DECIMALS_TOT_'.$multicurrency_code;
402  $keyforforeignMAIN_ROUNDING_RULE_TOT = 'MAIN_ROUNDING_RULE_TOT_'.$multicurrency_code;
403  if (getDolGlobalString($keyforforeignMAIN_ROUNDING_RULE_TOT)) {
404  $conf->global->MAIN_MAX_DECIMALS_UNIT = getDolGlobalString($keyforforeignMAIN_MAX_DECIMALS_UNIT);
405  $conf->global->MAIN_MAX_DECIMALS_TOT = getDolGlobalString($keyforforeignMAIN_MAX_DECIMALS_TOT);
406  $conf->global->MAIN_ROUNDING_RULE_TOT = getDolGlobalString($keyforforeignMAIN_ROUNDING_RULE_TOT);
407  }
408  }
409 
410  // Recall function using the multicurrency price as reference price. We must set param $multicurrency_tx to 1 to avoid infinite loop.
411  $newresult = calcul_price_total($qty, $pu_devise, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller, $localtaxes_array, $progress, 1, 0, '');
412 
413  if ($multicurrency_code) {
414  // Restore setup of currency accurency
415  $conf->global->MAIN_MAX_DECIMALS_UNIT = $savMAIN_MAX_DECIMALS_UNIT; // @phan-suppress-current-line PhanPossiblyUndeclaredVariable
416  $conf->global->MAIN_MAX_DECIMALS_TOT = $savMAIN_MAX_DECIMALS_TOT; // @phan-suppress-current-line PhanPossiblyUndeclaredVariable
417  $conf->global->MAIN_ROUNDING_RULE_TOT = $savMAIN_ROUNDING_RULE_TOT; // @phan-suppress-current-line PhanPossiblyUndeclaredVariable
418  }
419 
420  $result[16] = $newresult[0];
421  $result[17] = $newresult[1];
422  $result[18] = $newresult[2];
423  $result[19] = $newresult[3];
424  $result[20] = $newresult[4];
425  $result[21] = $newresult[5];
426  $result[22] = $newresult[6];
427  $result[23] = $newresult[7];
428  $result[24] = $newresult[8];
429  $result[25] = $newresult[9];
430  $result[26] = $newresult[10];
431  } else {
432  $result[16] = $result[0];
433  $result[17] = $result[1];
434  $result[18] = $result[2];
435  $result[19] = $result[3];
436  $result[20] = $result[4];
437  $result[21] = $result[5];
438  $result[22] = $result[6];
439  $result[23] = $result[7];
440  $result[24] = $result[8];
441  $result[25] = $result[9];
442  $result[26] = $result[10];
443  }
444  dol_syslog('Price.lib::calcul_price_total MAIN_ROUNDING_RULE_TOT='.getDolGlobalString('MAIN_ROUNDING_RULE_TOT').' pu='.$pu.' qty='.$qty.' price_base_type='.$price_base_type.' total_ht='.$result[0].'-total_vat='.$result[1].'-total_ttc='.$result[2]);
445 
446  return $result;
447 }
Class to manage third parties objects (customers, suppliers, prospects...)
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:745
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
div float
Buy price without taxes.
Definition: style.css.php:960
calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller='', $localtaxes_array=[], $progress=100, $multicurrency_tx=1, $pu_devise=0, $multicurrency_code='')
Calculate totals (net, vat, ...) of a line.
Definition: price.lib.php:88