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