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