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