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