dolibarr  13.0.2
limits.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2007-2020 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2009-2018 Regis Houssin <regis.houssin@inodbox.com>
4  * Copyright (C) 2010 Juanjo Menent <jmenent@2byte.es>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
25 require '../main.inc.php';
26 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
27 require_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
28 
29 // Load translation files required by the page
30 $langs->loadLangs(array('companies', 'products', 'admin'));
31 
32 if (!$user->admin) accessforbidden();
33 
34 $action = GETPOST('action', 'aZ09');
35 $currencycode = GETPOST('currencycode', 'alpha');
36 
37 if (!empty($conf->multicurrency->enabled) && !empty($conf->global->MULTICURRENCY_USE_LIMIT_BY_CURRENCY)) {
38  // When MULTICURRENCY_USE_LIMIT_BY_CURRENCY is on, we use always a defined currency code instead of '' even for default.
39  $currencycode = (!empty($currencycode) ? $currencycode : $conf->currency);
40 }
41 
42 $mainmaxdecimalsunit = 'MAIN_MAX_DECIMALS_UNIT'.(!empty($currencycode) ? '_'.$currencycode : '');
43 $mainmaxdecimalstot = 'MAIN_MAX_DECIMALS_TOT'.(!empty($currencycode) ? '_'.$currencycode : '');
44 $mainmaxdecimalsshown = 'MAIN_MAX_DECIMALS_SHOWN'.(!empty($currencycode) ? '_'.$currencycode : '');
45 $mainroundingruletot = 'MAIN_ROUNDING_RULE_TOT'.(!empty($currencycode) ? '_'.$currencycode : '');
46 
47 $valmainmaxdecimalsunit = GETPOST($mainmaxdecimalsunit, 'int');
48 $valmainmaxdecimalstot = GETPOST($mainmaxdecimalstot, 'int');
49 $valmainmaxdecimalsshown = GETPOST($mainmaxdecimalsshown, 'int');
50 $valmainroundingruletot = price2num(GETPOST($mainroundingruletot, 'alpha'));
51 
52 if ($action == 'update')
53 {
54  $error = 0;
55  $MAXDEC = 8;
56  if ($_POST[$mainmaxdecimalsunit] > $MAXDEC
57  || $_POST[$mainmaxdecimalstot] > $MAXDEC
58  || $_POST[$mainmaxdecimalsshown] > $MAXDEC)
59  {
60  $error++;
61  setEventMessages($langs->trans("ErrorDecimalLargerThanAreForbidden", $MAXDEC), null, 'errors');
62  }
63 
64  if ($_POST[$mainmaxdecimalsunit].(!empty($currencycode) ? '_'.$currencycode : '') < 0
65  || $_POST[$mainmaxdecimalstot] < 0
66  || $_POST[$mainmaxdecimalsshown] < 0)
67  {
68  $langs->load("errors");
69  $error++;
70  setEventMessages($langs->trans("ErrorNegativeValueNotAllowed"), null, 'errors');
71  }
72 
73  if ($valmainroundingruletot)
74  {
75  if ($valmainroundingruletot * pow(10, $valmainmaxdecimalstot) < 1)
76  {
77  $langs->load("errors");
78  $error++;
79  setEventMessages($langs->trans("ErrorMAIN_ROUNDING_RULE_TOTCanMAIN_MAX_DECIMALS_TOT"), null, 'errors');
80  }
81  }
82 
83  if (!$error)
84  {
85  dolibarr_set_const($db, $mainmaxdecimalsunit, $valmainmaxdecimalsunit, 'chaine', 0, '', $conf->entity);
86  dolibarr_set_const($db, $mainmaxdecimalstot, $valmainmaxdecimalstot, 'chaine', 0, '', $conf->entity);
87  dolibarr_set_const($db, $mainmaxdecimalsshown, $valmainmaxdecimalsshown, 'chaine', 0, '', $conf->entity);
88 
89  dolibarr_set_const($db, $mainroundingruletot, $valmainroundingruletot, 'chaine', 0, '', $conf->entity);
90 
91  header("Location: ".$_SERVER["PHP_SELF"]."?mainmenu=home&leftmenu=setup".(!empty($currencycode) ? '&currencycode='.$currencycode : ''));
92  exit;
93  }
94 }
95 
96 
97 /*
98  * View
99  */
100 
101 $form = new Form($db);
102 
103 $title = $langs->trans("LimitsSetup");
104 $help_url = '';
105 
106 llxHeader('', $title, $help_url);
107 
108 print load_fiche_titre($title, '', 'title_setup');
109 
110 $aCurrencies = array($conf->currency); // Default currency always first position
111 
112 if (!empty($conf->multicurrency->enabled) && !empty($conf->global->MULTICURRENCY_USE_LIMIT_BY_CURRENCY))
113 {
114  require_once DOL_DOCUMENT_ROOT.'/core/lib/multicurrency.lib.php';
115 
116  $sql = 'SELECT rowid, code FROM '.MAIN_DB_PREFIX.'multicurrency';
117  $sql .= ' WHERE entity = '.$conf->entity;
118  $sql .= ' AND code != "'.$conf->currency.'"'; // Default currency always first position
119  $resql = $db->query($sql);
120  if ($resql)
121  {
122  while ($obj = $db->fetch_object($resql))
123  {
124  $aCurrencies[] = $obj->code;
125  }
126  }
127 
128  if (!empty($aCurrencies) && count($aCurrencies) > 1)
129  {
130  $head = multicurrencyLimitPrepareHead($aCurrencies);
131 
132  print dol_get_fiche_head($head, $currencycode, '', -1, '');
133  }
134 }
135 
136 print '<span class="opacitymedium">'.$langs->trans("LimitsDesc")."</span><br>\n";
137 print "<br>\n";
138 
139 if ($action == 'edit')
140 {
141  print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
142  print '<input type="hidden" name="token" value="'.newToken().'">';
143  print '<input type="hidden" name="action" value="update">';
144  if (!empty($conf->multicurrency->enabled) && !empty($conf->global->MULTICURRENCY_USE_LIMIT_BY_CURRENCY)) {
145  print '<input type="hidden" name="currencycode" value="'.$currencycode.'">';
146  }
147 
148  clearstatcache();
149 
150  print '<table class="noborder centpercent">';
151  print '<tr class="liste_titre"><td>'.$langs->trans("Parameters").'</td><td>'.$langs->trans("Value").'</td></tr>';
152 
153  print '<tr class="oddeven"><td>';
154  print $form->textwithpicto($langs->trans("MAIN_MAX_DECIMALS_UNIT"), $langs->trans("ParameterActiveForNextInputOnly"));
155  print '</td><td><input class="flat" name="'.$mainmaxdecimalsunit.'" size="3" value="'.(isset($conf->global->$mainmaxdecimalsunit) ? $conf->global->$mainmaxdecimalsunit : $conf->global->MAIN_MAX_DECIMALS_UNIT).'"></td></tr>';
156 
157  print '<tr class="oddeven"><td>';
158  print $form->textwithpicto($langs->trans("MAIN_MAX_DECIMALS_TOT"), $langs->trans("ParameterActiveForNextInputOnly"));
159  print '</td><td><input class="flat" name="'.$mainmaxdecimalstot.'" size="3" value="'.(isset($conf->global->$mainmaxdecimalstot) ? $conf->global->$mainmaxdecimalstot : $conf->global->MAIN_MAX_DECIMALS_TOT).'"></td></tr>';
160 
161  print '<tr class="oddeven"><td>'.$langs->trans("MAIN_MAX_DECIMALS_SHOWN").'</td>';
162  print '<td><input class="flat" name="'.$mainmaxdecimalsshown.'" size="3" value="'.(isset($conf->global->$mainmaxdecimalsshown) ? $conf->global->$mainmaxdecimalsshown : $conf->global->MAIN_MAX_DECIMALS_SHOWN).'"></td></tr>';
163 
164  print '<tr class="oddeven"><td>';
165  print $form->textwithpicto($langs->trans("MAIN_ROUNDING_RULE_TOT"), $langs->trans("ParameterActiveForNextInputOnly"));
166  print '</td><td><input class="flat" name="'.$mainroundingruletot.'" size="3" value="'.(isset($conf->global->$mainroundingruletot) ? $conf->global->$mainroundingruletot : $conf->global->MAIN_ROUNDING_RULE_TOT).'"></td></tr>';
167 
168  print '</table>';
169 
170  print '<br>';
171  print '<div class="center">';
172  print '<input class="button button-save" type="submit" value="'.$langs->trans("Save").'">';
173  print '</div>';
174  print '<br>';
175 
176  print '</form>';
177  print '<br>';
178 } else {
179  print '<div class="div-table-responsive-no-min">';
180  print '<table class="noborder centpercent">';
181  print '<tr class="liste_titre"><td>'.$langs->trans("Parameter").'</td><td>'.$langs->trans("Value").'</td></tr>';
182 
183  print '<tr class="oddeven"><td>';
184  print $form->textwithpicto($langs->trans("MAIN_MAX_DECIMALS_UNIT"), $langs->trans("ParameterActiveForNextInputOnly"));
185  print '</td><td align="right">'.(isset($conf->global->$mainmaxdecimalsunit) ? $conf->global->$mainmaxdecimalsunit : $conf->global->MAIN_MAX_DECIMALS_UNIT).'</td></tr>';
186 
187  print '<tr class="oddeven"><td>';
188  print $form->textwithpicto($langs->trans("MAIN_MAX_DECIMALS_TOT"), $langs->trans("ParameterActiveForNextInputOnly"));
189  print '</td><td align="right">'.(isset($conf->global->$mainmaxdecimalstot) ? $conf->global->$mainmaxdecimalstot : $conf->global->MAIN_MAX_DECIMALS_TOT).'</td></tr>';
190 
191  print '<tr class="oddeven"><td>'.$langs->trans("MAIN_MAX_DECIMALS_SHOWN").'</td>';
192  print '<td align="right">'.(isset($conf->global->$mainmaxdecimalsshown) ? $conf->global->$mainmaxdecimalsshown : $conf->global->MAIN_MAX_DECIMALS_SHOWN).'</td></tr>';
193 
194  print '<tr class="oddeven"><td>';
195  print $form->textwithpicto($langs->trans("MAIN_ROUNDING_RULE_TOT"), $langs->trans("ParameterActiveForNextInputOnly"));
196  print '</td><td align="right">'.(isset($conf->global->$mainroundingruletot) ? $conf->global->$mainroundingruletot : $conf->global->MAIN_ROUNDING_RULE_TOT).'</td></tr>';
197 
198  print '</table>';
199  print '</div>';
200 
201  print '<div class="tabsAction">';
202  print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit'.(!empty($currencycode) ? '&currencycode='.$currencycode : '').'">'.$langs->trans("Modify").'</a>';
203  print '</div>';
204 }
205 
206 if (!empty($conf->multicurrency->enabled) && !empty($conf->global->MULTICURRENCY_USE_LIMIT_BY_CURRENCY))
207 {
208  if (!empty($aCurrencies) && count($aCurrencies) > 1)
209  {
210  print dol_get_fiche_end();
211  }
212 }
213 
214 if (empty($mysoc->country_code))
215 {
216  $langs->load("errors");
217  $warnpicto = img_warning($langs->trans("WarningMandatorySetupNotComplete"));
218  print '<br><a href="'.DOL_URL_ROOT.'/admin/company.php?mainmenu=home">'.$warnpicto.' '.$langs->trans("WarningMandatorySetupNotComplete").'</a>';
219 } else {
220  // Show examples
221  print load_fiche_titre($langs->trans("ExamplesWithCurrentSetup"), '', '');
222 
223  print '<span class="opacitymedium">'.$langs->trans("Format").':</span> '.price(price2num(1234.56789, 'MT'), 0, $langs, 1, -1, -1, $currencycode)."<br>\n";
224 
225  // Always show vat rates with vat 0
226  $s = 2 / 7; $qty = 1; $vat = 0;
227  $tmparray = calcul_price_total(1, $qty * price2num($s, 'MU'), 0, $vat, 0, 0, 0, 'HT', 0, 0, $mysoc);
228  print '<span class="opacitymedium">'.$langs->trans("UnitPriceOfProduct").":</span> ".price2num($s, 'MU');
229  print " x ".$langs->trans("Quantity").": ".$qty;
230  print " - ".$langs->trans("VAT").": ".$vat.'%';
231  print ' &nbsp; -> &nbsp; <span class="opacitymedium">'.$langs->trans("TotalPriceAfterRounding").":</span> ".$tmparray[0].' / '.$tmparray[1].' / '.$tmparray[2]."<br>\n";
232 
233  $s = 10 / 3; $qty = 1; $vat = 0;
234  $tmparray = calcul_price_total(1, $qty * price2num($s, 'MU'), 0, $vat, 0, 0, 0, 'HT', 0, 0, $mysoc);
235  print '<span class="opacitymedium">'.$langs->trans("UnitPriceOfProduct").":</span> ".price2num($s, 'MU');
236  print " x ".$langs->trans("Quantity").": ".$qty;
237  print " - ".$langs->trans("VAT").": ".$vat.'%';
238  print ' &nbsp; -> &nbsp; <span class="opacitymedium">'.$langs->trans("TotalPriceAfterRounding").":</span> ".$tmparray[0].' / '.$tmparray[1].' / '.$tmparray[2]."<br>\n";
239 
240  $s = 10 / 3; $qty = 2; $vat = 0;
241  $tmparray = calcul_price_total(1, $qty * price2num($s, 'MU'), 0, $vat, 0, 0, 0, 'HT', 0, 0, $mysoc);
242  print '<span class="opacitymedium">'.$langs->trans("UnitPriceOfProduct").":</span> ".price2num($s, 'MU');
243  print " x ".$langs->trans("Quantity").": ".$qty;
244  print " - ".$langs->trans("VAT").": ".$vat.'%';
245  print ' &nbsp; -> &nbsp; <span class="opacitymedium">'.$langs->trans("TotalPriceAfterRounding").":</span> ".$tmparray[0].' / '.$tmparray[1].' / '.$tmparray[2]."<br>\n";
246 
247  // Add vat rates examples specific to country
248  $vat_rates = array();
249 
250  $sql = "SELECT taux as vat_rate, t.code as vat_code, t.localtax1 as localtax_rate1, t.localtax2 as localtax_rate2";
251  $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c";
252  $sql .= " WHERE t.active=1 AND t.fk_pays = c.rowid AND c.code='".$db->escape($mysoc->country_code)."' AND (t.taux <> 0 OR t.localtax1 <>0 OR t.localtax2 <>0)";
253  $sql .= " ORDER BY t.taux ASC";
254  $resql = $db->query($sql);
255  if ($resql)
256  {
257  $num = $db->num_rows($resql);
258  if ($num)
259  {
260  for ($i = 0; $i < $num; $i++)
261  {
262  $obj = $db->fetch_object($resql);
263  $vat_rates[] = array('vat_rate'=>$obj->vat_rate, 'code'=>$obj->vat_code, 'localtax_rate1'=>$obj->localtax_rate1, 'locltax_rate2'=>$obj->localtax_rate2);
264  }
265  }
266  } else dol_print_error($db);
267 
268  if (count($vat_rates))
269  {
270  foreach ($vat_rates as $vatarray)
271  {
272  $vat = $vatarray['vat_rate'];
273  for ($qty = 1; $qty <= 2; $qty++)
274  {
275  $vattxt = $vat.($vatarray['code'] ? ' ('.$vatarray['code'].')' : '');
276 
277  $localtax_array = getLocalTaxesFromRate($vattxt, 0, $mysoc, $mysoc);
278 
279  $s = 10 / 3;
280  $tmparray = calcul_price_total($qty, price2num($s, 'MU'), 0, $vat, -1, -1, 0, 'HT', 0, 0, $mysoc, $localtax_array);
281  print '<span class="opacitymedium">'.$langs->trans("UnitPriceOfProduct").":</span> ".price2num($s, 'MU');
282  print " x ".$langs->trans("Quantity").": ".$qty;
283  print " - ".$langs->trans("VAT").": ".$vat.'%';
284  print ($vatarray['code'] ? ' ('.$vatarray['code'].')' : '');
285  print ' &nbsp; -> &nbsp; <span class="opacitymedium">'.$langs->trans("TotalPriceAfterRounding").":</span> ";
286  print $tmparray[0].' / '.$tmparray[1].($tmparray[9] ? '+'.$tmparray[9] : '').($tmparray[10] ? '+'.$tmparray[10] : '').' / '.$tmparray[2];
287  print "<br>\n";
288  }
289  }
290  } else {
291  // More examples if not specific vat rate found
292  // This example must be kept for test purpose with current value because value used (2/7, 10/3, and vat 0, 10)
293  // were calculated to show all possible cases of rounding. If we change this, examples becomes useless or show the same rounding rule.
294 
295  $localtax_array = array();
296 
297  $s = 10 / 3; $qty = 1; $vat = 10;
298  $tmparray = calcul_price_total($qty, price2num($s, 'MU'), 0, $vat, -1, -1, 0, 'HT', 0, 0, $mysoc, $localtax_array);
299  print '<span class="opacitymedium">'.$langs->trans("UnitPriceOfProduct").":</span> ".price2num($s, 'MU');
300  print " x ".$langs->trans("Quantity").": ".$qty;
301  print " - ".$langs->trans("VAT").": ".$vat.'%';
302  print ' &nbsp; -> &nbsp; <span class="opacitymedium">'.$langs->trans("TotalPriceAfterRounding").":</span> ".$tmparray[0].' / '.$tmparray[1].' / '.$tmparray[2]."<br>\n";
303 
304  $s = 10 / 3; $qty = 2; $vat = 10;
305  $tmparray = calcul_price_total($qty, price2num($s, 'MU'), 0, $vat, -1, -1, 0, 'HT', 0, 0, $mysoc, $localtax_array);
306  print '<span class="opacitymedium">'.$langs->trans("UnitPriceOfProduct").":</span> ".price2num($s, 'MU');
307  print " x ".$langs->trans("Quantity").": ".$qty;
308  print " - ".$langs->trans("VAT").": ".$vat.'%';
309  print ' &nbsp; -> &nbsp; <span class="opacitymedium">'.$langs->trans("TotalPriceAfterRounding").":</span> ".$tmparray[0].' / '.$tmparray[1].' / '.$tmparray[2]."<br>\n";
310  }
311 }
312 
313 // End of page
314 llxFooter();
315 $db->close();
GETPOST($paramname, $check= 'alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dolibarr_set_const($db, $name, $value, $type= 'chaine', $visible=0, $note= '', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
Definition: admin.lib.php:575
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:86
multicurrencyLimitPrepareHead($aCurrencies)
Prepare array with list of currency tabs.
img_warning($titlealt= 'default', $moreatt= '', $morecss= 'pictowarning')
Show warning logo.
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...
llxHeader()
Empty header.
Definition: wrapper.php:45
setEventMessages($mesg, $mesgs, $style= 'mesgs', $messagekey= '')
Set event messages in dol_events session object.
Class to manage generation of HTML components Only common components must be here.
load_fiche_titre($titre, $morehtmlright= '', $picto= 'generic', $pictoisfullpath=0, $id= '', $morecssontable= '', $morehtmlcenter= '')
Load a title with picto.
price2num($amount, $rounding= '', $option=0)
Function that return a number with universal decimal format (decimal separator is &#39;...
accessforbidden($message= '', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program Calling this function terminate execution ...
print $_SERVER["PHP_SELF"]
Edit parameters.
dol_get_fiche_head($links=array(), $active= '', $title= '', $notab=0, $picto= '', $pictoisfullpath=0, $morehtmlright= '', $morecss= '', $limittoshow=0, $moretabssuffix= '')
Show tabs of a record.
print
Draft customers invoices.
Definition: index.php:89
if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) if(!empty($conf->don->enabled)&&$user->rights->don->lire) if(!empty($conf->tax->enabled)&&$user->rights->tax->charges->lire) if(!empty($conf->facture->enabled)&&!empty($conf->commande->enabled)&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1232
dol_print_error($db= '', $error= '', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_get_fiche_end($notab=0)
Return tab footer of a card.
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
llxFooter()
Empty footer.
Definition: wrapper.php:59