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