dolibarr  20.0.0-beta
card-rec.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2023 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
6  * Copyright (C) 2013-2023 Juanjo Menent <jmenent@2byte.es>
7  * Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
8  * Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr>
9  * Copyright (C) 2015 Alexandre Spangaro <aspangaro@open-dsi.fr>
10  * Copyright (C) 2016 Meziane Sof <virtualsof@yahoo.fr>
11  * Copyright (C) 2017-2018 Frédéric France <frederic.france@netlogic.fr>
12  * Copyright (C) 2023 Nick Fragoulis
13  * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
14  *
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 3 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program. If not, see <https://www.gnu.org/licenses/>.
27  */
28 
35 // Load Dolibarr environment
36 require '../../main.inc.php';
37 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
38 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
39 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
40 if (isModEnabled('project')) {
41  include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
42  //include_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
43 }
44 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
45 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
46 require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice.lib.php';
47 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
48 
49 // Load translation files required by the page
50 $langs->loadLangs(array('bills', 'companies', 'compta', 'admin', 'other', 'products', 'banks'));
51 
52 $action = GETPOST('action', 'alpha');
53 $massaction = GETPOST('massaction', 'alpha');
54 $show_files = GETPOSTINT('show_files');
55 $confirm = GETPOST('confirm', 'alpha');
56 $cancel = GETPOST('cancel', 'alpha');
57 $toselect = GETPOST('toselect', 'array');
58 $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'invoicetemplatelist'; // To manage different context of search
59 $backtopage = GETPOST('backtopage', 'alpha'); // if not set, a default page will be used
60 $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); // if not set, $backtopage will be used
61 
62 
63 $id = (GETPOSTINT('facid') ? GETPOSTINT('facid') : GETPOSTINT('id'));
64 $lineid = GETPOSTINT('lineid');
65 $ref = GETPOST('ref', 'alpha');
66 if ($user->socid) {
67  $socid = $user->socid;
68 }
69 $objecttype = 'facture_rec';
70 if ($action == "create" || $action == "add") {
71  $objecttype = '';
72 }
73 $projectid = GETPOSTINT('projectid');
74 
75 $year_date_when = GETPOST('year_date_when');
76 $month_date_when = GETPOST('month_date_when');
77 $selectedLines = GETPOST('toselect', 'array');
78 
79 $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
80 $sortfield = GETPOST('sortfield', 'aZ09comma');
81 $sortorder = GETPOST('sortorder', 'aZ09comma');
82 $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
83 if (empty($page) || $page == -1) {
84  $page = 0;
85 } // If $page is not defined, or '' or -1
86 $offset = $limit * $page;
87 if (!$sortorder) {
88  $sortorder = 'DESC';
89 }
90 if (!$sortfield) {
91  $sortfield = 'f.titre';
92 }
93 $pageprev = $page - 1;
94 $pagenext = $page + 1;
95 
96 $object = new FactureRec($db);
97 if (($id > 0 || $ref) && $action != 'create' && $action != 'add') {
98  $ret = $object->fetch($id, $ref);
99  if (!$ret) {
100  setEventMessages($langs->trans("ErrorRecordNotFound"), null, 'errors');
101  }
102 }
103 
104 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
105 $hookmanager->initHooks(array('invoicereccard', 'globalcard'));
106 $extrafields = new ExtraFields($db);
107 
108 // fetch optionals attributes and labels
109 $extrafields->fetch_name_optionals_label($object->table_element);
110 
111 $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
112 
113 $permissionnote = $user->hasRight('facture', 'creer'); // Used by the include of actions_setnotes.inc.php
114 $permissiondellink = $user->hasRight('facture', 'creer'); // Used by the include of actions_dellink.inc.php
115 $permissiontoedit = $user->hasRight('facture', 'creer'); // Used by the include of actions_lineupdonw.inc.php
116 
117 $usercanread = $user->hasRight('facture', 'lire');
118 $usercancreate = $user->hasRight('facture', 'creer');
119 $usercanissuepayment = $user->hasRight('facture', 'paiement');
120 $usercandelete = $user->hasRight('facture', 'supprimer');
121 $usercanvalidate = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $usercancreate) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('facture', 'invoice_advance', 'validate')));
122 $usercansend = (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->rights->facture->invoice_advance->send);
123 $usercanreopen = (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->rights->facture->invoice_advance->reopen);
124 $usercanunvalidate = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !empty($usercancreate)) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('facture', 'invoice_advance', 'unvalidate')));
125 
126 $usercanproductignorepricemin = ((getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight('produit', 'ignore_price_min_advance')) || !getDolGlobalString('MAIN_USE_ADVANCED_PERMS'));
127 $usercancreatemargin = $user->hasRight("margins", "creer");
128 $usercanreadallmargin = $user->hasRight("margins", "liretous");
129 $usercancreatewithdrarequest = $user->hasRight("prelevement", "bons", "creer");
130 
131 $now = dol_now();
132 
133 $error = 0;
134 
135 // Security check
136 $result = restrictedArea($user, 'facture', $object->id, $objecttype);
137 
138 
139 /*
140  * Actions
141  */
142 
143 if (GETPOST('cancel', 'alpha')) {
144  $action = 'list';
145  $massaction = '';
146 }
147 if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
148  $massaction = '';
149 }
150 
151 $parameters = array();
152 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
153 if ($reshook < 0) {
154  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
155 }
156 
157 if (empty($reshook)) {
158  $backurlforlist = DOL_URL_ROOT.'/compta/facture/invoicetemplate_list.php';
159 
160  if (empty($backtopage) || ($cancel && empty($id))) {
161  if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
162  if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
163  $backtopage = $backurlforlist;
164  } else {
165  $backtopage = DOL_URL_ROOT.'/compta/facture/invoicetemplate_list.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
166  }
167  }
168  }
169 
170  // include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
171  if ($cancel) {
172  /*var_dump($cancel);var_dump($backtopage);var_dump($backtopageforcancel);exit;*/
173  if (!empty($backtopageforcancel)) {
174  header("Location: ".$backtopageforcancel);
175  exit;
176  } elseif (!empty($backtopage)) {
177  header("Location: ".$backtopage);
178  exit;
179  }
180  $action = '';
181  }
182 
183  // Selection of new fields
184  include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
185 
186  // Set note
187  include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once
188 
189  include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once
190 
191  include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be include, not include_once
192 
193  // Mass actions
194  /*$objectclass='MyObject';
195  $objectlabel='MyObject';
196  $uploaddir = $conf->mymodule->dir_output;
197  include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';*/
198 
199  // Create predefined invoice
200  if ($action == 'add') {
201  if (!GETPOST('title', 'alphanohtml')) {
202  setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("Title")), null, 'errors');
203  $action = "create";
204  $error++;
205  }
206 
207  $frequency = GETPOSTINT('frequency');
208  $reyear = GETPOSTINT('reyear');
209  $remonth = GETPOSTINT('remonth');
210  $reday = GETPOSTINT('reday');
211  $rehour = GETPOSTINT('rehour');
212  $remin = GETPOSTINT('remin');
213  $nb_gen_max = GETPOSTINT('nb_gen_max');
214  //if (empty($nb_gen_max)) $nb_gen_max =0;
215 
216  if (GETPOSTINT('frequency')) {
217  if (empty($reyear) || empty($remonth) || empty($reday)) {
218  setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("Date")), null, 'errors');
219  $action = "create";
220  $error++;
221  }
222  /*if ($nb_gen_max === '') {
223  setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("MaxPeriodNumber")), null, 'errors');
224  $action = "create";
225  $error++;
226  }*/
227  }
228 
229  if (!$error) {
230  $object->subtype = GETPOSTINT('subtype');
231  $object->title = GETPOST('title', 'alphanohtml');
232  $object->note_private = GETPOST('note_private', 'restricthtml');
233  $object->note_public = GETPOST('note_public', 'restricthtml');
234  $object->model_pdf = GETPOST('modelpdf', 'alphanohtml');
235  $object->usenewprice = GETPOST('usenewprice', 'alphanohtml');
236 
237  $object->mode_reglement_id = GETPOSTINT('mode_reglement_id');
238  $object->cond_reglement_id = GETPOSTINT('cond_reglement_id');
239 
240  $object->frequency = $frequency;
241  $object->unit_frequency = GETPOST('unit_frequency', 'alpha');
242  $object->nb_gen_max = $nb_gen_max;
243  $object->auto_validate = GETPOSTINT('auto_validate');
244  $object->generate_pdf = GETPOSTINT('generate_pdf');
245  $object->fk_project = $projectid;
246 
247  $date_next_execution = dol_mktime($rehour, $remin, 0, $remonth, $reday, $reyear);
248  $object->date_when = $date_next_execution;
249 
250  $ret = $extrafields->setOptionalsFromPost(null, $object);
251  if ($ret < 0) {
252  $error++;
253  }
254 
255  // Get first contract linked to invoice used to generate template (facid is id of source invoice)
256  if (GETPOSTINT('facid') > 0) {
257  $srcObject = new Facture($db);
258  $srcObject->fetch(GETPOSTINT('facid'));
259 
260  $srcObject->fetchObjectLinked();
261 
262  if (!empty($srcObject->linkedObjectsIds['contrat'])) {
263  $contractidid = reset($srcObject->linkedObjectsIds['contrat']);
264 
265  $object->origin = 'contrat';
266  $object->origin_id = $contractidid;
267  $object->linked_objects[$object->origin] = $object->origin_id;
268  }
269  }
270 
271  $db->begin();
272 
273  $oldinvoice = new Facture($db);
274  $oldinvoice->fetch(GETPOSTINT('facid'));
275 
276  $onlylines = GETPOST('toselect', 'array');
277 
278  $result = $object->create($user, $oldinvoice->id, 0, $onlylines);
279  if ($result > 0) {
280  $result = $oldinvoice->delete($user, 1);
281  if ($result < 0) {
282  $error++;
283  setEventMessages($oldinvoice->error, $oldinvoice->errors, 'errors');
284  $action = "create";
285  }
286  } else {
287  $error++;
288  setEventMessages($object->error, $object->errors, 'errors');
289  $action = "create";
290  }
291 
292  if (!$error) {
293  $db->commit();
294 
295  header("Location: ".$_SERVER['PHP_SELF'].'?facid='.$object->id);
296  exit;
297  } else {
298  $db->rollback();
299 
300  $action = "create";
301  }
302  }
303  }
304 
305  // Delete
306  if ($action == 'confirm_delete' && $confirm == 'yes' && $user->hasRight('facture', 'supprimer')) {
307  $object->delete($user);
308 
309  header("Location: ".DOL_URL_ROOT.'/compta/facture/invoicetemplate_list.php');
310  exit;
311  }
312 
313 
314  // Update field
315  if ($action == 'setconditions' && $user->hasRight('facture', 'creer')) {
316  // Set condition
317  $object->context['actionmsg'] = $langs->trans("FieldXModified", $langs->transnoentitiesnoconv("PaymentTerm"));
318  $result = $object->setPaymentTerms(GETPOSTINT('cond_reglement_id'));
319  } elseif ($action == 'setmode' && $user->hasRight('facture', 'creer')) {
320  // Set mode
321  $object->context['actionmsg'] = $langs->trans("FieldXModified", $langs->transnoentitiesnoconv("PaymentMode"));
322  $result = $object->setPaymentMethods(GETPOSTINT('mode_reglement_id'));
323  } elseif ($action == 'classin' && $user->hasRight('facture', 'creer')) {
324  // Set project
325  $object->context['actionmsg'] = $langs->trans("FieldXModified", $langs->transnoentitiesnoconv("Project"));
326  $object->setProject(GETPOSTINT('projectid'));
327  } elseif ($action == 'setref' && $user->hasRight('facture', 'creer')) {
328  // Set bank account
329  $object->context['actionmsg'] = $langs->trans("FieldXModifiedFromYToZ", $langs->transnoentitiesnoconv("Title"), $object->title, $ref);
330  $result = $object->setValueFrom('titre', $ref, '', null, 'text', '', $user, 'BILLREC_MODIFY');
331  if ($result > 0) {
332  $object->title = $ref;
333  $object->ref = $object->title;
334  } else {
335  $error++;
336  if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
337  $langs->load("errors");
338  setEventMessages($langs->trans('ErrorRefAlreadyExists', $ref), null, 'errors');
339  } else {
340  setEventMessages($object->error, $object->errors, 'errors');
341  }
342  }
343  } elseif ($action == 'setbankaccount' && $user->hasRight('facture', 'creer')) {
344  // Set bank account
345  $object->context['actionmsg'] = $langs->trans("FieldXModified", $langs->transnoentitiesnoconv("Bank"));
346  $result = $object->setBankAccount(GETPOSTINT('fk_account'));
347  } elseif ($action == 'setfrequency' && $user->hasRight('facture', 'creer')) {
348  // Set frequency and unit frequency
349  $object->context['actionmsg'] = $langs->trans("FieldXModified", $langs->transnoentitiesnoconv("Frequency"));
350  $object->setFrequencyAndUnit(GETPOSTINT('frequency'), GETPOST('unit_frequency'));
351  } elseif ($action == 'setdate_when' && $user->hasRight('facture', 'creer')) {
352  // Set next date of execution
353  $date = dol_mktime(GETPOST('date_whenhour'), GETPOST('date_whenmin'), 0, GETPOST('date_whenmonth'), GETPOST('date_whenday'), GETPOST('date_whenyear'));
354  if (!empty($date)) {
355  $object->setNextDate($date);
356  }
357  } elseif ($action == 'setnb_gen_max' && $user->hasRight('facture', 'creer')) {
358  // Set max period
359  $object->setMaxPeriod(GETPOSTINT('nb_gen_max'));
360  } elseif ($action == 'setauto_validate' && $user->hasRight('facture', 'creer')) {
361  // Set auto validate
362  $object->setAutoValidate(GETPOSTINT('auto_validate'));
363  } elseif ($action == 'setgenerate_pdf' && $user->hasRight('facture', 'creer')) {
364  // Set generate pdf
365  $object->setGeneratepdf(GETPOSTINT('generate_pdf'));
366  } elseif ($action == 'setmodelpdf' && $user->hasRight('facture', 'creer')) {
367  // Set model pdf
368  $object->setModelpdf(GETPOST('modelpdf', 'alpha'));
369  } elseif ($action == 'disable' && $user->hasRight('facture', 'creer')) {
370  // Set status disabled
371  $db->begin();
372 
373  $object->context['actionmsg'] = $langs->trans("RecordDisabled");
374 
375  $res = $object->setValueFrom('suspended', 1, '', null, 'text', '', $user, 'BILLREC_MODIFY');
376  if ($res <= 0) {
377  $error++;
378  }
379 
380  if (!$error) {
381  $db->commit();
382  } else {
383  $db->rollback();
384  setEventMessages($object->error, $object->errors, 'errors');
385  }
386  } elseif ($action == 'enable' && $user->hasRight('facture', 'creer')) {
387  // Set status enabled
388  $db->begin();
389 
390  $object->context['actionmsg'] = $langs->trans("RecordEnabled");
391 
392  $res = $object->setValueFrom('suspended', 0, '', null, 'text', '', $user, 'BILLREC_MODIFY');
393  if ($res <= 0) {
394  $error++;
395  }
396 
397  if (!$error) {
398  $db->commit();
399  } else {
400  $db->rollback();
401  setEventMessages($object->error, $object->errors, 'errors');
402  }
403  } elseif ($action == 'setmulticurrencycode' && $usercancreate) {
404  // Multicurrency Code
405  $result = $object->setMulticurrencyCode(GETPOST('multicurrency_code', 'alpha'));
406  } elseif ($action == 'setmulticurrencyrate' && $usercancreate) {
407  // Multicurrency rate
408  $result = $object->setMulticurrencyRate(price2num(GETPOST('multicurrency_tx')), GETPOSTINT('calculation_mode'));
409  }
410 
411  // Delete line
412  if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->hasRight('facture', 'creer')) {
413  $object->fetch($id);
414  $object->fetch_thirdparty();
415 
416  $db->begin();
417 
418  $line = new FactureLigneRec($db);
419 
420  // For triggers
421  $line->id = $lineid;
422 
423  if ($line->delete($user) > 0) {
424  $result = $object->update_price(1);
425 
426  if ($result > 0) {
427  $db->commit();
428  $object->fetch($object->id); // Reload lines
429  } else {
430  $db->rollback();
431  setEventMessages($db->lasterror(), null, 'errors');
432  }
433  } else {
434  $db->rollback();
435  setEventMessages($line->error, $line->errors, 'errors');
436  }
437  } elseif ($action == 'update_extras') {
438  $object->oldcopy = dol_clone($object, 2);
439 
440  // Fill array 'array_options' with data from update form
441  $ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'restricthtml'));
442  if ($ret < 0) {
443  $error++;
444  }
445 
446  if (!$error) {
447  $result = $object->insertExtraFields('BILLREC_MODIFY');
448  if ($result < 0) {
449  setEventMessages($object->error, $object->errors, 'errors');
450  $error++;
451  }
452  }
453  }
454 
455  // Add a new line
456  if ($action == 'addline' && $user->hasRight('facture', 'creer')) {
457  $langs->load('errors');
458  $error = 0;
459 
460  // Set if we used free entry or predefined product
461  $predef = '';
462  $product_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : '');
463  $price_ht = price2num(GETPOST('price_ht'), 'MU', 2);
464  $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2);
465  $prod_entry_mode = GETPOST('prod_entry_mode', 'alpha');
466  if ($prod_entry_mode == 'free') {
467  $idprod = 0;
468  } else {
469  $idprod = GETPOSTINT('idprod');
470 
471  if (getDolGlobalString('MAIN_DISABLE_FREE_LINES') && $idprod <= 0) {
472  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductOrService")), null, 'errors');
473  $error++;
474  }
475  }
476 
477  $tva_tx = (GETPOST('tva_tx', 'alpha') ? GETPOST('tva_tx', 'alpha') : 0);
478 
479  $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS', 2);
480  $remise_percent = price2num(GETPOST('remise_percent'.$predef), '', 2);
481  if (empty($remise_percent)) {
482  $remise_percent = 0;
483  }
484 
485  // Extrafields
486  $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
487  $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
488  // Unset extrafield
489  if (is_array($extralabelsline)) {
490  // Get extra fields
491  foreach ($extralabelsline as $key => $value) {
492  unset($_POST["options_".$key.$predef]);
493  }
494  }
495 
496  if ((empty($idprod) || $idprod < 0) && ($price_ht < 0) && ($qty < 0)) {
497  setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), null, 'errors');
498  $error++;
499  }
500  if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && GETPOST('type') < 0) {
501  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors');
502  $error++;
503  }
504  if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && (!($price_ht >= 0) || $price_ht == '')) { // Unit price can be 0 but not ''
505  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors');
506  $error++;
507  }
508  if ($qty == '') {
509  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
510  $error++;
511  }
512  if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && empty($product_desc)) {
513  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors');
514  $error++;
515  }
516  if ($qty < 0) {
517  $langs->load("errors");
518  setEventMessages($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), null, 'errors');
519  $error++;
520  }
521 
522  if (!$error && ($qty >= 0) && (!empty($product_desc) || (!empty($idprod) && $idprod > 0))) {
523  $ret = $object->fetch($id);
524  if ($ret < 0) {
525  dol_print_error($db, $object->error);
526  exit();
527  }
528  $ret = $object->fetch_thirdparty();
529 
530  // Clean parameters
531  $date_start = dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start'.$predef.'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year'));
532  $date_end = dol_mktime(GETPOST('date_end'.$predef.'hour'), GETPOST('date_end'.$predef.'min'), GETPOST('date_end'.$predef.'sec'), GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year'));
533  $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT');
534  $tva_npr = "";
535 
536  // Define special_code for special lines
537  $special_code = 0;
538  // if (!GETPOST('qty')) $special_code=3; // Options should not exists on invoices
539 
540  // Ecrase $pu par celui du produit
541  // Ecrase $desc par celui du produit
542  // Ecrase $base_price_type par celui du produit
543  // Replaces $fk_unit with the product's
544  if (!empty($idprod) && $idprod > 0) {
545  $prod = new Product($db);
546  $prod->fetch($idprod);
547 
548  $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : '');
549 
550  // Update if prices fields are defined
551  //$tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id);
552  //$tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id);
553  //if (empty($tva_tx)) {
554  // $tva_npr = 0;
555  //}
556 
557  // Search the correct price into loaded array product_price_by_qty using id of array retrieved into POST['pqp'].
558  $pqp = (GETPOSTINT('pbq') ? GETPOSTINT('pbq') : 0);
559 
560  $datapriceofproduct = $prod->getSellPrice($mysoc, $object->thirdparty, $pqp);
561 
562  $pu_ht = $datapriceofproduct['pu_ht'];
563  $pu_ttc = $datapriceofproduct['pu_ttc'];
564  $price_min = $datapriceofproduct['price_min'];
565  $price_base_type = empty($datapriceofproduct['price_base_type']) ? 'HT' : $datapriceofproduct['price_base_type'];
566  //$tva_tx = $datapriceofproduct['tva_tx'];
567  //$tva_npr = $datapriceofproduct['tva_npr'];
568 
569  $tmpvat = (float) price2num(preg_replace('/\s*\‍(.*\‍)/', '', $tva_tx));
570  $tmpprodvat = price2num(preg_replace('/\s*\‍(.*\‍)/', '', (string) $prod->tva_tx));
571 
572  // if price ht was forced (ie: from gui when calculated by margin rate and cost price). TODO Why this ?
573  if (!empty($price_ht)) {
574  $pu_ht = price2num($price_ht, 'MU');
575  $pu_ttc = price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU');
576  } elseif ($tmpvat != $tmpprodvat) {
577  // On reevalue prix selon taux tva car taux tva transaction peut etre different
578  // de ceux du produit par default (par example si pays different entre vendeur et acheteur).
579  if ($price_base_type != 'HT') {
580  $pu_ht = price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU');
581  } else {
582  $pu_ttc = price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU');
583  }
584  }
585 
586  $desc = '';
587 
588  // Define output language
589  if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
590  $outputlangs = $langs;
591  $newlang = '';
592  if (empty($newlang) && GETPOST('lang_id', 'aZ09')) {
593  $newlang = GETPOST('lang_id', 'aZ09');
594  }
595  if (empty($newlang)) {
596  $newlang = $object->thirdparty->default_lang;
597  }
598  if (!empty($newlang)) {
599  $outputlangs = new Translate("", $conf);
600  $outputlangs->setDefaultLang($newlang);
601  }
602 
603  $desc = (!empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description;
604  } else {
605  $desc = $prod->description;
606  }
607 
608  $desc = dol_concatdesc($desc, $product_desc);
609 
610  // Add custom code and origin country into description
611  if (!getDolGlobalString('MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE') && (!empty($prod->customcode) || !empty($prod->country_code))) {
612  $tmptxt = '(';
613  // Define output language
614  if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
615  $outputlangs = $langs;
616  $newlang = '';
617  if (empty($newlang) && GETPOST('lang_id', 'alpha')) {
618  $newlang = GETPOST('lang_id', 'alpha');
619  }
620  if (empty($newlang)) {
621  $newlang = $object->thirdparty->default_lang;
622  }
623  if (!empty($newlang)) {
624  $outputlangs = new Translate("", $conf);
625  $outputlangs->setDefaultLang($newlang);
626  $outputlangs->load('products');
627  }
628  if (!empty($prod->customcode)) {
629  $tmptxt .= $outputlangs->transnoentitiesnoconv("CustomCode").': '.$prod->customcode;
630  }
631  if (!empty($prod->customcode) && !empty($prod->country_code)) {
632  $tmptxt .= ' - ';
633  }
634  if (!empty($prod->country_code)) {
635  $tmptxt .= $outputlangs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code, 0, $db, $outputlangs, 0);
636  }
637  } else {
638  if (!empty($prod->customcode)) {
639  $tmptxt .= $langs->transnoentitiesnoconv("CustomCode").': '.$prod->customcode;
640  }
641  if (!empty($prod->customcode) && !empty($prod->country_code)) {
642  $tmptxt .= ' - ';
643  }
644  if (!empty($prod->country_code)) {
645  $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code, 0, $db, $langs, 0);
646  }
647  }
648  $tmptxt .= ')';
649  $desc = dol_concatdesc($desc, $tmptxt);
650  }
651 
652  $type = $prod->type;
653  $fk_unit = $prod->fk_unit;
654  } else {
655  $pu_ht = price2num($price_ht, 'MU');
656  $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
657  $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
658  $tva_tx = str_replace('*', '', $tva_tx);
659  if (empty($tva_tx)) {
660  $tva_npr = 0;
661  }
662  $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
663  $desc = $product_desc;
664  $type = GETPOST('type');
665  $fk_unit = GETPOST('units', 'alpha');
666  }
667 
668  $date_start_fill = GETPOSTINT('date_start_fill');
669  $date_end_fill = GETPOSTINT('date_end_fill');
670 
671  // Margin
672  $fournprice = price2num(GETPOST('fournprice'.$predef) ? GETPOST('fournprice'.$predef) : '');
673  $buyingprice = price2num(GETPOST('buying_price'.$predef) != '' ? GETPOST('buying_price'.$predef) : ''); // If buying_price is '0', we must keep this value
674 
675  // Local Taxes
676  $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty, $mysoc, $tva_npr);
677  $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty, $mysoc, $tva_npr);
678 
679  $info_bits = 0;
680  if ($tva_npr) {
681  $info_bits |= 0x01;
682  }
683 
684  if ($usercanproductignorepricemin && (!empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min)))) {
685  $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency));
686  setEventMessages($mesg, null, 'errors');
687  } else {
688  // Insert line
689  $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $info_bits, '', $pu_ttc, $type, -1, $special_code, $label, $fk_unit, 0, $date_start_fill, $date_end_fill, $fournprice, $buyingprice);
690 
691  if ($result > 0) {
692  // Define output language and generate document
693  /*if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
694  {
695  // Define output language
696  $outputlangs = $langs;
697  $newlang = '';
698  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
699  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) $newlang = $object->thirdparty->default_lang;
700  if (!empty($newlang)) {
701  $outputlangs = new Translate("", $conf);
702  $outputlangs->setDefaultLang($newlang);
703  }
704  $model=$object->model_pdf;
705  $ret = $object->fetch($id); // Reload to get new records
706 
707  $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
708  if ($result < 0) setEventMessages($object->error, $object->errors, 'errors');
709  }*/
710  $object->fetch($object->id); // Reload lines
711 
712  unset($_POST['prod_entry_mode']);
713 
714  unset($_POST['qty']);
715  unset($_POST['type']);
716  unset($_POST['remise_percent']);
717  unset($_POST['price_ht']);
718  unset($_POST['multicurrency_price_ht']);
719  unset($_POST['price_ttc']);
720  unset($_POST['tva_tx']);
721  unset($_POST['product_ref']);
722  unset($_POST['product_label']);
723  unset($_POST['product_desc']);
724  unset($_POST['fournprice']);
725  unset($_POST['buying_price']);
726  unset($_POST['np_marginRate']);
727  unset($_POST['np_markRate']);
728  unset($_POST['dp_desc']);
729  unset($_POST['idprod']);
730  unset($_POST['units']);
731 
732  unset($_POST['date_starthour']);
733  unset($_POST['date_startmin']);
734  unset($_POST['date_startsec']);
735  unset($_POST['date_startday']);
736  unset($_POST['date_startmonth']);
737  unset($_POST['date_startyear']);
738  unset($_POST['date_endhour']);
739  unset($_POST['date_endmin']);
740  unset($_POST['date_endsec']);
741  unset($_POST['date_endday']);
742  unset($_POST['date_endmonth']);
743  unset($_POST['date_endyear']);
744 
745  unset($_POST['date_start_fill']);
746  unset($_POST['date_end_fill']);
747 
748  unset($_POST['situations']);
749  unset($_POST['progress']);
750  } else {
751  setEventMessages($object->error, $object->errors, 'errors');
752  }
753 
754  $action = '';
755  }
756  }
757  } elseif ($action == 'updateline' && $usercancreate && !GETPOST('cancel', 'alpha')) {
758  if (!$object->fetch($id) > 0) {
759  dol_print_error($db);
760  }
761  $object->fetch_thirdparty();
762 
763  // Clean parameters
764  $date_start = '';
765  $date_end = '';
766  //$date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear'));
767  //$date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear'));
768  $description = dol_htmlcleanlastbr(GETPOST('product_desc', 'restricthtml') ? GETPOST('product_desc', 'restricthtml') : GETPOST('desc', 'restricthtml'));
769  $pu_ht = price2num(GETPOST('price_ht'), '', 2);
770  $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
771  $qty = GETPOST('qty');
772  $pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), '', 2);
773 
774  // Define info_bits
775  $info_bits = 0;
776  if (preg_match('/\*/', $vat_rate)) {
777  $info_bits |= 0x01;
778  }
779 
780  // Define vat_rate
781  $vat_rate = str_replace('*', '', $vat_rate);
782  $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty);
783  $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty);
784 
785  // Add buying price
786  $fournprice = price2num(GETPOST('fournprice') ? GETPOST('fournprice') : '');
787  $buyingprice = price2num(GETPOST('buying_price') != '' ? GETPOST('buying_price') : ''); // If buying_price is '0', we must keep this value
788 
789  // Extrafields
790  $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
791  $array_options = $extrafields->getOptionalsFromPost($object->table_element_line);
792 
793  $objectline = new FactureLigneRec($db);
794  if ($objectline->fetch(GETPOSTINT('lineid'))) {
795  $objectline->array_options = $array_options;
796  $result = $objectline->insertExtraFields();
797  if ($result < 0) {
798  setEventMessages($langs->trans('Error').$result, null, 'errors');
799  }
800  }
801 
802  $position = ($objectline->rang >= 0 ? $objectline->rang : 0);
803 
804  // Unset extrafield
805  if (is_array($extralabelsline)) {
806  // Get extra fields
807  foreach ($extralabelsline as $key => $value) {
808  unset($_POST["options_".$key]);
809  }
810  }
811 
812  // Define special_code for special lines
813  $special_code = GETPOSTINT('special_code');
814  if ($special_code == 3) {
815  $special_code = 0; // Options should not exists on invoices
816  }
817 
818  /*$line = new FactureLigne($db);
819  $line->fetch(GETPOST('lineid', 'int'));
820  $percent = $line->get_prev_progress($object->id);
821 
822  if (GETPOST('progress') < $percent)
823  {
824  $mesg = '<div class="warning">' . $langs->trans("CantBeLessThanMinPercent") . '</div>';
825  setEventMessages($mesg, null, 'warnings');
826  $error++;
827  $result = -1;
828  }*/
829 
830  $remise_percent = price2num(GETPOST('remise_percent'), '', 2);
831  if (empty($remise_percent)) {
832  $remise_percent = 0;
833  }
834 
835  // Check minimum price
836  $productid = GETPOSTINT('productid');
837  if (!empty($productid)) {
838  $product = new Product($db);
839  $product->fetch($productid);
840 
841  $type = $product->type;
842 
843  $price_min = $product->price_min;
844  if (getDolGlobalString('PRODUIT_MULTIPRICES') && !empty($object->thirdparty->price_level)) {
845  $price_min = $product->multiprices_min[$object->thirdparty->price_level];
846  }
847 
848  $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
849 
850  $typeinvoice = Facture::TYPE_STANDARD;
851 
852  // Check price is not lower than minimum (check is done only for standard or replacement invoices)
853  if (((getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight('produit', 'ignore_price_min_advance')) || !getDolGlobalString('MAIN_USE_ADVANCED_PERMS')) && (($typeinvoice == Facture::TYPE_STANDARD || $typeinvoice == Facture::TYPE_REPLACEMENT) && $price_min && ((float) price2num($pu_ht) * (1 - (float) $remise_percent / 100) < (float) price2num($price_min)))) {
854  setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), null, 'errors');
855  $error++;
856  }
857  } else {
858  $type = GETPOSTINT('type');
859  $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
860 
861  // Check parameters
862  if (GETPOSTINT('type') < 0) {
863  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
864  $error++;
865  }
866  }
867  if ($qty < 0) {
868  $langs->load("errors");
869  setEventMessages($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), null, 'errors');
870  $error++;
871  }
872 
873  $date_start_fill = GETPOSTINT('date_start_fill');
874  $date_end_fill = GETPOSTINT('date_end_fill');
875 
876  // Update line
877  if (!$error) {
878  $result = $object->updateline(
879  GETPOSTINT('lineid'),
880  $description,
881  $pu_ht,
882  $qty,
883  $vat_rate,
884  $localtax1_rate,
885  $localtax1_rate,
886  GETPOSTINT('productid'),
887  $remise_percent,
888  'HT',
889  $info_bits,
890  0,
891  0,
892  $type,
893  $position,
894  $special_code,
895  $label,
896  GETPOST('units'),
897  $pu_ht_devise,
898  0,
899  $date_start_fill,
900  $date_end_fill,
901  $fournprice,
902  $buyingprice
903  );
904 
905  if ($result >= 0) {
906  /*if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
907  // Define output language
908  $outputlangs = $langs;
909  $newlang = '';
910  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id','aZ09'))
911  $newlang = GETPOST('lang_id','aZ09');
912  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang))
913  $newlang = $object->thirdparty->default_lang;
914  if (!empty($newlang)) {
915  $outputlangs = new Translate("", $conf);
916  $outputlangs->setDefaultLang($newlang);
917  }
918 
919  $ret = $object->fetch($id); // Reload to get new records
920  $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
921  }*/
922 
923  $object->fetch($object->id); // Reload lines
924 
925  unset($_POST['qty']);
926  unset($_POST['type']);
927  unset($_POST['productid']);
928  unset($_POST['remise_percent']);
929  unset($_POST['price_ht']);
930  unset($_POST['multicurrency_price_ht']);
931  unset($_POST['price_ttc']);
932  unset($_POST['tva_tx']);
933  unset($_POST['product_ref']);
934  unset($_POST['product_label']);
935  unset($_POST['product_desc']);
936  unset($_POST['fournprice']);
937  unset($_POST['buying_price']);
938  unset($_POST['np_marginRate']);
939  unset($_POST['np_markRate']);
940 
941  unset($_POST['dp_desc']);
942  unset($_POST['idprod']);
943  unset($_POST['units']);
944 
945  unset($_POST['date_starthour']);
946  unset($_POST['date_startmin']);
947  unset($_POST['date_startsec']);
948  unset($_POST['date_startday']);
949  unset($_POST['date_startmonth']);
950  unset($_POST['date_startyear']);
951  unset($_POST['date_endhour']);
952  unset($_POST['date_endmin']);
953  unset($_POST['date_endsec']);
954  unset($_POST['date_endday']);
955  unset($_POST['date_endmonth']);
956  unset($_POST['date_endyear']);
957 
958  unset($_POST['situations']);
959  unset($_POST['progress']);
960  } else {
961  setEventMessages($object->error, $object->errors, 'errors');
962  }
963  }
964  }
965 }
966 
967 
968 /*
969  * View
970  */
971 
972 $title = $object->ref." - ".$langs->trans('Card');
973 $help_url = '';
974 
975 llxHeader('', $title, $help_url);
976 
977 $form = new Form($db);
978 $formother = new FormOther($db);
979 if (isModEnabled('project')) {
980  $formproject = new FormProjets($db);
981 }
982 $companystatic = new Societe($db);
983 $invoicerectmp = new FactureRec($db);
984 
985 $now = dol_now();
986 $nowlasthour = dol_get_last_hour($now);
987 
988 
989 /*
990  * Create mode
991  */
992 if ($action == 'create') {
993  print load_fiche_titre($langs->trans("CreateRepeatableInvoice"), '', 'bill');
994 
995  $object = new Facture($db); // Source invoice
996  $product_static = new Product($db);
997 
998  if ($object->fetch($id, $ref) > 0) {
999  $result = $object->getLinesArray();
1000 
1001  print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
1002  print '<input type="hidden" name="token" value="'.newToken().'">';
1003  print '<input type="hidden" name="action" value="add">';
1004  print '<input type="hidden" name="facid" value="'.$object->id.'">';
1005 
1006  print dol_get_fiche_head(null, '', '', 0);
1007 
1008  $rowspan = 4;
1009  if (isModEnabled('project')) {
1010  $rowspan++;
1011  }
1012  if ($object->fk_account > 0) {
1013  $rowspan++;
1014  }
1015 
1016  print '<table class="border centpercent">';
1017 
1018  $object->fetch_thirdparty();
1019 
1020  // Title
1021  print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Title").'</td><td>';
1022  print '<input class="flat quatrevingtpercent" type="text" name="title" value="'.dol_escape_htmltag(GETPOST("title", 'alphanohtml')).'" autofocus>';
1023  print '</td></tr>';
1024 
1025  // Third party
1026  print '<tr><td class="titlefieldcreate">'.$langs->trans("Customer").'</td><td>'.$object->thirdparty->getNomUrl(1, 'customer').'</td>';
1027  print '</tr>';
1028 
1029  // Invoice subtype
1030  if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED')) {
1031  print "<tr><td>".$langs->trans("InvoiceSubtype")."</td><td>";
1032  print $form->getSelectInvoiceSubtype(GETPOSTISSET('subtype') ? GETPOST('subtype') : $object->subtype, 'subtype', 0, 0, '');
1033  print "</td></tr>";
1034  }
1035 
1036  $note_public = GETPOSTISSET('note_public') ? GETPOST('note_public', 'restricthtml') : $object->note_public;
1037  $note_private = GETPOSTISSET('note_private') ? GETPOST('note_private', 'restricthtml') : $object->note_private;
1038 
1039  // Help of substitution key
1040  $substitutionarray = getCommonSubstitutionArray($langs, 2, null, $object);
1041 
1042  $substitutionarray['__INVOICE_PREVIOUS_MONTH__'] = $langs->trans("PreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($object->date, -1, 'm'), '%m').')';
1043  $substitutionarray['__INVOICE_MONTH__'] = $langs->trans("MonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($object->date, '%m').')';
1044  $substitutionarray['__INVOICE_NEXT_MONTH__'] = $langs->trans("NextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($object->date, 1, 'm'), '%m').')';
1045  $substitutionarray['__INVOICE_PREVIOUS_MONTH_TEXT__'] = $langs->trans("TextPreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($object->date, -1, 'm'), '%B').')';
1046  $substitutionarray['__INVOICE_MONTH_TEXT__'] = $langs->trans("TextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($object->date, '%B').')';
1047  $substitutionarray['__INVOICE_NEXT_MONTH_TEXT__'] = $langs->trans("TextNextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($object->date, 1, 'm'), '%B').')';
1048  $substitutionarray['__INVOICE_PREVIOUS_YEAR__'] = $langs->trans("PreviousYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($object->date, -1, 'y'), '%Y').')';
1049  $substitutionarray['__INVOICE_YEAR__'] = $langs->trans("YearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($object->date, '%Y').')';
1050  $substitutionarray['__INVOICE_NEXT_YEAR__'] = $langs->trans("NextYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($object->date, 1, 'y'), '%Y').')';
1051  // Only on template invoices
1052  $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_BEFORE_GEN__'] = $langs->trans("DateNextInvoiceBeforeGen").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($object->date, 1, 'm'), 'dayhour').')';
1053  $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_AFTER_GEN__'] = $langs->trans("DateNextInvoiceAfterGen").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($object->date, 2, 'm'), 'dayhour').')';
1054  $substitutionarray['__INVOICE_COUNTER_CURRENT__'] = $langs->trans("Count");
1055  $substitutionarray['__INVOICE_COUNTER_MAX__'] = $langs->trans("MaxPeriodNumber");
1056 
1057  $htmltext = '<i>'.$langs->trans("FollowingConstantsWillBeSubstituted").':<br>';
1058  foreach ($substitutionarray as $key => $val) {
1059  $htmltext .= $key.' = '.$langs->trans($val).'<br>';
1060  }
1061  $htmltext .= '</i>';
1062 
1063  // Author
1064  print "<tr><td>".$langs->trans("Author")."</td><td>".$user->getFullName($langs)."</td></tr>";
1065 
1066  // Payment term
1067  print "<tr><td>".$langs->trans("PaymentConditions")."</td><td>";
1068  print $form->getSelectConditionsPaiements(GETPOSTISSET('cond_reglement_id') ? GETPOSTINT('cond_reglement_id') : $object->cond_reglement_id, 'cond_reglement_id', -1, 0, 0, '');
1069  //$form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'cond_reglement_id');
1070  print "</td></tr>";
1071 
1072  // Payment mode
1073  print "<tr><td>".$langs->trans("PaymentMode")."</td><td>";
1074  print img_picto('', 'payment', 'class="pictofixedwidth"');
1075  print $form->select_types_paiements(GETPOSTISSET('mode_reglement_id') ? GETPOSTINT('mode_reglement_id') : $object->mode_reglement_id, 'mode_reglement_id', '', 0, 1, 0, 0, 1, '', 1);
1076  //$form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->mode_reglement_id, 'mode_reglement_id', '', 1);
1077  print "</td></tr>";
1078 
1079  // Bank account
1080  if ($object->fk_account > 0) {
1081  print "<tr><td>".$langs->trans('BankAccount')."</td><td>";
1082  $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none');
1083  print "</td></tr>";
1084  }
1085 
1086  //extrafields
1087  $draft = new Facture($db);
1088  $draft->fetch(GETPOSTINT('facid'));
1089 
1090  $extralabels = new ExtraFields($db);
1091  $extralabels = $extrafields->fetch_name_optionals_label($draft->table_element);
1092  if ($draft->fetch_optionals() > 0) {
1093  $object->array_options = array_merge($object->array_options, $draft->array_options);
1094  }
1095 
1096  print $object->showOptionals($extrafields, 'create', $parameters);
1097 
1098  // Project
1099  if (isModEnabled('project') && is_object($object->thirdparty) && $object->thirdparty->id > 0) {
1100  $projectid = GETPOST('projectid') ? GETPOST('projectid') : $object->fk_project;
1101  $langs->load('projects');
1102  print '<tr><td>'.$langs->trans('Project').'</td><td>';
1103  print img_picto('', 'project', 'class="pictofixedwidth"');
1104  $numprojet = $formproject->select_projects($object->thirdparty->id, $projectid, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, '');
1105  print ' &nbsp; <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.$object->thirdparty->id.'&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create&socid='.$object->thirdparty->id.(!empty($id) ? '&id='.$id : '')).'">'.img_object($langs->trans("AddProject"), 'add').'</a>';
1106  print '</td></tr>';
1107  }
1108 
1109  // Model pdf
1110  print "<tr><td>".$langs->trans('Model')."</td><td>";
1111  include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
1112  $list = ModelePDFFactures::liste_modeles($db);
1113  print img_picto('', 'generic', 'class="pictofixedwidth"');
1114  // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
1115  print $form->selectarray('modelpdf', $list, $conf->global->FACTURE_ADDON_PDF);
1116  print "</td></tr>";
1117 
1118  // Public note
1119  print '<tr>';
1120  print '<td class="tdtop">';
1121  print $form->textwithpicto($langs->trans('NotePublic'), $htmltext, 1, 'help', '', 0, 2, 'notepublic');
1122  print '</td>';
1123  print '<td>';
1124  $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%');
1125  print $doleditor->Create(1);
1126 
1127  // Private note
1128  if (empty($user->socid)) {
1129  print '<tr>';
1130  print '<td class="tdtop">';
1131  print $form->textwithpicto($langs->trans('NotePrivate'), $htmltext, 1, 'help', '', 0, 2, 'noteprivate');
1132  print '</td>';
1133  print '<td>';
1134  $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%');
1135  print $doleditor->Create(1);
1136  // print '<textarea name="note_private" wrap="soft" cols="70" rows="'.ROWS_3.'">'.$note_private.'.</textarea>
1137  print '</td></tr>';
1138  }
1139 
1140  print "</table>";
1141 
1142  print dol_get_fiche_end();
1143 
1144  // Autogeneration
1145  $title = $langs->trans("Recurrence");
1146  print load_fiche_titre(img_picto('', 'recurring', 'class="pictofixedwidth"').$title, '', '');
1147 
1148  print '<span class="opacitymedium">'.$langs->trans("ToCreateARecurringInvoiceGeneAuto", $langs->transnoentitiesnoconv('Module2300Name')).'</span><br><br>';
1149 
1150  print dol_get_fiche_head(null, '', '', 0);
1151 
1152  print '<table class="border centpercent">';
1153 
1154  // Frequency + unit
1155  print '<tr><td class="titlefieldcreate">'.$form->textwithpicto($langs->trans("Frequency"), $langs->transnoentitiesnoconv('toolTipFrequency'))."</td><td>";
1156  print '<input type="text" class="width50" name="frequency" value="'.GETPOST('frequency', 'int').'">&nbsp;';
1157  print $form->selectarray('unit_frequency', array('d' => $langs->trans('Day'), 'm' => $langs->trans('Month'), 'y' => $langs->trans('Year')), (GETPOST('unit_frequency') ? GETPOST('unit_frequency') : 'm'));
1158  print "</td></tr>";
1159 
1160  // Date next run
1161  print "<tr><td>".$langs->trans('NextDateToExecution')."</td><td>";
1162  $date_next_execution = isset($date_next_execution) ? $date_next_execution : (GETPOSTINT('remonth') ? dol_mktime(12, 0, 0, GETPOSTINT('remonth'), GETPOSTINT('reday'), GETPOSTINT('reyear')) : -1);
1163  print $form->selectDate($date_next_execution, '', 1, 1, 0, "add", 1, 1);
1164  print "</td></tr>";
1165 
1166  // Number max of generation
1167  print "<tr><td>".$langs->trans("MaxPeriodNumber")."</td><td>";
1168  print '<input type="text" class="width50" name="nb_gen_max" value="'.GETPOSTINT('nb_gen_max').'">';
1169  print "</td></tr>";
1170 
1171  // Auto validate the invoice
1172  print "<tr><td>".$langs->trans("StatusOfAutoGeneratedInvoices")."</td><td>";
1173  $select = array('0' => $langs->trans('BillStatusDraft'), '1' => $langs->trans('BillStatusValidated'));
1174  print $form->selectarray('auto_validate', $select, GETPOSTINT('auto_validate'));
1175  print "</td></tr>";
1176 
1177  // Auto generate document
1178  if (getDolGlobalString('INVOICE_REC_CAN_DISABLE_DOCUMENT_FILE_GENERATION')) {
1179  print "<tr><td>".$langs->trans("StatusOfGeneratedDocuments")."</td><td>";
1180  $select = array('0' => $langs->trans('DoNotGenerateDoc'), '1' => $langs->trans('AutoGenerateDoc'));
1181  print $form->selectarray('generate_pdf', $select, GETPOSTINT('generate_pdf'));
1182  print "</td></tr>";
1183  } else {
1184  print '<input type="hidden" name="generate_pdf" value="1">';
1185  }
1186 
1187  print "</table>";
1188 
1189  print dol_get_fiche_end();
1190 
1191 
1192  $title = $langs->trans("ProductsAndServices");
1193  if (!isModEnabled('service')) {
1194  $title = $langs->trans("Products");
1195  } elseif (!isModEnabled('product')) {
1196  $title = $langs->trans("Services");
1197  }
1198 
1199  print load_fiche_titre($title, '', '');
1200 
1201  /*
1202  * Invoice lines
1203  */
1204  print '<div class="div-table-responsive-no-min">';
1205  print '<table id="tablelines" class="noborder noshadow centpercent">';
1206 
1207  // Show object lines
1208  if (!empty($object->lines)) {
1209  $object->printOriginLinesList('', $selectedLines);
1210  }
1211 
1212  print "</table>\n";
1213  print '<div>';
1214 
1215  print '</td></tr>';
1216 
1217  $flag_price_may_change = getDolGlobalString('INVOICE_REC_PRICE_MAY_CHANGE');
1218  if (!empty($flag_price_may_change)) {
1219  print '<tr><td colspan="3" class="left">';
1220  print '<select name="usenewprice" class="flat">';
1221  print '<option value="0">'.$langs->trans("AlwaysUseFixedPrice").'</option>';
1222  print '<option value="1" disabled>'.$langs->trans("AlwaysUseNewPrice").'</option>';
1223  print '</select>';
1224  print '</td></tr>';
1225  }
1226  print "</table>\n";
1227 
1228  print $form->buttonsSaveCancel("Create");
1229 
1230  print "</form>\n";
1231  } else {
1232  dol_print_error(null, "Error, no invoice ".$object->id);
1233  }
1234 } else {
1235  /*
1236  * View mode
1237  */
1238  if ($object->id > 0) {
1239  $object->fetch_thirdparty();
1240 
1241  $formconfirm = '';
1242  // Confirmation of deletion of product line
1243  if ($action == 'ask_deleteline') {
1244  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1);
1245  }
1246  // Confirm delete of repeatable invoice
1247  if ($action == 'delete') {
1248  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteRepeatableInvoice'), $langs->trans('ConfirmDeleteRepeatableInvoice'), 'confirm_delete', '', 'no', 1);
1249  }
1250 
1251  // Call Hook formConfirm
1252  $parameters = array('formConfirm' => $formconfirm);
1253  $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1254  if (empty($reshook)) {
1255  $formconfirm .= $hookmanager->resPrint;
1256  } elseif ($reshook > 0) {
1257  $formconfirm = $hookmanager->resPrint;
1258  }
1259 
1260  print $formconfirm;
1261 
1262  $author = new User($db);
1263  $author->fetch($object->user_author);
1264 
1266 
1267  print dol_get_fiche_head($head, 'card', $langs->trans("RepeatableInvoice"), -1, 'bill'); // Add a div
1268 
1269  // Recurring invoice content
1270 
1271  $linkback = '<a href="'.DOL_URL_ROOT.'/compta/facture/invoicetemplate_list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
1272 
1273  $morehtmlref = '';
1274  if ($action != 'editref') {
1275  $morehtmlref .= $form->editfieldkey($object->ref, 'ref', $object->ref, $object, $user->hasRight('facture', 'creer'), '', '', 0, 2);
1276  } else {
1277  $morehtmlref .= $form->editfieldval('', 'ref', $object->ref, $object, $user->hasRight('facture', 'creer'), 'string');
1278  }
1279 
1280  $morehtmlref .= '<div class="refidno">';
1281  // Ref customer
1282  //$morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_customer, $object, $user->hasRight('facture', 'creer'), 'string', '', 0, 1);
1283  //$morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_customer, $object, $user->hasRight('facture', 'creer'), 'string', '', null, null, '', 1);
1284  // Thirdparty
1285  $morehtmlref .= $object->thirdparty->getNomUrl(1, 'customer');
1286  // Project
1287  if (isModEnabled('project')) {
1288  $langs->load("projects");
1289  $morehtmlref .= '<br>';
1290  if ($user->hasRight('facture', 'creer')) {
1291  $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
1292  if ($action != 'classify') {
1293  $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
1294  }
1295  $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
1296  } else {
1297  if (!empty($object->fk_project)) {
1298  $proj = new Project($db);
1299  $proj->fetch($object->fk_project);
1300  $morehtmlref .= ' : '.$proj->getNomUrl(1);
1301  if ($proj->title) {
1302  $morehtmlref .= ' - '.$proj->title;
1303  }
1304  } else {
1305  $morehtmlref .= '';
1306  }
1307  }
1308  }
1309  $morehtmlref .= '</div>';
1310 
1311  $morehtmlstatus = '';
1312 
1313  dol_banner_tab($object, 'ref', $linkback, 1, 'title', 'none', $morehtmlref, '', 0, '', $morehtmlstatus);
1314 
1315  print '<div class="fichecenter">';
1316  print '<div class="fichehalfleft">';
1317  print '<div class="underbanner clearboth"></div>';
1318 
1319  print '<table class="border centpercent tableforfield">';
1320 
1321  // Invoice subtype
1322  if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED')) {
1323  print "<tr><td>".$langs->trans("InvoiceSubtype")."</td><td>";
1324  if ($object->subtype > 0) {
1325  print $object->getSubtypeLabel('facture_rec');
1326  }
1327  print "</td></tr>";
1328  }
1329 
1330  // Author
1331  print '<tr><td class="titlefield">'.$langs->trans("Author").'</td><td>';
1332  print $author->getNomUrl(-1);
1333  print "</td></tr>";
1334 
1335  // Amount (excl. tax)
1336  print '<tr><td>'.$langs->trans("AmountHT").'</td>';
1337  print '<td>'.price($object->total_ht, 0, $langs, 1, -1, -1, $conf->currency).'</td>';
1338  print '</tr>';
1339 
1340  // Amount tax
1341  print '<tr><td>'.$langs->trans("AmountVAT").'</td><td>'.price($object->total_tva, 0, $langs, 1, -1, -1, $conf->currency).'</td>';
1342  print '</tr>';
1343 
1344  // Amount Local Taxes
1345  if (($mysoc->localtax1_assuj == "1" && $mysoc->useLocalTax(1)) || $object->total_localtax1 != 0) { // Localtax1
1346  print '<tr><td>'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td>';
1347  print '<td class="nowrap">'.price($object->total_localtax1, 1, '', 1, - 1, - 1, $conf->currency).'</td></tr>';
1348  }
1349  if (($mysoc->localtax2_assuj == "1" && $mysoc->useLocalTax(2)) || $object->total_localtax2 != 0) { // Localtax2
1350  print '<tr><td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td>';
1351  print '<td class=nowrap">'.price($object->total_localtax2, 1, '', 1, - 1, - 1, $conf->currency).'</td></tr>';
1352  }
1353 
1354  print '<tr><td>'.$langs->trans("AmountTTC").'</td><td colspan="3">'.price($object->total_ttc, 0, $langs, 1, -1, -1, $conf->currency).'</td>';
1355  print '</tr>';
1356 
1357 
1358  // Payment term
1359  print '<tr><td>';
1360  print '<table class="nobordernopadding centpercent"><tr><td>';
1361  print $langs->trans('PaymentConditionsShort');
1362  print '</td>';
1363  if ($action != 'editconditions' && $user->hasRight('facture', 'creer')) {
1364  print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editconditions&token='.newToken().'&facid='.$object->id.'">'.img_edit($langs->trans('SetConditions'), 1).'</a></td>';
1365  }
1366  print '</tr></table>';
1367  print '</td><td>';
1368  if ($object->type != Facture::TYPE_CREDIT_NOTE) {
1369  if ($action == 'editconditions') {
1370  $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, $object->cond_reglement_id, 'cond_reglement_id');
1371  } else {
1372  $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, $object->cond_reglement_id, 'none');
1373  }
1374  } else {
1375  print '&nbsp;';
1376  }
1377  print '</td></tr>';
1378 
1379  // Payment mode
1380  print '<tr><td>';
1381  print '<table class="nobordernopadding" width="100%"><tr><td>';
1382  print $langs->trans('PaymentMode');
1383  print '</td>';
1384  if ($action != 'editmode' && $user->hasRight('facture', 'creer')) {
1385  print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editmode&token='.newToken().'&facid='.$object->id.'">'.img_edit($langs->trans('SetMode'), 1).'</a></td>';
1386  }
1387  print '</tr></table>';
1388  print '</td><td>';
1389  if ($action == 'editmode') {
1390  $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, $object->mode_reglement_id, 'mode_reglement_id', 'CRDT', 1, 1);
1391  } else {
1392  $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, $object->mode_reglement_id, 'none');
1393  }
1394  print '</td></tr>';
1395 
1396  // Multicurrency
1397  if (isModEnabled('multicurrency')) {
1398  // Multicurrency code
1399  print '<tr>';
1400  print '<td>';
1401  print '<table class="nobordernopadding" width="100%"><tr><td>';
1402  print $form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0);
1403  print '</td>';
1404  if ($usercancreate && $action != 'editmulticurrencycode' && $object->suspended == $object::STATUS_SUSPENDED) {
1405  print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editmulticurrencycode&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).'</a></td>';
1406  }
1407  print '</tr></table>';
1408  print '</td><td>';
1409  $htmlname = (($usercancreate && $action == 'editmulticurrencycode') ? 'multicurrency_code' : 'none');
1410  $form->form_multicurrency_code($_SERVER['PHP_SELF'].'?id='.$object->id, $object->multicurrency_code, $htmlname);
1411  print '</td></tr>';
1412 
1413  // Multicurrency rate
1414  if ($object->multicurrency_code != $conf->currency || $object->multicurrency_tx != 1) {
1415  print '<tr>';
1416  print '<td>';
1417  print '<table class="nobordernopadding" width="100%"><tr><td>';
1418  print $form->editfieldkey('CurrencyRate', 'multicurrency_tx', '', $object, 0);
1419  print '</td>';
1420  if ($usercancreate && $action != 'editmulticurrencyrate' && $object->suspended == $object::STATUS_SUSPENDED && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) {
1421  print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editmulticurrencyrate&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).'</a></td>';
1422  }
1423  print '</tr></table>';
1424  print '</td><td>';
1425  if ($action == 'editmulticurrencyrate' || $action == 'actualizemulticurrencyrate') {
1426  if ($action == 'actualizemulticurrencyrate') {
1427  list($object->fk_multicurrency, $object->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($object->db, $object->multicurrency_code);
1428  }
1429  $form->form_multicurrency_rate($_SERVER['PHP_SELF'].'?id='.$object->id, $object->multicurrency_tx, ($usercancreate ? 'multicurrency_tx' : 'none'), $object->multicurrency_code);
1430  } else {
1431  $form->form_multicurrency_rate($_SERVER['PHP_SELF'].'?id='.$object->id, $object->multicurrency_tx, 'none', $object->multicurrency_code);
1432  if ($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) {
1433  print '<div class="inline-block"> &nbsp; &nbsp; &nbsp; &nbsp; ';
1434  print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=actualizemulticurrencyrate">'.$langs->trans("ActualizeCurrency").'</a>';
1435  print '</div>';
1436  }
1437  }
1438  print '</td></tr>';
1439  }
1440  }
1441 
1442  // Help of substitution key
1443  $dateexample = dol_now();
1444  if (!empty($object->frequency) && !empty($object->date_when)) {
1445  $dateexample = $object->date_when;
1446  }
1447 
1448  // Help of substitution key
1449  $substitutionarray = getCommonSubstitutionArray($langs, 2, null, $object);
1450 
1451  $substitutionarray['__INVOICE_PREVIOUS_MONTH__'] = $langs->trans("PreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%m').')';
1452  $substitutionarray['__INVOICE_MONTH__'] = $langs->trans("MonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%m').')';
1453  $substitutionarray['__INVOICE_NEXT_MONTH__'] = $langs->trans("NextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%m').')';
1454  $substitutionarray['__INVOICE_PREVIOUS_MONTH_TEXT__'] = $langs->trans("TextPreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%B').')';
1455  $substitutionarray['__INVOICE_MONTH_TEXT__'] = $langs->trans("TextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%B').')';
1456  $substitutionarray['__INVOICE_NEXT_MONTH_TEXT__'] = $langs->trans("TextNextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%B').')';
1457  $substitutionarray['__INVOICE_PREVIOUS_YEAR__'] = $langs->trans("PreviousYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'y'), '%Y').')';
1458  $substitutionarray['__INVOICE_YEAR__'] = $langs->trans("YearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%Y').')';
1459  $substitutionarray['__INVOICE_NEXT_YEAR__'] = $langs->trans("NextYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'y'), '%Y').')';
1460  // Only on template invoices
1461  $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_BEFORE_GEN__'] = $langs->trans("DateNextInvoiceBeforeGen").' ('.$langs->trans("Example").': '.dol_print_date(($object->date_when ? $object->date_when : dol_now()), 'dayhour').')';
1462  $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_AFTER_GEN__'] = $langs->trans("DateNextInvoiceAfterGen").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree(($object->date_when ? $object->date_when : dol_now()), $object->frequency, $object->unit_frequency), 'dayhour').')';
1463  $substitutionarray['__INVOICE_COUNTER_CURRENT__'] = $object->nb_gen_done;
1464  $substitutionarray['__INVOICE_COUNTER_MAX__'] = $object->nb_gen_max;
1465 
1466  $htmltext = '<i>'.$langs->trans("FollowingConstantsWillBeSubstituted").':<br>';
1467  foreach ($substitutionarray as $key => $val) {
1468  $htmltext .= $key.' = '.$langs->trans($val).'<br>';
1469  }
1470  $htmltext .= '</i>';
1471 
1472  // Bank Account
1473  print '<tr><td class="nowrap">';
1474  print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
1475  print $langs->trans('BankAccount');
1476  print '<td>';
1477  if (($action != 'editbankaccount') && $user->hasRight('facture', 'creer') && $object->statut == FactureRec::STATUS_DRAFT) {
1478  print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editbankaccount&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetBankAccount'), 1).'</a></td>';
1479  }
1480  print '</tr></table>';
1481  print '</td><td>';
1482  if ($action == 'editbankaccount') {
1483  $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'fk_account', 1);
1484  } else {
1485  $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none');
1486  }
1487  print "</td>";
1488  print '</tr>';
1489 
1490  // Extrafields
1491  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1492 
1493 
1494  // Note public
1495  print '<tr><td>';
1496  print $form->editfieldkey($form->textwithpicto($langs->trans('NotePublic'), $htmltext, 1, 'help', '', 0, 2, 'notepublic'), 'note_public', $object->note_public, $object, $user->hasRight('facture', 'creer'));
1497  print '</td><td class="wordbreak">';
1498  print $form->editfieldval($langs->trans("NotePublic"), 'note_public', $object->note_public, $object, $user->hasRight('facture', 'creer'), 'textarea:'.ROWS_4.':90%', '', null, null, '', 1);
1499  print '</td>';
1500  print '</tr>';
1501 
1502  // Note private
1503  print '<tr><td>';
1504  print $form->editfieldkey($form->textwithpicto($langs->trans("NotePrivate"), $htmltext, 1, 'help', '', 0, 2, 'noteprivate'), 'note_private', $object->note_private, $object, $user->hasRight('facture', 'creer'));
1505  print '</td><td class="wordbreak">';
1506  print $form->editfieldval($langs->trans("NotePrivate"), 'note_private', $object->note_private, $object, $user->hasRight('facture', 'creer'), 'textarea:'.ROWS_4.':90%', '', null, null, '', 1);
1507  print '</td>';
1508  print '</tr>';
1509 
1510  // Model pdf
1511  print '<tr><td class="nowrap">';
1512  print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
1513  print $langs->trans('Model');
1514  print '<td>';
1515  if (($action != 'editmodelpdf') && $user->hasRight('facture', 'creer') && $object->statut == FactureRec::STATUS_DRAFT) {
1516  print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editmodelpdf&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetModel'), 1).'</a></td>';
1517  }
1518  print '</tr></table>';
1519  print '</td><td>';
1520  if ($action == 'editmodelpdf') {
1521  include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
1522  $list = array();
1523  $models = ModelePDFFactures::liste_modeles($db);
1524  foreach ($models as $k => $model) {
1525  $list[] = str_replace(':', '|', $k).':'.$model;
1526  }
1527  $select = 'select;'.implode(',', $list);
1528  print $form->editfieldval($langs->trans("Model"), 'modelpdf', $object->model_pdf, $object, $user->hasRight('facture', 'creer'), $select);
1529  } else {
1530  print $object->model_pdf;
1531  }
1532  print "</td>";
1533  print '</tr>';
1534 
1535  // Other attributes
1536  $cols = 2;
1537 
1538 
1539  print '</table>';
1540 
1541  print '</div>';
1542  print '<div class="fichehalfright">';
1543  print '<div class="underbanner clearboth"></div>';
1544 
1545 
1546  /*
1547  * Recurrence
1548  */
1549  $title = $langs->trans("Recurrence");
1550 
1551  print '<table class="border centpercent tableforfield">';
1552 
1553  print '<tr><td colspan="2">'.img_picto('', 'recurring', 'class="pictofixedwidth"').$title.'</td></tr>';
1554 
1555  // if "frequency" is empty or = 0, the recurrence is disabled
1556  print '<tr><td style="width: 50%">';
1557  print '<table class="nobordernopadding" width="100%"><tr><td>';
1558  print $langs->trans('Frequency');
1559  print '</td>';
1560  if ($action != 'editfrequency' && $user->hasRight('facture', 'creer')) {
1561  print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editfrequency&token='.newToken().'&facid='.$object->id.'">'.img_edit($langs->trans('Edit'), 1).'</a></td>';
1562  }
1563  print '</tr></table>';
1564  print '</td><td>';
1565  if ($action == 'editfrequency') {
1566  print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'">';
1567  print '<input type="hidden" name="action" value="setfrequency">';
1568  print '<input type="hidden" name="token" value="'.newToken().'">';
1569  print '<table class="nobordernopadding">';
1570  print '<tr><td>';
1571  print '<input type="text" name="frequency" class="width50 marginrightonly right" value="'.$object->frequency.'">';
1572  print $form->selectarray('unit_frequency', array('d' => $langs->trans('Day'), 'm' => $langs->trans('Month'), 'y' => $langs->trans('Year')), ($object->unit_frequency ? $object->unit_frequency : 'm'));
1573  print '</td>';
1574  print '<td class="left"><input type="submit" class="button button-edit smallpaddingimp" value="'.$langs->trans("Modify").'"></td>';
1575  print '</tr></table></form>';
1576  } else {
1577  if ($object->frequency > 0) {
1578  print $langs->trans('FrequencyPer_'.$object->unit_frequency, $object->frequency);
1579  } else {
1580  print '<span class="opacitymedium">'.$langs->trans("NotARecurringInvoiceTemplate").'</span>';
1581  }
1582  }
1583  print '</td></tr>';
1584 
1585  // Date when (next invoice generation)
1586  print '<tr><td>';
1587  if ($action == 'date_when' || $object->frequency > 0) {
1588  print $form->editfieldkey($langs->trans("NextDateToExecution"), 'date_when', $object->date_when, $object, $user->hasRight('facture', 'creer'), 'day');
1589  } else {
1590  print $langs->trans("NextDateToExecution");
1591  }
1592  print '</td><td>';
1593  if ($action == 'date_when' || $object->frequency > 0) {
1594  print $form->editfieldval($langs->trans("NextDateToExecution"), 'date_when', $object->date_when, $object, $user->hasRight('facture', 'creer'), 'day', $object->date_when, null, '', '', 0, 'strikeIfMaxNbGenReached');
1595  }
1596  //var_dump(dol_print_date($object->date_when+60, 'dayhour').' - '.dol_print_date($now, 'dayhour'));
1597  if (!$object->isMaxNbGenReached()) {
1598  if (!$object->suspended && $action != 'editdate_when' && $object->frequency > 0 && $object->date_when && $object->date_when < $now) {
1599  print img_warning($langs->trans("Late"));
1600  }
1601  } else {
1602  print img_info($langs->trans("MaxNumberOfGenerationReached"));
1603  }
1604  print '</td>';
1605  print '</tr>';
1606 
1607  // Max period / Rest period
1608  print '<tr><td>';
1609  if ($action == 'nb_gen_max' || $object->frequency > 0) {
1610  print $form->editfieldkey($langs->trans("MaxPeriodNumber"), 'nb_gen_max', $object->nb_gen_max, $object, $user->hasRight('facture', 'creer'));
1611  } else {
1612  print $langs->trans("MaxPeriodNumber");
1613  }
1614  print '</td><td>';
1615  if ($action == 'nb_gen_max' || $object->frequency > 0) {
1616  print $form->editfieldval($langs->trans("MaxPeriodNumber"), 'nb_gen_max', $object->nb_gen_max ? $object->nb_gen_max : '', $object, $user->hasRight('facture', 'creer'));
1617  } else {
1618  print '';
1619  }
1620  print '</td>';
1621  print '</tr>';
1622 
1623  // Status of auto generated invoices
1624  print '<tr><td>';
1625  if ($action == 'auto_validate' || $object->frequency > 0) {
1626  print $form->editfieldkey($langs->trans("StatusOfAutoGeneratedInvoices"), 'auto_validate', $object->auto_validate, $object, $user->hasRight('facture', 'creer'));
1627  } else {
1628  print $langs->trans("StatusOfAutoGeneratedInvoices");
1629  }
1630  print '</td><td>';
1631  $select = 'select;0:'.$langs->trans('BillStatusDraft').',1:'.$langs->trans('BillStatusValidated');
1632  if ($action == 'auto_validate' || $object->frequency > 0) {
1633  print $form->editfieldval($langs->trans("StatusOfAutoGeneratedInvoices"), 'auto_validate', $object->auto_validate, $object, $user->hasRight('facture', 'creer'), $select);
1634  }
1635  print '</td>';
1636  // Auto generate documents
1637  if (getDolGlobalString('INVOICE_REC_CAN_DISABLE_DOCUMENT_FILE_GENERATION')) {
1638  print '<tr>';
1639  print '<td>';
1640  if ($action == 'generate_pdf' || $object->frequency > 0) {
1641  print $form->editfieldkey($langs->trans("StatusOfGeneratedDocuments"), 'generate_pdf', $object->generate_pdf, $object, $user->hasRight('facture', 'creer'));
1642  } else {
1643  print $langs->trans("StatusOfGeneratedDocuments");
1644  }
1645  print '</td>';
1646  print '<td>';
1647  $select = 'select;0:'.$langs->trans('DoNotGenerateDoc').',1:'.$langs->trans('AutogenerateDoc');
1648  if ($action == 'generate_pdf' || $object->frequency > 0) {
1649  print $form->editfieldval($langs->trans("StatusOfGeneratedDocuments"), 'generate_pdf', $object->generate_pdf, $object, $user->hasRight('facture', 'creer'), $select);
1650  }
1651  print '</td>';
1652  print '</tr>';
1653  } else {
1654  print '<input type="hidden" name="generate_pdf" value="1">';
1655  }
1656 
1657  print '</table>';
1658 
1659  // Frequencry/Recurring section
1660  if ($object->frequency > 0) {
1661  print '<br>';
1662 
1663  if (!isModEnabled('cron')) {
1664  print info_admin($langs->trans("EnableAndSetupModuleCron", $langs->transnoentitiesnoconv("Module2300Name")));
1665  }
1666 
1667  print '<div class="underbanner clearboth"></div>';
1668  print '<table class="border centpercent tableforfield">';
1669 
1670  // Nb of generation already done
1671  print '<tr><td style="width: 50%">'.$langs->trans("NbOfGenerationDone").'</td>';
1672  print '<td>';
1673  print $object->nb_gen_done ? $object->nb_gen_done : '0';
1674  print '</td>';
1675  print '</tr>';
1676 
1677  // Date last
1678  print '<tr><td>';
1679  print $langs->trans("DateLastGeneration");
1680  print '</td><td>';
1681  print dol_print_date($object->date_last_gen, 'dayhour');
1682  print '</td>';
1683  print '</tr>';
1684 
1685  print '</table>';
1686 
1687  print '<br>';
1688  }
1689 
1690  print '</div>';
1691  print '</div>';
1692 
1693  print '<div class="clearboth"></div><br>';
1694 
1695 
1696  // Lines
1697  print '<form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '#add' : '#line_'.GETPOSTINT('lineid')).'" method="POST">';
1698  print '<input type="hidden" name="token" value="' . newToken().'">';
1699  print '<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">';
1700  print '<input type="hidden" name="mode" value="">';
1701  print '<input type="hidden" name="id" value="' . $object->id.'">';
1702  print '<input type="hidden" name="page_y" value="">';
1703 
1704  if (!empty($conf->use_javascript_ajax) && $object->statut == 0) {
1705  include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
1706  }
1707 
1708  print '<div class="div-table-responsive-no-min">';
1709  print '<table id="tablelines" class="noborder noshadow centpercent">';
1710  // Show object lines
1711  if (!empty($object->lines)) {
1712  $canchangeproduct = 1;
1713  $object->printObjectLines($action, $mysoc, $object->thirdparty, $lineid, 0); // No date selector for template invoice
1714  }
1715 
1716  // Form to add new line
1717  if ($object->status == $object::STATUS_DRAFT && $user->hasRight('facture', 'creer') && $action != 'valid' && $action != 'editline') {
1718  if ($action != 'editline') {
1719  // Add free products/services
1720 
1721  $parameters = array();
1722  $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1723  if ($reshook < 0) {
1724  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1725  }
1726  if (empty($reshook)) {
1727  $object->formAddObjectLine(0, $mysoc, $object->thirdparty);
1728  } // No date selector for template invoice
1729  }
1730  }
1731 
1732  print "</table>\n";
1733  print '</div>';
1734 
1735  print "</form>\n";
1736 
1737  print dol_get_fiche_end();
1738 
1739 
1740  /*
1741  * Action bar
1742  */
1743  print '<div class="tabsAction">';
1744 
1745  $parameters = array();
1746  $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1747  if (empty($reshook)) {
1748  $params = array(
1749  'attr' => array(
1750  'class' => 'classfortooltip',
1751  ),
1752  );
1753  if (empty($object->suspended)) {
1754  if ($user->hasRight('facture', 'creer')) {
1755  if (!empty($object->frequency) && $object->nb_gen_max > 0 && ($object->nb_gen_done >= $object->nb_gen_max)) {
1756  print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' . dol_escape_htmltag($langs->trans("MaxGenerationReached")) . '">' . $langs->trans("CreateBill") . '</a></div>';
1757  } else {
1758  if (empty($object->frequency) || $object->date_when <= $nowlasthour) {
1759  print '<div class="inline-block divButAction"><a class="butAction" href="' . DOL_URL_ROOT . '/compta/facture/card.php?action=create&socid=' . $object->thirdparty->id . '&fac_rec=' . $object->id . '">' . $langs->trans("CreateBill") . '</a></div>';
1760  } else {
1761  print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' . dol_escape_htmltag($langs->trans("DateIsNotEnough")) . '">' . $langs->trans("CreateBill") . '</a></div>';
1762  }
1763  }
1764  } else {
1765  print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#">' . $langs->trans("CreateBill") . '</a></div>';
1766  }
1767  }
1768 
1769  if ($user->hasRight('facture', 'creer')) {
1770  if (empty($object->suspended)) {
1771  print '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=disable&id='.$object->id.'&token='.newToken().'">'.$langs->trans("Disable").'</a></div>';
1772  } else {
1773  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=enable&id='.$object->id.'&token='.newToken().'">'.$langs->trans("Enable").'</a></div>';
1774  }
1775  }
1776 
1777  // Delete
1778  print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=delete&token=' . newToken(), 'delete', $user->hasRight('facture', 'supprimer'));
1779  }
1780  print '</div>';
1781 
1782 
1783 
1784  print '<div class="fichecenter"><div class="fichehalfleft">';
1785  print '<a name="builddoc"></a>'; // ancre
1786 
1787 
1788  // Show links to link elements
1789  $linktoelem = $form->showLinkToObjectBlock($object, null, array('invoice'));
1790 
1791  $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
1792 
1793 
1794  print '</div>';
1795  print '<div class="fichehalfright">';
1796 
1797  $MAXEVENT = 10;
1798 
1799  //$morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', dol_buildpath('/mymodule/myobject_agenda.php', 1).'?id='.$object->id);
1800  $morehtmlcenter = '';
1801 
1802  // List of actions on element
1803  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
1804  $formactions = new FormActions($db);
1805  $somethingshown = $formactions->showactions($object, $object->element, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlcenter);
1806 
1807  print '</div>';
1808  print '</div>';
1809  }
1810 }
1811 
1812 // End of page
1813 llxFooter();
1814 $db->close();
if($user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition: card.php:58
if(preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) if(preg_match('/del_([a-z0-9_\-]+)/i', $action, $reg)) if($action=='set') elseif($action=='specimen') elseif($action=='setmodel') elseif($action=='del') elseif($action=='setdoc') $formactions
View.
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:55
llxFooter()
Empty footer.
Definition: wrapper.php:69
const STATUS_DRAFT
Draft status.
Class to manage a WYSIWYG editor.
Class to manage standard extra fields.
Class to manage invoices.
const TYPE_REPLACEMENT
Replacement invoice.
const TYPE_STANDARD
Standard invoice.
const TYPE_CREDIT_NOTE
Credit note invoice.
Class to manage invoice lines of templates.
Class to manage invoice templates.
Class to manage building of HTML components.
Class to manage generation of HTML components Only common components must be here.
Class permettant la generation de composants html autre Only common components are here.
Class to manage building of HTML components.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
static getIdAndTxFromCode($dbs, $code, $date_document='')
Get id and rate of currency from code.
Class to manage products or services.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
Class to manage Dolibarr users.
Definition: user.class.php:50
getCountry($searchkey, $withcode='', $dbtouse=null, $outputlangs=null, $entconv=1, $searchlabel='')
Return country label, code or id from an id, code or label.
dol_get_last_hour($date, $gm='tzserver')
Return GMT time for last hour of a given GMT date (it replaces hours, min and second part to 23:59:59...
Definition: date.lib.php:641
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition: date.lib.php:124
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
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.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
newToken()
Return the value of token currently saved into session with name 'newtoken'.
dol_clone($object, $native=0)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dolGetButtonAction($label, $text='', $actionType='default', $url='', $id='', $userRight=1, $params=array())
Function dolGetButtonAction.
dol_htmlcleanlastbr($stringtodecode)
This function remove all ending and br at end.
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='')
Show information in HTML for admin users or standard users.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $object=null, $include=null)
Return array of possible common substitutions.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
get_localtax($vatrate, $local, $thirdparty_buyer=null, $thirdparty_seller=null, $vatnpr=0)
Return localtax rate for a particular vat, when selling a product with vat $vatrate,...
img_info($titlealt='default')
Show info logo.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
invoice_rec_prepare_head($object)
Return array head with list of tabs to view object information.
$formconfirm
if ($action == 'delbookkeepingyear') {
div float
Buy price without taxes.
Definition: style.css.php:960
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.