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