dolibarr 25.0.0-alpha
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-2026 Frédéric France <frederic.france@free.fr>
12 * Copyright (C) 2023 Nick Fragoulis
13 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
14 * Copyright (C) 2026 Joris Le Blansch <ping@apio.systems>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program. If not, see <https://www.gnu.org/licenses/>.
28 */
29
36// Load Dolibarr environment
37require '../../main.inc.php';
47require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
48require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
49require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
50if (isModEnabled('project')) {
51 include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
52}
53require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
54require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
55require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice.lib.php';
56
57// Load translation files required by the page
58$langs->loadLangs(array('bills', 'companies', 'compta', 'admin', 'other', 'products', 'banks'));
59
60$action = GETPOST('action', 'aZ09');
61$massaction = GETPOST('massaction', 'alpha');
62$show_files = GETPOSTINT('show_files');
63$confirm = GETPOST('confirm', 'alpha');
64$cancel = GETPOST('cancel', 'alpha');
65$toselect = GETPOST('toselect', 'array:int');
66$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'invoicetemplatelist'; // To manage different context of search
67$backtopage = GETPOST('backtopage', 'alpha'); // if not set, a default page will be used
68$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); // if not set, $backtopage will be used
69
70
71$id = (GETPOSTINT('facid') ? GETPOSTINT('facid') : GETPOSTINT('id'));
72$lineid = GETPOSTINT('lineid');
73$ref = GETPOST('ref', 'alpha');
74$socid = 0;
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:int');
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
119// fetch optionals attributes and labels
120$extrafields->fetch_name_optionals_label($object->table_element);
121
122$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
123
124$permissiontoadd = $user->hasRight('facture', 'creer');
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$permissiontoeditextra = $permissiontoadd;
129if (GETPOST('attribute', 'aZ09') && isset($extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')])) {
130 // For action 'update_extras', is there a specific permission set for the attribute to update
131 $permissiontoeditextra = dol_eval((string) $extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')]);
132}
133
134$usercanread = $user->hasRight('facture', 'lire');
135$usercancreate = $user->hasRight('facture', 'creer');
136$usercanissuepayment = $user->hasRight('facture', 'paiement');
137$usercandelete = $user->hasRight('facture', 'supprimer');
138
139// Advanced permissions
140$usercanvalidate = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $usercancreate) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('facture', 'invoice_advance', 'validate')));
141$usercansend = (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->hasRight('facture', 'invoice_advance', 'send'));
142$usercanreopen = (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->hasRight('facture', 'invoice_advance', 'reopen'));
143$usercanunvalidate = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !empty($usercancreate)) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('facture', 'invoice_advance', 'unvalidate')));
144$usermustrespectpricemin = ((getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight('produit', 'ignore_price_min_advance')) || !getDolGlobalString('MAIN_USE_ADVANCED_PERMS'));
145
146// Other permissions
147$usercanproductignorepricemin = ((getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight('produit', 'ignore_price_min_advance')) || !getDolGlobalString('MAIN_USE_ADVANCED_PERMS'));
148$usercancreatemargin = $user->hasRight("margins", "creer");
149$usercanreadallmargin = $user->hasRight("margins", "liretous");
150$usercancreatewithdrarequest = $user->hasRight("prelevement", "bons", "creer");
151
152$now = dol_now();
153
154$error = 0;
155
156// Security check
157$result = restrictedArea($user, 'facture', $object->id, $objecttype);
158
159
160/*
161 * Actions
162 */
163
164if (GETPOST('cancel', 'alpha')) {
165 if ($action != 'updateline') {
166 $action = 'list';
167 $massaction = '';
168 } else {
169 $action = '';
170 $cancel = '';
171 }
172}
173if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
174 $massaction = '';
175}
176
177$parameters = array('socid' => $socid);
178$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
179if ($reshook < 0) {
180 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
181}
182
183if (empty($reshook)) {
184 $backurlforlist = DOL_URL_ROOT.'/compta/facture/invoicetemplate_list.php';
185
186 if (empty($backtopage) || ($cancel && empty($id))) {
187 if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
188 if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
189 $backtopage = $backurlforlist;
190 } else {
191 $backtopage = DOL_URL_ROOT.'/compta/facture/invoicetemplate_list.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
192 }
193 }
194 }
195
196 // include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
197 if ($cancel) {
198 /*var_dump($cancel);var_dump($backtopage);var_dump($backtopageforcancel);exit;*/
199 if (!empty($backtopageforcancel)) {
200 header("Location: ".$backtopageforcancel);
201 exit;
202 } elseif (!empty($backtopage)) {
203 header("Location: ".$backtopage);
204 exit;
205 }
206 $action = '';
207 }
208
209 // Selection of new fields
210 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
211
212 // Set note
213 include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be 'include', not 'include_once'
214
215 include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be 'include', not 'include_once'
216
217 include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be 'include', not 'include_once'
218
219 // Mass actions
220 /*$objectclass='MyObject';
221 $objectlabel='MyObject';
222 $uploaddir = $conf->mymodule->dir_output;
223 include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';*/
224
225 // Create predefined invoice
226 if ($action == 'add' && $usercancreate) {
227 if (!GETPOST('title', 'alphanohtml')) {
228 setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("Title")), null, 'errors');
229 $action = "create";
230 $error++;
231 }
232
233 $frequency = GETPOSTINT('frequency');
234 $reyear = GETPOSTINT('reyear');
235 $remonth = GETPOSTINT('remonth');
236 $reday = GETPOSTINT('reday');
237 $rehour = GETPOSTINT('rehour');
238 $remin = GETPOSTINT('remin');
239 $nb_gen_max = GETPOSTINT('nb_gen_max');
240 //if (empty($nb_gen_max)) $nb_gen_max =0;
241
242 if (GETPOSTINT('frequency')) {
243 if (empty($reyear) || empty($remonth) || empty($reday)) {
244 setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("Date")), null, 'errors');
245 $action = "create";
246 $error++;
247 }
248 /*if ($nb_gen_max === '') {
249 setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("MaxPeriodNumber")), null, 'errors');
250 $action = "create";
251 $error++;
252 }*/
253 }
254
255 if (!$error) {
256 $object->subtype = GETPOSTINT('subtype');
257 $object->title = GETPOST('title', 'alphanohtml');
258
259 $object->note_private = GETPOST('note_private', 'restricthtml');
260 $object->note_public = GETPOST('note_public', 'restricthtml');
261 $object->model_pdf = GETPOST('modelpdf', 'alphanohtml');
262 $object->usenewprice = GETPOSTINT('usenewprice');
263
264 $object->mode_reglement_id = GETPOSTINT('mode_reglement_id');
265 $object->cond_reglement_id = GETPOSTINT('cond_reglement_id');
266 $object->fk_societe_rib = GETPOSTINT('accountcustomerid');
267 $object->rule_for_lines_dates = GETPOST('rule_for_lines_dates', 'alpha');
268
269 $object->frequency = $frequency;
270 $object->unit_frequency = GETPOST('unit_frequency', 'alpha');
271 $object->nb_gen_max = $nb_gen_max;
272 $object->auto_validate = GETPOSTINT('auto_validate');
273 $object->fk_email_template = GETPOSTINT('auto_send_model_mail');
274 $object->generate_pdf = GETPOSTINT('generate_pdf');
275 $object->fk_project = $projectid;
276
277 $date_next_execution = dol_mktime($rehour, $remin, 0, $remonth, $reday, $reyear);
278 $object->date_when = $date_next_execution;
279
280 $ret = $extrafields->setOptionalsFromPost(null, $object);
281 if ($ret < 0) {
282 setEventMessages($extrafields->error, $extrafields->errors, 'errors');
283 $error++;
284 }
285
286 // Get first contract linked to invoice (or order or proposal) used to generate template (facid is id of source invoice)
287 if (GETPOSTINT('facid') > 0) {
288 $srcObject = new Facture($db);
289 $srcObject->fetch(GETPOSTINT('facid'));
290
291 $srcObject->fetchObjectLinked();
292
293 if (!empty($srcObject->linkedObjectsIds['contrat'])) {
294 $contractidid = reset($srcObject->linkedObjectsIds['contrat']);
295
296 $object->origin_type = 'contrat';
297 $object->origin_id = $contractidid;
298 $object->linked_objects[$object->origin_type] = $object->origin_id;
299 } elseif (!empty($srcObject->linkedObjectsIds['commande'])) {
300 $orderid = reset($srcObject->linkedObjectsIds['commande']);
301
302 $object->linked_objects['commande'] = $orderid;
303 } elseif (!empty($srcObject->linkedObjectsIds['propal'])) {
304 $proposalid = reset($srcObject->linkedObjectsIds['propal']);
305 $object->linked_objects['propal'] = $proposalid;
306 }
307 }
308
309 $db->begin();
310
311 $oldinvoice = new Facture($db);
312 $oldinvoice->fetch(GETPOSTINT('facid'));
313
314 $onlylines = GETPOST('toselect', 'array:int');
315
316 $result = $object->create($user, $oldinvoice->id, 0, $onlylines);
317 if ($result > 0) {
318 $result = $oldinvoice->delete($user, 1);
319 if ($result < 0) {
320 $error++;
321 setEventMessages($oldinvoice->error, $oldinvoice->errors, 'errors');
322 $action = "create";
323 }
324 } else {
325 $error++;
326 setEventMessages($object->error, $object->errors, 'errors');
327 $action = "create";
328 }
329
330 if (!$error) {
331 $db->commit();
332
333 header("Location: ".$_SERVER['PHP_SELF'].'?facid='.$object->id);
334 exit;
335 } else {
336 $db->rollback();
337
338 $action = "create";
339 }
340 }
341 }
342
343 // Delete
344 if ($action == 'confirm_delete' && $confirm == 'yes' && $user->hasRight('facture', 'supprimer')) {
345 $object->delete($user);
346
347 header("Location: ".DOL_URL_ROOT.'/compta/facture/invoicetemplate_list.php');
348 exit;
349 }
350
351
352 // Update field
353 if ($action == 'setconditions' && $usercancreate) {
354 // Set condition
355 $object->context['actionmsg'] = $langs->trans("FieldXModified", $langs->transnoentitiesnoconv("PaymentTerm"));
356 $result = $object->setPaymentTerms(GETPOSTINT('cond_reglement_id'));
357 } elseif ($action == 'setmode' && $usercancreate) {
358 // Set mode
359 $object->context['actionmsg'] = $langs->trans("FieldXModified", $langs->transnoentitiesnoconv("PaymentMode"));
360 $object->setPaymentMethods(GETPOSTINT('mode_reglement_id'));
361 $object->setValueFrom('fk_societe_rib', 0);
362
363 //Need to reload to display bank customer account field
364 header("Location: ".$_SERVER['PHP_SELF'].'?facid='.$object->id);
365 exit;
366 } elseif ($action == 'classin' && $usercancreate) {
367 // Set project
368 $object->context['actionmsg'] = $langs->trans("FieldXModified", $langs->transnoentitiesnoconv("Project"));
369 $object->setProject(GETPOSTINT('projectid'));
370 } elseif ($action == 'setref' && $usercancreate) {
371 // Set bank account
372 $object->context['actionmsg'] = $langs->trans("FieldXModifiedFromYToZ", $langs->transnoentitiesnoconv("Title"), $object->title, $ref);
373 $result = $object->setValueFrom('titre', $ref, '', null, 'text', '', $user, 'BILLREC_MODIFY');
374 if ($result > 0) {
375 $object->title = $ref;
376 $object->ref = $object->title;
377 } else {
378 $error++;
379 if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
380 $langs->load("errors");
381 setEventMessages($langs->trans('ErrorRefAlreadyExists', $ref), null, 'errors');
382 } else {
383 setEventMessages($object->error, $object->errors, 'errors');
384 }
385 }
386 } elseif ($action == 'setbankaccount' && $usercancreate) {
387 // Set bank account
388 $object->context['actionmsg'] = $langs->trans("FieldXModified", $langs->transnoentitiesnoconv("Bank"));
389 $result = $object->setBankAccount(GETPOSTINT('fk_account'));
390 } elseif ($action == 'setbankaccountcustomer' && $usercancreate) {
391 // Set bank account customer
392 $object->context['actionmsg'] = $langs->trans("FieldXModified", $langs->transnoentitiesnoconv("DebitBankAccount"));
393 $fk_societe_rib = (GETPOSTINT('accountcustomerid') != "-1") ? GETPOSTINT('accountcustomerid') : 0;
394 $result = $object->setValueFrom('fk_societe_rib', $fk_societe_rib);
395 } elseif ($action == 'setfrequency' && $usercancreate) {
396 // Set frequency and unit frequency
397 $object->context['actionmsg'] = $langs->trans("FieldXModified", $langs->transnoentitiesnoconv("Frequency"));
398 $object->setFrequencyAndUnit(GETPOSTINT('frequency'), GETPOST('unit_frequency'));
399 } elseif ($action == 'setdate_when' && $usercancreate) {
400 // Set next date of execution
401 $date = dol_mktime(GETPOSTINT('date_whenhour'), GETPOSTINT('date_whenmin'), 0, GETPOSTINT('date_whenmonth'), GETPOSTINT('date_whenday'), GETPOSTINT('date_whenyear'));
402 if (!empty($date)) {
403 $object->setNextDate($date);
404 }
405 } elseif ($action == 'setnb_gen_max' && $usercancreate) {
406 // Set max period
407 $object->setMaxPeriod(GETPOSTINT('nb_gen_max'));
408 } elseif ($action == 'setauto_validate' && $usercancreate) {
409 // Set auto validate
410 $object->setAutoValidate(GETPOSTINT('auto_validate'));
411 } elseif ($action == 'setEmailTemplate' && $usercancreate) {
412 // Set Email Template
413 $object->setMailTemplate(GETPOSTINT('auto_send_model_mail'));
414 } elseif ($action == 'setgenerate_pdf' && $usercancreate) {
415 // Set generate pdf
416 $object->setGeneratepdf(GETPOSTINT('generate_pdf'));
417 } elseif ($action == 'setmodelpdf' && $usercancreate) {
418 // Set model pdf
419 $object->setModelpdf(GETPOST('modelpdf', 'alpha'));
420 } elseif ($action == 'disable' && $usercancreate) {
421 // Set status disabled
422 $db->begin();
423
424 $object->context['actionmsg'] = $langs->trans("RecordDisabled");
425
426 $res = $object->setValueFrom('suspended', 1, '', null, 'text', '', $user, 'BILLREC_MODIFY');
427 if ($res <= 0) {
428 $error++;
429 }
430
431 if (!$error) {
432 $db->commit();
433 } else {
434 $db->rollback();
435 setEventMessages($object->error, $object->errors, 'errors');
436 }
437 } elseif ($action == 'enable' && $usercancreate) {
438 // Set status enabled
439 $db->begin();
440
441 $object->context['actionmsg'] = $langs->trans("RecordEnabled");
442
443 $res = $object->setValueFrom('suspended', 0, '', null, 'text', '', $user, 'BILLREC_MODIFY');
444 if ($res <= 0) {
445 $error++;
446 }
447
448 if (!$error) {
449 $db->commit();
450 } else {
451 $db->rollback();
452 setEventMessages($object->error, $object->errors, 'errors');
453 }
454 } elseif ($action == 'setmulticurrencycode' && $usercancreate) {
455 // Multicurrency Code
456 $result = $object->setMulticurrencyCode(GETPOST('multicurrency_code', 'alpha'));
457 $object->fetch($object->id); // Reload all.
458 } elseif ($action == 'setmulticurrencyrate' && $usercancreate) {
459 // Multicurrency rate
460 $result = $object->setMulticurrencyRate(GETPOSTFLOAT('multicurrency_tx'), GETPOSTINT('calculation_mode'));
461 $object->fetch($object->id); // Reload all.
462 } elseif ($action == 'setruleforlinesdates' && $usercancreate) {
463 $object->context['actionmsg'] = $langs->trans("FieldXModified", $langs->transnoentitiesnoconv("RuleForLinesDates"));
464 $ruleForLinesDates = GETPOSTISSET('rule_for_lines_dates') ? GETPOST('rule_for_lines_dates', 'alpha') : 'prepaid';
465 $object->setValueFrom('rule_for_lines_dates', $ruleForLinesDates);
466 }
467
468 // Delete line
469 if ($action == 'confirm_deleteline' && $confirm == 'yes' && $usercancreate) {
470 $object->fetch($id);
471 $object->fetch_thirdparty();
472
473 $db->begin();
474
475 $line = new FactureLigneRec($db);
476
477 // For triggers
478 $line->id = $lineid;
479
480 if ($line->delete($user) > 0) {
481 $result = $object->update_price(1);
482
483 if ($result > 0) {
484 $db->commit();
485 $object->fetch($object->id); // Reload lines
486 } else {
487 $db->rollback();
488 setEventMessages($db->lasterror(), null, 'errors');
489 }
490 } else {
491 $db->rollback();
492 setEventMessages($line->error, $line->errors, 'errors');
493 }
494 } elseif ($action == 'confirm_delete_subtotalline' && $confirm == 'yes' && $usercancreate) {
495 // Delete line
496 $object->fetch($id);
497 $object->fetch_thirdparty();
498
499 $result = $object->deleteSubtotalLine($langs, GETPOSTINT('lineid'), (bool) GETPOST('deletecorrespondingsubtotalline'), $user);
500 if ($result > 0) {
501 $result = $object->update_price(1);
502
503 if ($result > 0) {
504 $db->commit();
505 $object->fetch($object->id); // Reload lines
506 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);
507 exit();
508 } else {
509 $db->rollback();
510 setEventMessages($db->lasterror(), null, 'errors');
511 }
512 } else {
513 setEventMessages($object->error, $object->errors, 'errors');
514 $action = '';
515 }
516 } elseif ($action == 'update_extras' && $permissiontoeditextra) {
517 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
518
519 $attribute_name = GETPOST('attribute', 'aZ09');
520
521 // Fill array 'array_options' with data from update form
522 $ret = $extrafields->setOptionalsFromPost(null, $object, $attribute_name);
523 if ($ret < 0) {
524 $error++;
525 }
526
527 if (!$error) {
528 $result = $object->updateExtraField($attribute_name, 'BILLREC_MODIFY');
529 if ($result < 0) {
530 setEventMessages($object->error, $object->errors, 'errors');
531 $error++;
532 }
533 }
534
535 if ($error) {
536 $action = 'edit_extras';
537 }
538 }
539
540 // Add a new line
541 if ($action == 'addline' && $usercancreate) {
542 $langs->load('errors');
543 $error = 0;
544
545 // Set if we used free entry or predefined product
546 $predef = '';
547 $product_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : '');
548 $price_ht = price2num(GETPOST('price_ht'), 'MU', 2);
549 $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2);
550 $prod_entry_mode = GETPOST('prod_entry_mode', 'alpha');
551 if ($prod_entry_mode == 'free') {
552 $idprod = 0;
553 } else {
554 $idprod = GETPOSTINT('idprod');
555
556 if (getDolGlobalString('MAIN_DISABLE_FREE_LINES') && $idprod <= 0) {
557 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductOrService")), null, 'errors');
558 $error++;
559 }
560 }
561
562 $tva_tx = (GETPOST('tva_tx', 'alpha') ? GETPOST('tva_tx', 'alpha') : 0);
563
564 $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS', 2);
565 $remise_percent = price2num(GETPOST('remise_percent'.$predef), '', 2);
566 if (empty($remise_percent)) {
567 $remise_percent = 0;
568 }
569
570 // Extrafields
571 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
572 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
573 // Unset extrafield
574 if (is_array($extralabelsline)) {
575 // Get extra fields
576 foreach ($extralabelsline as $key => $value) {
577 unset($_POST["options_".$key.$predef]);
578 }
579 }
580
581 if ((empty($idprod) || $idprod < 0) && ($price_ht < 0) && ((float) $qty < 0)) {
582 setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), null, 'errors');
583 $error++;
584 }
585 if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && GETPOST('type') < 0) {
586 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors');
587 $error++;
588 }
589 if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && (!($price_ht >= 0) || $price_ht == '')) { // Unit price can be 0 but not ''
590 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors');
591 $error++;
592 }
593 if ($qty == '') {
594 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
595 $error++;
596 }
597 if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && empty($product_desc)) {
598 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors');
599 $error++;
600 }
601 if ($qty < 0) {
602 $langs->load("errors");
603 setEventMessages($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), null, 'errors');
604 $error++;
605 }
606
607 if (!$error && ($qty >= 0) && (!empty($product_desc) || (!empty($idprod) && $idprod > 0))) {
608 $ret = $object->fetch($id);
609 if ($ret < 0) {
610 dol_print_error($db, $object->error);
611 exit();
612 }
613 $ret = $object->fetch_thirdparty();
614
615 // Clean parameters
616 $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'));
617 $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'));
618 $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT');
619 $tva_npr = "";
620
621 // Define special_code for special lines
622 $special_code = 0;
623 // if (!GETPOST('qty')) $special_code=3; // Options should not exists on invoices
624
625 // Ecrase $pu par celui du produit
626 // Ecrase $desc par celui du produit
627 // Ecrase $base_price_type par celui du produit
628 // Replaces $fk_unit with the product's
629 if (!empty($idprod) && $idprod > 0) {
630 $prod = new Product($db);
631 $prod->fetch($idprod);
632
633 $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : '');
634
635 // Update if prices fields are defined
636 //$tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id);
637 //$tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id);
638 //if (empty($tva_tx)) {
639 // $tva_npr = 0;
640 //}
641
642 // Search the correct price into loaded array product_price_by_qty using id of array retrieved into POST['pqp'].
643 $pqp = (GETPOSTINT('pbq') ? GETPOSTINT('pbq') : 0);
644
645 $datapriceofproduct = $prod->getSellPrice($mysoc, $object->thirdparty, $pqp);
646
647 $pu_ht = $datapriceofproduct['pu_ht'];
648 $pu_ttc = $datapriceofproduct['pu_ttc'];
649 $price_min = $datapriceofproduct['price_min'];
650 $price_base_type = empty($datapriceofproduct['price_base_type']) ? 'HT' : $datapriceofproduct['price_base_type'];
651 //$tva_tx = $datapriceofproduct['tva_tx'];
652 //$tva_npr = $datapriceofproduct['tva_npr'];
653
654 $tmpvat = (float) price2num(preg_replace('/\s*\‍(.*\‍)/', '', $tva_tx));
655 $tmpprodvat = price2num(preg_replace('/\s*\‍(.*\‍)/', '', (string) $prod->tva_tx));
656
657 // if price ht was forced (ie: from gui when calculated by margin rate and cost price). TODO Why this ?
658 if (!empty($price_ht)) {
659 $pu_ht = price2num($price_ht, 'MU');
660 $pu_ttc = price2num((float) $pu_ht * (1 + ($tmpvat / 100)), 'MU');
661 } elseif ($tmpvat != $tmpprodvat) {
662 // We reevaluate the price according to vat rate because vat rate of transactionmay differs from
663 // the one oth the product by default (for example when country of seller and buyer are different).
664 if ($price_base_type != 'HT') {
665 $pu_ht = price2num((float) $pu_ttc / (1 + ($tmpvat / 100)), 'MU');
666 } else {
667 $pu_ttc = price2num((float) $pu_ht * (1 + ($tmpvat / 100)), 'MU');
668 }
669 }
670
671 $outputlangs = $langs;
672 $newlang = '';
673 $desc = '';
674
675 // Define output language
676 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
677 if (/* empty($newlang) && */ GETPOST('lang_id', 'aZ09')) {
678 $newlang = GETPOST('lang_id', 'aZ09');
679 }
680 if (empty($newlang)) {
681 $newlang = $object->thirdparty->default_lang;
682 }
683 if (!empty($newlang)) {
684 $outputlangs = new Translate("", $conf);
685 $outputlangs->setDefaultLang($newlang);
686 $outputlangs->load('products');
687 }
688
689 $desc = (!empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description;
690 } else {
691 $desc = $prod->description;
692 }
693
694 // Add custom code and origin country into description
695 if (!getDolGlobalString('MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE') && (!empty($prod->customcode) || !empty($prod->country_code))) {
696 $tmptxt = '(';
697 // Define output language
698 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
699 if (!empty($prod->customcode)) {
700 $tmptxt .= $outputlangs->transnoentitiesnoconv("CustomsCode").': '.$prod->customcode;
701 }
702 if (!empty($prod->customcode) && !empty($prod->country_code)) {
703 $tmptxt .= ' - ';
704 }
705 if (!empty($prod->country_code)) {
706 $tmptxt .= $outputlangs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code, '', $db, $outputlangs, 0);
707 }
708 } else {
709 if (!empty($prod->customcode)) {
710 $tmptxt .= $langs->transnoentitiesnoconv("CustomsCode").': '.$prod->customcode;
711 }
712 if (!empty($prod->customcode) && !empty($prod->country_code)) {
713 $tmptxt .= ' - ';
714 }
715 if (!empty($prod->country_code)) {
716 $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code, '', $db, $langs, 0);
717 }
718 }
719 $tmptxt .= ')';
720 $desc = dol_concatdesc($desc, $tmptxt);
721 }
722
723 $type = $prod->type;
724 $fk_unit = $prod->fk_unit;
725 } else {
726 $pu_ht = price2num($price_ht, 'MU');
727 $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
728 $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
729 $tva_tx = str_replace('*', '', $tva_tx);
730 if (empty($tva_tx)) {
731 $tva_npr = 0;
732 }
733 $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
734 $desc = $product_desc;
735 $type = GETPOST('type');
736 $fk_unit = GETPOSTINT('units');
737 }
738
739 $date_start_fill = GETPOSTINT('date_start_fill');
740 $date_end_fill = GETPOSTINT('date_end_fill');
741
742 // Margin
743 $fournprice = (int) (GETPOST('fournprice'.$predef) ? GETPOST('fournprice'.$predef) : ''); // This can be id of supplier price, or 'pmpprice' or 'costprice', or 'inputprice', we force to keep ID only
744 $buyingprice = price2num(GETPOST('buying_price'.$predef) != '' ? GETPOST('buying_price'.$predef) : ''); // If buying_price is '0', we must keep this value
745
746 // Local Taxes
747 $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty, $mysoc, $tva_npr);
748 $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty, $mysoc, $tva_npr);
749
750 $info_bits = 0;
751 if ($tva_npr) {
752 $info_bits |= 0x01;
753 }
754
755 $fk_parent_line = GETPOSTINT('fk_parent_line');
756
757 if ($usercanproductignorepricemin && (!empty($price_min) && ((float) price2num($pu_ht) * (1 - (float) price2num($remise_percent) / 100) < (float) price2num($price_min)))) {
758 $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
759 setEventMessages($mesg, null, 'errors');
760 } else {
761 // Insert line
762 $result = $object->addline($desc, $pu_ht, (float) $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $info_bits, 0, $pu_ttc, $type, -1, $special_code, $label, (int) $fk_unit, 0, $date_start_fill, $date_end_fill, (int) $fournprice, (float) $buyingprice, $fk_parent_line);
763
764 if ($result > 0) {
765 // TODO add "insert" function into FactureLigneRec or add "invoicerecline.class.php" (same of "factureligne.class.php")
766 $objectline = new FactureLigneRec($db);
767 if ($objectline->fetch($result)) {
768 $objectline->array_options = $array_options;
769 $result = $objectline->insertExtraFields();
770 if ($result < 0) {
771 setEventMessages($langs->trans('Error').$result, null, 'errors');
772 }
773 }
774
775 // Define output language and generate document
776 /*if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
777 {
778 // Define output language
779 $outputlangs = $langs;
780 $newlang = '';
781 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
782 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) $newlang = $object->thirdparty->default_lang;
783 if (!empty($newlang)) {
784 $outputlangs = new Translate("", $conf);
785 $outputlangs->setDefaultLang($newlang);
786 }
787 $model=$object->model_pdf;
788 $ret = $object->fetch($id); // Reload to get new records
789
790 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
791 if ($result < 0) setEventMessages($object->error, $object->errors, 'errors');
792 }*/
793 $object->fetch($object->id); // Reload lines
794
795 unset($_POST['prod_entry_mode']);
796
797 unset($_POST['qty']);
798 unset($_POST['type']);
799 unset($_POST['remise_percent']);
800 unset($_POST['price_ht']);
801 unset($_POST['multicurrency_price_ht']);
802 unset($_POST['price_ttc']);
803 unset($_POST['tva_tx']);
804 unset($_POST['product_ref']);
805 unset($_POST['product_label']);
806 unset($_POST['product_desc']);
807 unset($_POST['fournprice']);
808 unset($_POST['buying_price']);
809 unset($_POST['np_marginRate']);
810 unset($_POST['np_markRate']);
811 unset($_POST['dp_desc']);
812 unset($_POST['idprod']);
813 unset($_POST['units']);
814
815 unset($_POST['date_starthour']);
816 unset($_POST['date_startmin']);
817 unset($_POST['date_startsec']);
818 unset($_POST['date_startday']);
819 unset($_POST['date_startmonth']);
820 unset($_POST['date_startyear']);
821 unset($_POST['date_endhour']);
822 unset($_POST['date_endmin']);
823 unset($_POST['date_endsec']);
824 unset($_POST['date_endday']);
825 unset($_POST['date_endmonth']);
826 unset($_POST['date_endyear']);
827
828 unset($_POST['date_start_fill']);
829 unset($_POST['date_end_fill']);
830
831 unset($_POST['situations']);
832 unset($_POST['progress']);
833 } else {
834 setEventMessages($object->error, $object->errors, 'errors');
835 }
836
837 $action = '';
838 }
839 }
840 } elseif ($action == 'confirm_addtextline' && $usercancreate) {
841 // Handling adding a new text line for subtotals module
842
843 $langs->load('subtotals');
844
845 $desc = GETPOST('subtotaltextcontent', 'restricthtml');
846
847 // Insert line
848 $result = $object->addSubtotalLine($langs, $desc, 0, array());
849
850 if ($result >= 0) {
851 if ($result == 0) {
852 setEventMessages($object->error, $object->errors, 'warnings');
853 }
854 $ret = $object->fetch($object->id); // Reload to get new records
855 $object->fetch_thirdparty();
856 } else {
857 setEventMessages($object->error, $object->errors, 'errors');
858 }
859 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);
860 exit();
861 } elseif ($action == 'confirm_addtitleline' && $usercancreate) {
862 // Handling adding a new title line for subtotals module
863
864 $langs->load('subtotals');
865
866 $desc = GETPOST('subtotallinedesc', 'alphanohtml');
867 $depth = GETPOSTINT('subtotallinelevel') ?? 1;
868
869 $subtotal_options = array();
870
871 foreach (FactureRec::$TITLE_OPTIONS as $option) {
872 $value = GETPOST($option, 'alphanohtml');
873 if ($value) {
874 $subtotal_options[$option] = $value == 'on' ? 1 : $value;
875 }
876 }
877
878 // Insert line
879 $result = $object->addSubtotalLine($langs, $desc, (int) $depth, $subtotal_options);
880
881 if ($result >= 0) {
882 if ($result == 0) {
883 setEventMessages($object->error, $object->errors, 'warnings');
884 }
885 $ret = $object->fetch($object->id); // Reload to get new records
886 $object->fetch_thirdparty();
887 } else {
888 setEventMessages($object->error, $object->errors, 'errors');
889 }
890 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);
891 exit();
892 } elseif ($action == 'confirm_addsubtotalline' && $usercancreate) {
893 // Handling adding a new subtotal line for subtotals module
894
895 $langs->load('subtotals');
896
897 $choosen_line = GETPOST('subtotaltitleline', 'alphanohtml');
898 foreach ($object->lines as $line) {
899 if ($line->desc == $choosen_line && $line->special_code == SUBTOTALS_SPECIAL_CODE) {
900 $desc = $line->desc;
901 $depth = -$line->qty;
902 }
903 }
904
905 $subtotal_options = array();
906
907 foreach (FactureRec::$SUBTOTAL_OPTIONS as $option) {
908 $value = GETPOST($option, 'alphanohtml');
909 if ($value) {
910 $subtotal_options[$option] = $value == 'on' ? 1 : $value;
911 }
912 }
913
914 // Insert line
915 if (isset($desc) && isset($depth)) {
916 $result = $object->addSubtotalLine($langs, $desc, (int) $depth, $subtotal_options);
917 } else {
918 $result = -1;
919 $object->errors[] = $langs->trans("CorrespondingTitleNotFound");
920 }
921
922 if ($result >= 0) {
923 $ret = $object->fetch($object->id); // Reload to get new records
924 $object->fetch_thirdparty();
925 } else {
926 setEventMessages($object->error, $object->errors, 'errors');
927 }
928 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);
929 exit();
930 } elseif ($action == 'updateline' && $usercancreate && !GETPOST('cancel', 'alpha')) {
931 if (!$object->fetch($id) > 0) {
933 }
934 $object->fetch_thirdparty();
935
936 // Clean parameters
937 $date_start = '';
938 $date_end = '';
939 //$date_start = dol_mktime(GETPOSTINT('date_starthour'), GETPOSTINT('date_startmin'), GETPOSTINT('date_startsec'), GETPOSTINT('date_startmonth'), GETPOSTINT('date_startday'), GETPOSTINT('date_startyear'));
940 //$date_end = dol_mktime(GETPOSTINT('date_endhour'), GETPOSTINT('date_endmin'), GETPOSTINT('date_endsec'), GETPOSTINT('date_endmonth'), GETPOSTINT('date_endday'), GETPOSTINT('date_endyear'));
941 $description = dol_htmlcleanlastbr(GETPOST('product_desc', 'restricthtml') ? GETPOST('product_desc', 'restricthtml') : GETPOST('desc', 'restricthtml'));
942 $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
943
944 $pu_ht = price2num(GETPOST('price_ht'), '', 2);
945 $pu_ttc = price2num(GETPOST('price_ttc'), '', 2);
946
947 $pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), '', 2);
948 $pu_ttc_devise = price2num(GETPOST('multicurrency_subprice_ttc'), '', 2);
949
950 $qty = (float) price2num(GETPOST('qty', 'alpha'), 'MS');
951
952 // Define info_bits
953 $info_bits = 0;
954 if (preg_match('/\*/', $vat_rate)) {
955 $info_bits |= 0x01;
956 }
957
958 // Define vat_rate
959 $vat_rate = str_replace('*', '', $vat_rate);
960 $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty);
961 $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty);
962
963 // Add buying price
964 $fournprice = (int) (GETPOST('fournprice') ? GETPOST('fournprice') : '');
965 $buyingprice = price2num(GETPOST('buying_price') != '' ? GETPOST('buying_price') : ''); // If buying_price is '0', we must keep this value
966
967 // Prepare a price equivalent for minimum price check
968 $pu_equivalent = $pu_ht;
969 $pu_equivalent_ttc = $pu_ttc;
970
971 $currency_tx = $object->multicurrency_tx;
972
973 // Check if we have a foreign currency
974 // If so, we update the pu_equiv as the equivalent price in base currency
975 if ($pu_ht == '' && $pu_ht_devise != '' && $currency_tx != '' && !empty((float) $currency_tx)) {
976 $pu_equivalent = (float) $pu_ht_devise / (float) $currency_tx;
977 }
978 if ($pu_ttc == '' && $pu_ttc_devise != '' && $currency_tx != '' && !empty((float) $currency_tx)) {
979 $pu_equivalent_ttc = (float) $pu_ttc_devise / (float) $currency_tx;
980 }
981
982 // TODO $pu_equivalent or $pu_equivalent_ttc must be calculated from the one not null taking into account all taxes
983 /*
984 if ($pu_equivalent) {
985 $tmp = calcul_price_total(1, $pu_equivalent, 0, $vat_rate, -1, -1, 0, 'HT', $info_bits, $type);
986 $pu_equivalent_ttc = ...
987 } else {
988 $tmp = calcul_price_total(1, $pu_equivalent_ttc, 0, $vat_rate, -1, -1, 0, 'TTC', $info_bits, $type);
989 $pu_equivalent_ht = ...
990 }
991 */
992
993 // Extrafields
994 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
995 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line);
996
997 $objectline = new FactureLigneRec($db);
998 if ($objectline->fetch(GETPOSTINT('lineid'))) {
999 $objectline->array_options = $array_options;
1000 $result = $objectline->insertExtraFields();
1001 if ($result < 0) {
1002 setEventMessages($langs->trans('Error').$result, null, 'errors');
1003 }
1004 }
1005 $position = ($objectline->rang >= 0 ? $objectline->rang : 0);
1006
1007 // Unset extrafield
1008 if (is_array($extralabelsline)) {
1009 // Get extra fields
1010 foreach ($extralabelsline as $key => $value) {
1011 unset($_POST["options_".$key]);
1012 }
1013 }
1014
1015 // Define special_code for special lines
1016 $special_code = GETPOSTINT('special_code');
1017 if ($special_code == 3) {
1018 $special_code = 0; // Options should not exists on invoices
1019 }
1020
1021 /*
1022 $line = new FactureLigne($db);
1023 $line->fetch(GETPOST('lineid', 'int'));
1024 $percent = $line->get_prev_progress($object->id);
1025
1026 ...
1027 */
1028
1029 $remise_percent = price2num(GETPOST('remise_percent'), '', 2);
1030 if (empty($remise_percent)) {
1031 $remise_percent = 0;
1032 }
1033
1034 $price_base_type = 'HT';
1035 $pu = $pu_ht;
1036 if (empty($pu) && !empty($pu_ttc)) {
1037 $pu = $pu_ttc;
1038 $price_base_type = 'TTC';
1039 }
1040
1041 // Check minimum price
1042 $productid = GETPOSTINT('productid');
1043 if (!empty($productid)) {
1044 $product = new Product($db);
1045 $product->fetch($productid);
1046
1047 $type = $product->type;
1048
1049 $price_min = $product->price_min;
1050 if ((getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) && !empty($object->thirdparty->price_level)) {
1051 $price_min = $product->multiprices_min[$object->thirdparty->price_level];
1052 }
1053 $price_min_ttc = $product->price_min_ttc;
1054 if ((getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) && !empty($object->thirdparty->price_level)) {
1055 $price_min_ttc = $product->multiprices_min_ttc[$object->thirdparty->price_level];
1056 }
1057
1058 $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
1059
1060 $typeinvoice = Facture::TYPE_STANDARD;
1061
1062 // Check price is not lower than minimum (check is done only for standard or replacement invoices)
1063 if ($usermustrespectpricemin && ($typeinvoice == Facture::TYPE_STANDARD || $typeinvoice == Facture::TYPE_REPLACEMENT)) {
1064 if ($pu_equivalent && $price_min && (((float) price2num($pu_equivalent) * (1 - (float) $remise_percent / 100)) < (float) price2num($price_min)) && $price_base_type == 'HT') {
1065 $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
1066 setEventMessages($mesg, null, 'errors');
1067 $error++;
1068 $action = 'editline';
1069 } elseif ($pu_equivalent_ttc && $price_min_ttc && (((float) price2num($pu_equivalent_ttc) * (1 - (float) $remise_percent / 100)) < (float) price2num($price_min_ttc)) && $price_base_type == 'TTC') {
1070 $mesg = $langs->trans("CantBeLessThanMinPriceInclTax", price(price2num($price_min_ttc, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
1071 setEventMessages($mesg, null, 'errors');
1072 $error++;
1073 $action = 'editline';
1074 }
1075 }
1076 } else {
1077 $type = GETPOSTINT('type');
1078 $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
1079
1080 // Check parameters
1081 if (GETPOSTINT('type') < 0) {
1082 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
1083 $error++;
1084 }
1085 }
1086 if ($qty < 0) {
1087 $langs->load("errors");
1088 setEventMessages($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), null, 'errors');
1089 $error++;
1090 }
1091
1092 $date_start_fill = GETPOSTINT('date_start_fill');
1093 $date_end_fill = GETPOSTINT('date_end_fill');
1094 $fk_parent_line = GETPOST('fk_parent_line', 'int');
1095
1096 // Update line
1097 if (!$error) {
1098 $result = $object->updateline(
1099 GETPOSTINT('lineid'),
1100 $description,
1101 (float) $pu_ht,
1102 (float) $qty,
1103 $vat_rate,
1104 $localtax1_rate,
1105 $localtax1_rate,
1106 GETPOSTINT('productid'),
1107 $remise_percent,
1108 'HT',
1109 $info_bits,
1110 0,
1111 0,
1112 $type,
1113 $position,
1114 $special_code,
1115 $label,
1116 GETPOSTINT('units'),
1117 (float) $pu_ht_devise,
1118 0,
1119 $date_start_fill,
1120 $date_end_fill,
1121 (int) $fournprice,
1122 (float) $buyingprice,
1123 (int) $fk_parent_line
1124 );
1125
1126 if ($result >= 0) {
1127 /*if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
1128 // Define output language
1129 $outputlangs = $langs;
1130 $newlang = '';
1131 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id','aZ09')) {
1132 $newlang = GETPOST('lang_id','aZ09');
1133 }
1134 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1135 $newlang = $object->thirdparty->default_lang;
1136 }
1137 if (!empty($newlang)) {
1138 $outputlangs = new Translate("", $conf);
1139 $outputlangs->setDefaultLang($newlang);
1140 }
1141 $ret = $object->fetch($id); // Reload to get new records
1142 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1143 }*/
1144
1145 $object->fetch($object->id); // Reload lines
1146
1147 unset($_POST['qty']);
1148 unset($_POST['type']);
1149 unset($_POST['productid']);
1150 unset($_POST['remise_percent']);
1151 unset($_POST['price_ht']);
1152 unset($_POST['multicurrency_price_ht']);
1153 unset($_POST['price_ttc']);
1154 unset($_POST['tva_tx']);
1155 unset($_POST['product_ref']);
1156 unset($_POST['product_label']);
1157 unset($_POST['product_desc']);
1158 unset($_POST['fournprice']);
1159 unset($_POST['buying_price']);
1160 unset($_POST['np_marginRate']);
1161 unset($_POST['np_markRate']);
1162
1163 unset($_POST['dp_desc']);
1164 unset($_POST['idprod']);
1165 unset($_POST['units']);
1166
1167 unset($_POST['date_starthour']);
1168 unset($_POST['date_startmin']);
1169 unset($_POST['date_startsec']);
1170 unset($_POST['date_startday']);
1171 unset($_POST['date_startmonth']);
1172 unset($_POST['date_startyear']);
1173 unset($_POST['date_endhour']);
1174 unset($_POST['date_endmin']);
1175 unset($_POST['date_endsec']);
1176 unset($_POST['date_endday']);
1177 unset($_POST['date_endmonth']);
1178 unset($_POST['date_endyear']);
1179
1180 unset($_POST['situations']);
1181 unset($_POST['progress']);
1182 } else {
1183 setEventMessages($object->error, $object->errors, 'errors');
1184 }
1185 }
1186 } elseif ($action == 'updatetitleline' && GETPOSTISSET("save") && $usercancreate && !GETPOST('cancel', 'alpha')) {
1187 // Handling updating a title line for subtotals module
1188
1189 $langs->load('subtotals');
1190
1191 $desc = GETPOST('line_desc', 'alphanohtml') ?? $langs->trans("Title");
1192 $depth = GETPOSTINT('line_depth') ?? 1;
1193
1194 $subtotal_options = array();
1195
1196 foreach (Facture::$TITLE_OPTIONS as $option) {
1197 $value = GETPOST($option, 'alphanohtml');
1198 if ($value) {
1199 $subtotal_options[$option] = $value == 'on' ? 1 : $value;
1200 }
1201 }
1202
1203 // Update line
1204 $result = $object->updateSubtotalLine($langs, GETPOSTINT('lineid'), $desc, $depth, $subtotal_options);
1205
1206 if ($result >= 0) {
1207 if ($result == 0) {
1208 setEventMessages($object->error, $object->errors, 'warnings');
1209 }
1210 $ret = $object->fetch($object->id); // Reload to get new records
1211 $object->fetch_thirdparty();
1212 } else {
1213 setEventMessages($object->error, $object->errors, 'errors');
1214 }
1215 } elseif ($action == 'updatetextline' && GETPOSTISSET("save") && $usercancreate && !GETPOST('cancel', 'alpha')) {
1216 // Handling updating a text line for subtotals module
1217
1218 $langs->load('subtotals');
1219
1220 $desc = GETPOST('line_desc', 'restricthtml');
1221
1222 // Update line
1223 $result = $object->updateSubtotalLine($langs, GETPOSTINT('lineid'), $desc, 0, array());
1224
1225 if ($result >= 0) {
1226 if ($result == 0) {
1227 setEventMessages($object->error, $object->errors, 'warnings');
1228 }
1229 $ret = $object->fetch($object->id); // Reload to get new records
1230 $object->fetch_thirdparty();
1231 } else {
1232 setEventMessages($object->error, $object->errors, 'errors');
1233 }
1234 } elseif ($action == 'updatesubtotalline' && GETPOSTISSET("save") && $usercancreate && !GETPOST('cancel', 'alpha')) {
1235 // Handling updating a subtotal line for subtotals module
1236
1237 $langs->load('subtotals');
1238
1239 $desc = GETPOST('line_desc', 'alphanohtml');
1240 $depth = GETPOSTINT('line_depth');
1241
1242 $subtotal_options = array();
1243
1244 foreach (Facture::$SUBTOTAL_OPTIONS as $option) {
1245 $value = GETPOST($option, 'alphanohtml');
1246 if ($value) {
1247 $subtotal_options[$option] = $value == 'on' ? 1 : $value;
1248 }
1249 }
1250
1251 // Update line
1252 $result = $object->updateSubtotalLine($langs, GETPOSTINT('lineid'), $desc, $depth, $subtotal_options);
1253
1254 if ($result > 0) {
1255 $ret = $object->fetch($object->id); // Reload to get new records
1256 $object->fetch_thirdparty();
1257 } else {
1258 setEventMessages($object->error, $object->errors, 'errors');
1259 }
1260 }
1261}
1262
1263
1264/*
1265 * View
1266 */
1267
1268$title = $object->ref." - ".$langs->trans('Card');
1269$help_url = '';
1270
1271llxHeader('', $title, $help_url);
1272
1273$form = new Form($db);
1274$formother = new FormOther($db);
1275if (isModEnabled('project')) {
1276 $formproject = new FormProjets($db);
1277} else {
1278 $formproject = null;
1279}
1280$companystatic = new Societe($db);
1281$invoicerectmp = new FactureRec($db);
1282
1283$now = dol_now();
1284$nowlasthour = dol_get_last_hour($now);
1285
1286
1287// Create mode
1288if ($action == 'create') {
1289 print load_fiche_titre($langs->trans("CreateRepeatableInvoice"), '', 'bill');
1290
1291 $sourceInvoice = new Facture($db); // Source invoice
1292 $factureRec = new FactureRec($db);
1293 $product_static = new Product($db);
1294
1295 if ($sourceInvoice->fetch($id, $ref) > 0) {
1296 $result = $sourceInvoice->getLinesArray();
1297
1298 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
1299 print '<input type="hidden" name="token" value="'.newToken().'">';
1300 print '<input type="hidden" name="action" value="add">';
1301 print '<input type="hidden" name="facid" value="'.$sourceInvoice->id.'">';
1302
1303
1304 print dol_get_fiche_head([], '', '', 0);
1305
1306 $rowspan = 4;
1307 if (isModEnabled('project')) {
1308 $rowspan++;
1309 }
1310 if ($sourceInvoice->fk_account > 0) {
1311 $rowspan++;
1312 }
1313
1314 print '<table class="border centpercent">';
1315
1316 $sourceInvoice->fetch_thirdparty();
1317
1318 // Title
1319 print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Title").'</td><td>';
1320 print '<input class="flat quatrevingtpercent" type="text" name="title" value="'.dol_escape_htmltag(GETPOST("title", 'alphanohtml')).'" autofocus>';
1321 print '</td></tr>';
1322
1323 // Third party
1324 print '<tr><td class="titlefieldcreate">'.$langs->trans("Customer").'</td><td>'.$sourceInvoice->thirdparty->getNomUrl(1, 'customer').'</td>';
1325 print '</tr>';
1326
1327 // Invoice subtype
1328 if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED')) {
1329 print "<tr><td>".$langs->trans("InvoiceSubtype")."</td><td>";
1330 print $form->getSelectInvoiceSubtype(GETPOSTISSET('subtype') ? GETPOSTINT('subtype') : $sourceInvoice->subtype, 'subtype', 0, 0, '');
1331 print "</td></tr>";
1332 }
1333
1334 $note_public = GETPOSTISSET('note_public') ? GETPOST('note_public', 'restricthtml') : $sourceInvoice->note_public;
1335 $note_private = GETPOSTISSET('note_private') ? GETPOST('note_private', 'restricthtml') : $sourceInvoice->note_private;
1336
1337 // Help of substitution key
1338 $substitutionarray = getCommonSubstitutionArray($langs, 2, null, $sourceInvoice);
1339
1340 $substitutionarray['__INVOICE_PREVIOUS_MONTH__'] = $langs->trans("PreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($sourceInvoice->date, -1, 'm'), '%m').')';
1341 $substitutionarray['__INVOICE_MONTH__'] = $langs->trans("MonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($sourceInvoice->date, '%m').')';
1342 $substitutionarray['__INVOICE_NEXT_MONTH__'] = $langs->trans("NextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($sourceInvoice->date, 1, 'm'), '%m').')';
1343 $substitutionarray['__INVOICE_PREVIOUS_MONTH_TEXT__'] = $langs->trans("TextPreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($sourceInvoice->date, -1, 'm'), '%B').')';
1344 $substitutionarray['__INVOICE_MONTH_TEXT__'] = $langs->trans("TextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($sourceInvoice->date, '%B').')';
1345 $substitutionarray['__INVOICE_NEXT_MONTH_TEXT__'] = $langs->trans("TextNextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($sourceInvoice->date, 1, 'm'), '%B').')';
1346 $substitutionarray['__INVOICE_PREVIOUS_YEAR__'] = $langs->trans("PreviousYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($sourceInvoice->date, -1, 'y'), '%Y').')';
1347 $substitutionarray['__INVOICE_YEAR__'] = $langs->trans("YearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($sourceInvoice->date, '%Y').')';
1348 $substitutionarray['__INVOICE_NEXT_YEAR__'] = $langs->trans("NextYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($sourceInvoice->date, 1, 'y'), '%Y').')';
1349 // Only on template invoices
1350 $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_BEFORE_GEN__'] = $langs->trans("DateNextInvoiceBeforeGen").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($sourceInvoice->date, 1, 'm'), 'dayhour').')';
1351 $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_AFTER_GEN__'] = $langs->trans("DateNextInvoiceAfterGen").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($sourceInvoice->date, 2, 'm'), 'dayhour').')';
1352 $substitutionarray['__INVOICE_COUNTER_CURRENT__'] = $langs->trans("Count");
1353 $substitutionarray['__INVOICE_COUNTER_MAX__'] = $langs->trans("MaxPeriodNumber");
1354
1355 $htmltext = '<i>'.$langs->trans("FollowingConstantsWillBeSubstituted").':<br>';
1356 foreach ($substitutionarray as $key => $val) {
1357 $htmltext .= $key.' = '.$langs->trans($val).'<br>';
1358 }
1359 $htmltext .= '</i>';
1360
1361 // Author
1362 print "<tr><td>".$langs->trans("Author")."</td><td>".$user->getFullName($langs)."</td></tr>";
1363
1364 // Payment term
1365 print "<tr><td>".$langs->trans("PaymentConditions")."</td><td>";
1366 print $form->getSelectConditionsPaiements(GETPOSTISSET('cond_reglement_id') ? GETPOSTINT('cond_reglement_id') : $sourceInvoice->cond_reglement_id, 'cond_reglement_id', -1, 0, 0, '');
1367 //$form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'cond_reglement_id');
1368 print "</td></tr>";
1369
1370 // Payment mode
1371 print "<tr><td>".$langs->trans("PaymentMode")."</td><td>";
1372 print img_picto('', 'payment', 'class="pictofixedwidth"');
1373 print $form->select_types_paiements((string) (GETPOSTISSET('mode_reglement_id') ? GETPOSTINT('mode_reglement_id') : $sourceInvoice->mode_reglement_id), 'mode_reglement_id', '', 0, 1, 0, 0, 1, '', 1);
1374 //$form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->mode_reglement_id, 'mode_reglement_id', '', 1);
1375 print "</td></tr>";
1376
1377 // Customer Bank Account
1378 print "<tr><td>".$langs->trans('DebitBankAccount')."</td><td>";
1379 $defaultRibId = $sourceInvoice->thirdparty->getDefaultRib();
1380 $form->selectRib(GETPOSTISSET('accountcustomerid') ? GETPOSTINT('accountcustomerid') : $defaultRibId, 'accountcustomerid', '(fk_soc:=:'.$sourceInvoice->socid.")", 1, '', 1);
1381 print "</td></tr>";
1382
1383 print '<script>
1384 $(document).ready(function() {
1385 if($("#selectmode_reglement_id option:selected").data("code") != "' . $factureRec::PAYMENTCODETOEDITSOCIETERIB . '") {
1386 hideselectfksocieterib();
1387 }
1388 $("#selectmode_reglement_id").change(function() {
1389 if($("#selectmode_reglement_id option:selected").data("code") != "'. $factureRec::PAYMENTCODETOEDITSOCIETERIB .'") {
1390 hideselectfksocieterib(1);
1391 } else {
1392 showselectfksocieterib();
1393 }
1394 });
1395 });
1396
1397 function hideselectfksocieterib(empty = 0){
1398 $("#selectaccountcustomerid").closest("tr").hide();
1399 if(empty == 1){
1400 $("#selectaccountcustomerid").val("-1").change();
1401 }
1402 }
1403
1404 function showselectfksocieterib(){
1405 $("#selectaccountcustomerid").closest("tr").show();
1406 }
1407 </script>';
1408
1409 // Bank account
1410 if ($sourceInvoice->fk_account > 0) {
1411 print "<tr><td>".$langs->trans('BankAccount')."</td><td>";
1412 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$sourceInvoice->id, (string) $sourceInvoice->fk_account, 'none');
1413 print "</td></tr>";
1414 }
1415
1416 // Rule for lines dates
1417 if (getDolGlobalInt("FACTUREREC_SUPPORT_RULE_FOR_LINES")) {
1418 print "<tr><td>".$langs->trans("RuleForLinesDates")."</td><td>";
1419 print $form->getSelectRuleForLinesDates(GETPOSTISSET('rule_for_lines_dates') ? GETPOST('rule_for_lines_dates', 'alpha') : $factureRec->rule_for_lines_dates);
1420 print "</td></tr>";
1421 }
1422
1423 //extrafields
1424 $draft = new Facture($db);
1425 $draft->fetch(GETPOSTINT('facid'));
1426
1427 $extralabels = $extrafields->fetch_name_optionals_label($draft->table_element);
1428 if ($draft->fetch_optionals() > 0) {
1429 $sourceInvoice->array_options = array_merge($sourceInvoice->array_options, $draft->array_options);
1430 }
1431
1432 print $sourceInvoice->showOptionals($extrafields, 'create', $parameters);
1433
1434 // Project
1435 if (isModEnabled('project') && is_object($sourceInvoice->thirdparty) && $sourceInvoice->thirdparty->id > 0 && is_object($formproject)) {
1436 $projectid = GETPOST('projectid') ? GETPOST('projectid') : $sourceInvoice->fk_project;
1437 $langs->load('projects');
1438 print '<tr><td>'.$langs->trans('Project').'</td><td>';
1439 print img_picto('', 'project', 'class="pictofixedwidth"');
1440 $numprojet = $formproject->select_projects($sourceInvoice->thirdparty->id, $projectid, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, '');
1441 print ' &nbsp; <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.$sourceInvoice->thirdparty->id.'&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create&socid='.$sourceInvoice->thirdparty->id.(!empty($id) ? '&id='.$id : '')).'">'.img_object($langs->trans("AddProject"), 'add').'</a>';
1442 print '</td></tr>';
1443 }
1444
1445 // Model pdf
1446 print "<tr><td>".$langs->trans('Model')."</td><td>";
1447 include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
1449 print img_picto('', 'generic', 'class="pictofixedwidth"');
1450 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
1451 print $form->selectarray('modelpdf', $list, $conf->global->FACTURE_ADDON_PDF);
1452 print "</td></tr>";
1453
1454 // Public note
1455 print '<tr>';
1456 print '<td class="tdtop">';
1457 print $form->textwithpicto($langs->trans('NotePublic'), $htmltext, 1, 'help', '', 0, 2, 'notepublic');
1458 print '</td>';
1459 print '<td>';
1460 $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%');
1461 print $doleditor->Create(1);
1462
1463 // Private note
1464 if (empty($user->socid)) {
1465 print '<tr>';
1466 print '<td class="tdtop">';
1467 print $form->textwithpicto($langs->trans('NotePrivate'), $htmltext, 1, 'help', '', 0, 2, 'noteprivate');
1468 print '</td>';
1469 print '<td>';
1470 $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%');
1471 print $doleditor->Create(1);
1472 // print '<textarea name="note_private" wrap="soft" cols="70" rows="'.ROWS_3.'">'.$note_private.'.</textarea>
1473 print '</td></tr>';
1474 }
1475
1476 print "</table>";
1477
1478 print dol_get_fiche_end();
1479
1480 // Autogeneration
1481 $title = $langs->trans("Recurrence");
1482 print load_fiche_titre(img_picto('', 'recurring', 'class="pictofixedwidth"').$title, '', '');
1483
1484 print '<span class="opacitymedium">'.$langs->trans("ToCreateARecurringInvoiceGeneAuto", $langs->transnoentitiesnoconv('Module2300Name')).'</span><br><br>';
1485
1486 print dol_get_fiche_head([], '', '', 0);
1487
1488 print '<table class="border centpercent">';
1489
1490 // Frequency + unit
1491 print '<tr><td class="titlefieldcreate">'.$form->textwithpicto($langs->trans("Frequency"), $langs->transnoentitiesnoconv('toolTipFrequency'))."</td><td>";
1492 print '<input type="text" class="width50" name="frequency" value="'.GETPOST('frequency', 'int').'">&nbsp;';
1493 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'));
1494 print "</td></tr>";
1495
1496 // Date next run
1497 print "<tr><td>".$form->textwithpicto($langs->trans('NextDateToExecution'), $langs->trans("NextDateToExecutionHelp"))."</td><td>";
1498 $date_next_execution = isset($date_next_execution) ? $date_next_execution : (GETPOSTINT('remonth') ? dol_mktime(12, 0, 0, GETPOSTINT('remonth'), GETPOSTINT('reday'), GETPOSTINT('reyear')) : -1);
1499 print $form->selectDate($date_next_execution, '', 1, 1, 0, "add", 1, 1);
1500 print "</td></tr>";
1501
1502 // Number max of generation
1503 print "<tr><td>".$langs->trans("MaxPeriodNumber")."</td><td>";
1504 print '<input type="text" class="width50" name="nb_gen_max" value="'.GETPOSTINT('nb_gen_max').'">';
1505 print "</td></tr>";
1506
1507 // Auto validate the invoice
1508 print "<tr><td>".$langs->trans("StatusOfAutoGeneratedInvoices")."</td><td>";
1509 $select = array('0' => $langs->trans('BillStatusDraft'), '1' => $langs->trans('BillStatusValidated'), '2' => $langs->trans('BillStatusValidatedWithSendind'));
1510 print $form->selectarray('auto_validate', $select, GETPOSTINT('auto_validate'));
1511 print "</td></tr>";
1512
1513 // Email template for auto sending invoices
1514 print "<tr id='col_auto_send_model_mail' class='".(GETPOSTINT('auto_validate') != 2 ? 'hidden' : '')."'><td>" . $langs->trans("EmailTemplateForAutoSend") . "</td><td>";
1515 print $form->selectModelMail("auto_send_", "facture_send", 1, 0, GETPOSTINT('auto_send_model_mail'));
1516 print "</td></tr>";
1517 print " <script>
1518 $(document).ready(function() {
1519 $('#auto_validate').on('change', function () {
1520 if(+$(this).val() === 2) {
1521 $('#col_auto_send_model_mail').show();
1522 } else {
1523 $('#col_auto_send_model_mail').hide();
1524 $('#select_auto_send_model_mail').val(0);
1525 }
1526 });
1527 });
1528 </script>";
1529
1530 // Auto generate document
1531 if (getDolGlobalString('INVOICE_REC_CAN_DISABLE_DOCUMENT_FILE_GENERATION')) {
1532 print "<tr><td>".$langs->trans("StatusOfGeneratedDocuments")."</td><td>";
1533 $select = array('0' => $langs->trans('DoNotGenerateDoc'), '1' => $langs->trans('AutoGenerateDoc'));
1534 print $form->selectarray('generate_pdf', $select, GETPOSTINT('generate_pdf'));
1535 print "</td></tr>";
1536 } else {
1537 print '<input type="hidden" name="generate_pdf" value="1">';
1538 }
1539
1540 print "</table>";
1541
1542 print dol_get_fiche_end();
1543
1544
1545 $title = $langs->trans("ProductsAndServices");
1546 if (!isModEnabled('service')) {
1547 $title = $langs->trans("Products");
1548 } elseif (!isModEnabled('product')) {
1549 $title = $langs->trans("Services");
1550 }
1551
1552 print load_fiche_titre($title, '', '');
1553
1554 /*
1555 * Invoice lines
1556 */
1557 print '<div class="div-table-responsive-no-min">';
1558 print '<table id="tablelines" class="noborder noshadow centpercent nomarginbottom">';
1559
1560 // Show object lines
1561 if (!empty($sourceInvoice->lines)) {
1562 $sourceInvoice->printOriginLinesList('', $selectedLines);
1563 }
1564
1565 print "</table>\n";
1566 print '<div>';
1567
1568 print '</td></tr>';
1569
1570 $flag_price_may_change = getDolGlobalString('INVOICE_REC_PRICE_MAY_CHANGE');
1571 if (!empty($flag_price_may_change)) {
1572 print '<tr><td colspan="3" class="left">';
1573 print '<select name="usenewprice" class="flat">';
1574 print '<option value="0">'.$langs->trans("AlwaysUseFixedPrice").'</option>';
1575 print '<option value="1" disabled>'.$langs->trans("AlwaysUseNewPrice").'</option>';
1576 print '</select>';
1577 print '</td></tr>';
1578 }
1579 print "</table>\n";
1580
1581 print '<br>';
1582
1583 print $form->buttonsSaveCancel("Create");
1584
1585 print "</form>\n";
1586 } else {
1587 dol_print_error(null, "Error, no invoice ".$sourceInvoice->id);
1588 }
1589} else {
1590 // View mode
1591 if ($object->id > 0) {
1592 $object->fetch_thirdparty();
1593
1594 $formconfirm = '';
1595 // Confirmation of deletion of product line
1596 if ($action == 'ask_deleteline') {
1597 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1);
1598 }
1599 // Confirm delete of repeatable invoice
1600 if ($action == 'delete') {
1601 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteRepeatableInvoice'), $langs->trans('ConfirmDeleteRepeatableInvoice'), 'confirm_delete', '', 'no', 1);
1602 }
1603 // Confirmation of deletion of the subtotal line
1604 if ($action == 'ask_subtotal_deleteline') {
1605 $langs->load("subtotals");
1606 $title = "DeleteSubtotalLine";
1607 $question = "ConfirmDeleteSubtotalLine";
1608 if (GETPOST('type') == 'title') {
1609 $formconfirm = array(array('type' => 'checkbox', 'name' => 'deletecorrespondingsubtotalline', 'label' => $langs->trans("DeleteCorrespondingSubtotalLine"), 'value' => 0));
1610 $title = "DeleteTitleLine";
1611 $question = "ConfirmDeleteTitleLine";
1612 }
1613 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans($title), $langs->trans($question), 'confirm_delete_subtotalline', $formconfirm, 'no', 1);
1614 }
1615
1616 // Subtotal line form
1617 if ($action == 'add_title_line') {
1618 $langs->load('subtotals');
1619 $type = 'title';
1620 $depth_array = $object->getPossibleLevels($langs);
1621 require dol_buildpath('/core/tpl/subtotal_create.tpl.php');
1622 } elseif ($action == 'add_subtotal_line') {
1623 $langs->load('subtotals');
1624 $type = 'subtotal';
1625 $titles = $object->getPossibleTitles();
1626 require dol_buildpath('/core/tpl/subtotal_create.tpl.php');
1627 } elseif ($action == 'add_text_line') {
1628 $langs->load('subtotals');
1629 $type = 'text';
1630 require dol_buildpath('/core/tpl/subtotal_create.tpl.php');
1631 }
1632
1633 // Call Hook formConfirm
1634 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
1635 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1636 if (empty($reshook)) {
1637 $formconfirm .= $hookmanager->resPrint;
1638 } elseif ($reshook > 0) {
1639 $formconfirm = $hookmanager->resPrint;
1640 }
1641
1642 print $formconfirm;
1643
1644 $author = new User($db);
1645 $author->fetch($object->user_creation_id);
1646
1647 $head = invoice_rec_prepare_head($object);
1648
1649 print dol_get_fiche_head($head, 'card', $langs->trans("RepeatableInvoice"), -1, $object->picto); // Add a div
1650
1651 // Recurring invoice content
1652
1653 $linkback = '<a href="'.DOL_URL_ROOT.'/compta/facture/invoicetemplate_list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
1654
1655 $morehtmlref = '';
1656 if ($action != 'editref') {
1657 $morehtmlref .= $form->editfieldkey($object->ref, 'ref', $object->ref, $object, $user->hasRight('facture', 'creer'), '', '', 0, 2);
1658 } else {
1659 $morehtmlref .= $form->editfieldval('', 'ref', $object->ref, $object, $user->hasRight('facture', 'creer'), 'string');
1660 }
1661
1662 $morehtmlref .= '<div class="refidno">';
1663 // Ref customer
1664 //$morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_customer, $object, $user->hasRight('facture', 'creer'), 'string', '', 0, 1);
1665 //$morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_customer, $object, $user->hasRight('facture', 'creer'), 'string', '', null, null, '', 1);
1666 // Thirdparty
1667 $morehtmlref .= $object->thirdparty->getNomUrl(1, 'customer');
1668 // Project
1669 if (isModEnabled('project')) {
1670 $langs->load("projects");
1671 $morehtmlref .= '<br>';
1672 if ($user->hasRight('facture', 'creer')) {
1673 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
1674 if ($action != 'classify') {
1675 $morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
1676 }
1677 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
1678 } else {
1679 if (!empty($object->fk_project)) {
1680 $proj = new Project($db);
1681 $proj->fetch($object->fk_project);
1682 $morehtmlref .= ' : '.$proj->getNomUrl(1);
1683 if ($proj->title) {
1684 $morehtmlref .= ' - '.$proj->title;
1685 }
1686 } else {
1687 $morehtmlref .= '';
1688 }
1689 }
1690 }
1691 $morehtmlref .= '</div>';
1692
1693 $morehtmlstatus = '';
1694
1695 dol_banner_tab($object, 'ref', $linkback, 1, 'title', 'none', $morehtmlref, '', 0, '', $morehtmlstatus);
1696
1697 print '<div class="fichecenter">';
1698 print '<div class="fichehalfleft">';
1699 print '<div class="underbanner clearboth"></div>';
1700
1701 print '<table class="border centpercent tableforfield">';
1702
1703 // Invoice subtype
1704 if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED')) {
1705 print "<tr><td>".$langs->trans("InvoiceSubtype")."</td><td>";
1706 if ($object->subtype > 0) {
1707 print $object->getSubtypeLabel('facture_rec');
1708 }
1709 print "</td></tr>";
1710 }
1711
1712 // Author
1713 print '<tr><td class="titlefieldmiddle">'.$langs->trans("Author").'</td><td>';
1714 print $author->getNomUrl(-1);
1715 print "</td></tr>";
1716
1717 // Payment term
1718 print '<tr><td>';
1719 print '<table class="nobordernopadding centpercent"><tr><td>';
1720 print $langs->trans('PaymentConditionsShort');
1721 print '</td>';
1722 if ($action != 'editconditions' && $user->hasRight('facture', 'creer')) {
1723 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>';
1724 }
1725 print '</tr></table>';
1726 print '</td><td>';
1727 if ($action == 'editconditions') {
1728 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, (string) $object->cond_reglement_id, 'cond_reglement_id');
1729 } else {
1730 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, (string) $object->cond_reglement_id, 'none');
1731 }
1732 print '</td></tr>';
1733
1734 // Payment mode
1735 print '<tr><td>';
1736 print '<table class="nobordernopadding" width="100%"><tr><td>';
1737 print $langs->trans('PaymentMode');
1738 print '</td>';
1739 if ($action != 'editmode' && $user->hasRight('facture', 'creer')) {
1740 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>';
1741 }
1742 print '</tr></table>';
1743 print '</td><td>';
1744 if ($action == 'editmode') {
1745 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, (string) $object->mode_reglement_id, 'mode_reglement_id', 'CRDT', 1, 1);
1746 } else {
1747 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, (string) $object->mode_reglement_id, 'none');
1748 }
1749 print '</td></tr>';
1750
1751
1752 // Bank Account Customer
1753 if ($object->mode_reglement_code == $object::PAYMENTCODETOEDITSOCIETERIB) {
1754 print '<tr><td class="nowrap">';
1755 print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
1756 print $langs->trans('DebitBankAccount');
1757 print '<td>';
1758
1759 if (($action != 'editbankaccountcustomer') && $user->hasRight('facture', 'creer') && $object->statut == FactureRec::STATUS_DRAFT) {
1760 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>';
1761 }
1762 print '</tr></table>';
1763 print '</td><td>';
1764
1765 if ($action == 'editbankaccountcustomer') {
1766 $form->formRib($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->fk_societe_rib, 'accountcustomerid', 'fk_soc='.$object->socid, 1, 1);
1767 } else {
1768 $form->formRib($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->fk_societe_rib, 'none', '', 0, 1);
1769 }
1770 print "</td>";
1771 print '</tr>';
1772 }
1773
1774 // Bank Account
1775 print '<tr><td class="nowrap">';
1776 print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
1777 print $langs->trans('BankAccount');
1778 print '<td>';
1779 if (($action != 'editbankaccount') && $user->hasRight('facture', 'creer') && $object->statut == FactureRec::STATUS_DRAFT) {
1780 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>';
1781 }
1782 print '</tr></table>';
1783 print '</td><td>';
1784 if ($action == 'editbankaccount') {
1785 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'fk_account', 1);
1786 } else {
1787 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'none');
1788 }
1789 print "</td>";
1790 print '</tr>';
1791
1792 // Rule for line date. Need a hidden const as this generate unexpected dates into substitution variables
1793 if (getDolGlobalInt("FACTUREREC_SUPPORT_RULE_FOR_LINES")) {
1794 print '<tr><td>';
1795 print '<table class="nobordernopadding centpercent"><tr><td>';
1796 print $langs->trans('RuleForLinesDates');
1797 print '</td>';
1798 if ($action != 'editruleforlinesdates' && $user->hasRight('facture', 'creer')) {
1799 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editruleforlinesdates&token='.newToken().'&facid='.$object->id.'">'.img_edit($langs->trans('SetRuleForLinesDates'), 1).'</a></td>';
1800 }
1801 print '</tr></table>';
1802 print '</td><td>';
1803 if ($action == 'editruleforlinesdates') {
1804 $form->form_rule_for_lines_dates($_SERVER['PHP_SELF'].'?facid='.$object->id, $object->rule_for_lines_dates, 'rule_for_lines_dates');
1805 } else {
1806 $form->form_rule_for_lines_dates($_SERVER['PHP_SELF'].'?facid='.$object->id, $object->rule_for_lines_dates, 'none');
1807 }
1808 print '</td></tr>';
1809 }
1810
1811 // Extrafields
1812 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1813
1814 // Model pdf
1815 print '<tr><td class="nowrap">';
1816 print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
1817 print $langs->trans('Model');
1818 print '<td>';
1819 if (($action != 'editmodelpdf') && $user->hasRight('facture', 'creer') && $object->statut == FactureRec::STATUS_DRAFT) {
1820 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>';
1821 }
1822 print '</tr></table>';
1823 print '</td><td>';
1824 if ($action == 'editmodelpdf') {
1825 include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
1826 $list = array();
1828 foreach ($models as $k => $model) {
1829 $list[] = str_replace(':', '|', $k).':'.$model;
1830 }
1831 $select = 'select;'.implode(',', $list);
1832 print $form->editfieldval($langs->trans("Model"), 'modelpdf', $object->model_pdf, $object, $user->hasRight('facture', 'creer'), $select);
1833 } else {
1834 print $object->model_pdf;
1835 }
1836 print "</td>";
1837 print '</tr>';
1838
1839 // Other attributes
1840 $cols = 2;
1841
1842
1843 print '</table>';
1844
1845 print '</div>';
1846 print '<div class="fichehalfright">';
1847
1848 print '<!-- amounts -->'."\n";
1849 print '<div class="underbanner clearboth"></div>'."\n";
1850
1851 // Recurrence
1852 $title = $langs->trans("Recurrence");
1853
1854 print '<table class="border tableforfield centpercent">';
1855
1856 include DOL_DOCUMENT_ROOT.'/core/tpl/object_currency_amount.tpl.php';
1857
1858 $sign = 1;
1859 if (getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE_SCREEN') && $object->type == $object::TYPE_CREDIT_NOTE) {
1860 $sign = -1; // We invert sign for output
1861 }
1862
1863 // Amount (excl. tax)
1864 print '<tr><td class="titlefieldmiddle">'.$langs->trans("AmountHT").'</td>';
1865 print '<td class="nowraponall amountcard right">'.price($sign * $object->total_ht, 0, $langs, 1, -1, -1, $conf->currency).'</td>';
1866 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
1867 // Multicurrency Amount HT
1868 print '<td class="nowraponall amountcard right">' . price($sign * $object->multicurrency_total_ht, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
1869 }
1870 print '</tr>';
1871
1872 // Amount tax
1873 print '<tr><td>'.$langs->trans("AmountVAT").'</td>';
1874 print '<td class="nowrap amountcard right">'.price($sign * $object->total_tva, 0, $langs, 1, -1, -1, $conf->currency).'</td>';
1875 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
1876 // Multicurrency Amount VAT
1877 print '<td class="nowraponall amountcard right">' . price($sign * $object->multicurrency_total_tva, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
1878 }
1879 print '</tr>';
1880
1881 // Amount Local Taxes
1882 if (($mysoc->localtax1_assuj == "1" && $mysoc->useLocalTax(1)) || $object->total_localtax1 != 0) { // Localtax1
1883 print '<tr>';
1884 print '<td class="titlefieldmiddle">'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td>';
1885 print '<td class="nowraponall amountcard right">'.price($sign * $object->total_localtax1, 1, '', 1, - 1, - 1, $conf->currency).'</td></tr>';
1886 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
1887 $object->multicurrency_total_localtax1 = (float) price2num($object->total_localtax1 * $object->multicurrency_tx, 'MT');
1888
1889 print '<td class="nowraponall amountcard right">' . price($sign * $object->multicurrency_total_localtax1, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
1890 }
1891 print '</tr>';
1892 }
1893
1894 if (($mysoc->localtax2_assuj == "1" && $mysoc->useLocalTax(2)) || $object->total_localtax2 != 0) { // Localtax2
1895 print '<tr>';
1896 print '<td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td>';
1897 print '<td class=nowraponall amountcard right">'.price($sign * $object->total_localtax2, 1, '', 1, - 1, - 1, $conf->currency).'</td></tr>';
1898 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
1899 $object->multicurrency_total_localtax2 = (float) price2num($object->total_localtax2 * $object->multicurrency_tx, 'MT');
1900
1901 print '<td class="nowraponall amountcard right">' . price($sign * $object->multicurrency_total_localtax2, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
1902 }
1903 print '</tr>';
1904 }
1905
1906 // Add the revenue stamp
1907 /*
1908 if ($selleruserevenustamp) {
1909 print '<tr><td class="titlefieldmiddle">';
1910 print '<table class="nobordernopadding centpercent"><tr><td>';
1911 print $langs->trans('RevenueStamp');
1912 print '</td>';
1913 if ($action != 'editrevenuestamp' && $object->status == $object::STATUS_DRAFT && $usercancreate) {
1914 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editrevenuestamp&token='.newToken().'&facid='.$object->id.'">'.img_edit($langs->trans('SetRevenuStamp'), 1).'</a></td>';
1915 }
1916 print '</tr></table>';
1917 print '</td><td class="nowrap amountcard right">';
1918 if ($action == 'editrevenuestamp') {
1919 print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
1920 print '<input type="hidden" name="token" value="'.newToken().'">';
1921 print '<input type="hidden" name="action" value="setrevenuestamp">';
1922 print '<input type="hidden" name="revenuestamp" id="revenuestamp_val" value="'.price2num($object->revenuestamp).'">';
1923 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
1924 print $formother->select_revenue_stamp('', 'revenuestamp_type', $mysoc->country_code);
1925 print ' &rarr; <span id="revenuestamp_span"></span>';
1926 print ' <input type="submit" class="button buttongen button-save small" value="'.$langs->trans('Modify').'">';
1927 print '</form>';
1928 print " <script>
1929 $(document).ready(function(){
1930 js_recalculate_revenuestamp();
1931 $('select[name=revenuestamp_type]').on('change',function(){
1932 js_recalculate_revenuestamp();
1933 });
1934 });
1935 function js_recalculate_revenuestamp(){
1936 var valselected = $('select[name=revenuestamp_type]').val();
1937 console.log('Calculate revenue stamp from '+valselected);
1938 var revenue = 0;
1939 if (valselected.indexOf('%') == -1)
1940 {
1941 revenue = valselected;
1942 }
1943 else
1944 {
1945 var revenue_type = parseFloat(valselected);
1946 var amount_net = ".round($object->total_ht, 2).";
1947 revenue = revenue_type * amount_net / 100;
1948 revenue = revenue.toFixed(2);
1949 }
1950 $('#revenuestamp_val').val(revenue);
1951 $('#revenuestamp_span').html(revenue);
1952 }
1953 </script>";
1954 } else {
1955 print price($object->revenuestamp, 1, '', 1, -1, -1, $conf->currency);
1956 }
1957 print '</td></tr>';
1958 }
1959 */
1960
1961 // Amount TTC
1962 print '<tr><td>'.$langs->trans("AmountTTC").'</td><td class="nowraponall amountcard right">'.price($sign * $object->total_ttc, 0, $langs, 1, -1, -1, $conf->currency).'</td>';
1963 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
1964 // Multicurrency Amount TTC
1965 print '<td class="nowrap amountcard right">' . price($sign * $object->multicurrency_total_ttc, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
1966 }
1967 print '</tr>';
1968
1969 // Recurring info
1970 print '<tr class="liste_titre"><td class="liste_titre">'.img_picto('', 'recurring', 'class="pictofixedwidth"').$title.'</td>';
1971 print '<td></td>';
1972 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
1973 print '<td></td>';
1974 }
1975 print '</tr>';
1976
1977 // if "frequency" is empty or = 0, the recurrence is disabled
1978 print '<tr><td style="width: 50%">';
1979 print '<table class="nobordernopadding" width="100%"><tr><td>';
1980 print $langs->trans('Frequency');
1981 print '</td>';
1982 if ($action != 'editfrequency' && $user->hasRight('facture', 'creer')) {
1983 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>';
1984 }
1985 print '</tr></table>';
1986 print '</td><td>';
1987 if ($action == 'editfrequency') {
1988 print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'">';
1989 print '<input type="hidden" name="action" value="setfrequency">';
1990 print '<input type="hidden" name="token" value="'.newToken().'">';
1991 print '<table class="nobordernopadding">';
1992 print '<tr><td>';
1993 print '<input type="text" name="frequency" class="width50 marginrightonly right" value="'.$object->frequency.'">';
1994 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'));
1995 print '</td>';
1996 print '<td class="left"><input type="submit" class="button button-edit smallpaddingimp" value="'.$langs->trans("Modify").'"></td>';
1997 print '</tr></table></form>';
1998 } else {
1999 if ($object->frequency > 0) {
2000 print $langs->trans('FrequencyPer_'.$object->unit_frequency, $object->frequency);
2001 } else {
2002 print '<span class="opacitymedium">'.$langs->trans("NotARecurringInvoiceTemplate").'</span>';
2003 }
2004 }
2005 print '</td>';
2006 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2007 print '<td></td>';
2008 }
2009 print '</tr>';
2010
2011 if ($object->frequency > 0) {
2012 // Date when (next invoice generation)
2013 print '<tr><td>';
2014 if ($action == 'date_when' || $object->frequency > 0) {
2015 print $form->editfieldkey($form->textwithpicto($langs->trans("NextDateToExecution"), $langs->trans("NextDateToExecutionHelp")), 'date_when', $object->date_when, $object, $user->hasRight('facture', 'creer'), 'day');
2016 } else {
2017 print $form->textwithpicto($langs->trans("NextDateToExecution"), $langs->trans("NextDateToExecutionHelp"));
2018 }
2019 print '</td><td>';
2020 if ($action == 'date_when' || $object->frequency > 0) {
2021 print $form->editfieldval($langs->trans("NextDateToExecution"), 'date_when', $object->date_when, $object, $user->hasRight('facture', 'creer'), 'day', $object->date_when, null, '', '', 0, 'strikeIfMaxNbGenReached');
2022 }
2023 //var_dump(dol_print_date($object->date_when+60, 'dayhour').' - '.dol_print_date($now, 'dayhour'));
2024 if (!$object->isMaxNbGenReached()) {
2025 if (!$object->suspended && $action != 'editdate_when' && $object->frequency > 0 && $object->date_when && $object->date_when < $now) {
2026 print img_warning($langs->trans("Late"));
2027 }
2028 } else {
2029 print img_info($langs->trans("MaxNumberOfGenerationReached"));
2030 }
2031 print '</td>';
2032 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2033 print '<td></td>';
2034 }
2035 print '</tr>';
2036
2037 // Max period / Rest period
2038 print '<tr><td>';
2039 if ($action == 'nb_gen_max' || $object->frequency > 0) {
2040 print $form->editfieldkey($langs->trans("MaxPeriodNumber"), 'nb_gen_max', (string) $object->nb_gen_max, $object, $user->hasRight('facture', 'creer'));
2041 } else {
2042 print $langs->trans("MaxPeriodNumber");
2043 }
2044 print '</td><td>';
2045 if ($action == 'nb_gen_max' || $object->frequency > 0) {
2046 print $form->editfieldval($langs->trans("MaxPeriodNumber"), 'nb_gen_max', $object->nb_gen_max ? $object->nb_gen_max : '', $object, $user->hasRight('facture', 'creer'));
2047 } else {
2048 print '';
2049 }
2050 print '</td>';
2051 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2052 print '<td></td>';
2053 }
2054 print '</tr>';
2055
2056 // Status of auto generated invoices
2057 print '<tr><td>';
2058 if ($action == 'auto_validate' || $object->frequency > 0) {
2059 print $form->editfieldkey($langs->trans("StatusOfAutoGeneratedInvoices"), 'auto_validate', (string) $object->auto_validate, $object, $user->hasRight('facture', 'creer'));
2060 } else {
2061 print $langs->trans("StatusOfAutoGeneratedInvoices");
2062 }
2063 print '</td><td>';
2064 $select = 'select;0:' . $langs->trans('BillStatusDraft') . ',1:' . $langs->trans('BillStatusValidated') . ',2:' . $langs->trans('BillStatusValidatedWithSendind');
2065 if ($action == 'auto_validate' || $object->frequency > 0) {
2066 print $form->editfieldval($langs->trans("StatusOfAutoGeneratedInvoices"), 'auto_validate', $object->auto_validate, $object, $user->hasRight('facture', 'creer'), $select);
2067 }
2068 print '</td>';
2069 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2070 print '<td></td>';
2071 }
2072 print '</tr>';
2073
2074 // Email template for auto sending invoices
2075 if ($object->frequency > 0 && $object->auto_validate == 2) {
2076 print '<tr><td style="width: 50%">';
2077 print '<table class="nobordernopadding" width="100%"><tr><td>';
2078 print $langs->trans("EmailTemplateForAutoSend");
2079 print '</td>';
2080 if ($action != 'editEmailTemplate' && $user->hasRight('facture', 'creer')) {
2081 print '<td class="right"><a class="editfielda" href="' . $_SERVER["PHP_SELF"] . '?action=editEmailTemplate&token=' . newToken() . '&facid=' . $object->id . '">' . img_edit($langs->trans('Edit'), 1) . '</a></td>';
2082 }
2083 print '</tr></table>';
2084 print '</td><td>';
2085
2086 if ($action == 'editEmailTemplate') {
2087 // Edit
2088 print '<form method="POST" action="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '">';
2089 print '<input type="hidden" name="token" value="' . newToken() . '">';
2090 print '<input type="hidden" name="action" value="setEmailTemplate">';
2091 print $form->selectModelMail("auto_send_", "facture_send", 1, 0, $object->fk_email_template);
2092 print '<input type="submit" class="button valignmiddle smallpaddingimp" name="modify" value="' . $langs->trans("Modify") . '">';
2093 print '<input type="submit" class="button button-cancel valignmiddle smallpaddingimp" name="cancel" value="' . $langs->trans("Cancel") . '">';
2094 print '</form>';
2095 } else {
2096 // Show
2097 if (!empty($object->fk_email_template)) {
2098 $sql = "SELECT label
2099 FROM ".$db->prefix()."c_email_templates
2100 WHERE rowid = ".((int) $object->fk_email_template);
2101 $result = $db->query($sql);
2102 if ($result) {
2103 if ($obj = $db->fetch_object($result)) {
2104 print $obj->label;
2105 }
2106 }
2107 } else {
2108 print $langs->trans('DefaultMailModel');
2109 }
2110 }
2111
2112 print '</td>';
2113 print '</tr>';
2114 }
2115
2116 // Auto generate documents
2117 if (getDolGlobalString('INVOICE_REC_CAN_DISABLE_DOCUMENT_FILE_GENERATION')) {
2118 print '<tr>';
2119 print '<td>';
2120 if ($action == 'generate_pdf' || $object->frequency > 0) {
2121 print $form->editfieldkey($langs->trans("StatusOfGeneratedDocuments"), 'generate_pdf', (string) $object->generate_pdf, $object, $user->hasRight('facture', 'creer'));
2122 } else {
2123 print $langs->trans("StatusOfGeneratedDocuments");
2124 }
2125 print '</td>';
2126 print '<td>';
2127 $select = 'select;0:'.$langs->trans('DoNotGenerateDoc').',1:'.$langs->trans('AutogenerateDoc');
2128 if ($action == 'generate_pdf' || $object->frequency > 0) {
2129 print $form->editfieldval($langs->trans("StatusOfGeneratedDocuments"), 'generate_pdf', $object->generate_pdf, $object, $user->hasRight('facture', 'creer'), $select);
2130 }
2131 print '</td>';
2132 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2133 print '<td></td>';
2134 }
2135 print '</tr>';
2136 } else {
2137 print '<input type="hidden" name="generate_pdf" value="1">';
2138 }
2139 }
2140
2141 print '</table>';
2142
2143 // Frequencry/Recurring section
2144 if ($object->frequency > 0) {
2145 print '<br>';
2146
2147 if (!isModEnabled('cron')) {
2148 print info_admin($langs->trans("EnableAndSetupModuleCron", $langs->transnoentitiesnoconv("Module2300Name")));
2149 }
2150
2151 print '<div class="underbanner clearboth"></div>';
2152 print '<table class="border centpercent tableforfield">';
2153
2154 // Nb of generation already done
2155 print '<tr><td style="width: 50%">'.$langs->trans("NbOfGenerationDone").'</td>';
2156 print '<td>';
2157 print $object->nb_gen_done ? $object->nb_gen_done : '0';
2158 print '</td>';
2159 print '</tr>';
2160
2161 // Date last
2162 print '<tr><td>';
2163 print $langs->trans("DateLastGeneration");
2164 print '</td><td>';
2165 print dol_print_date($object->date_last_gen, 'dayhour');
2166 print '</td>';
2167 print '</tr>';
2168
2169 print '</table>';
2170
2171 print '<br>';
2172 }
2173
2174 print '</div>';
2175 print '</div>';
2176
2177 print '<div class="clearboth"></div><br>';
2178
2179
2180 // Lines
2181 print '<form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '#add' : '#line_'.GETPOSTINT('lineid')).'" method="POST">';
2182 print '<input type="hidden" name="token" value="' . newToken().'">';
2183 print '<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">';
2184 print '<input type="hidden" name="mode" value="">';
2185 print '<input type="hidden" name="id" value="' . $object->id.'">';
2186 print '<input type="hidden" name="page_y" value="">';
2187
2188 if (!empty($conf->use_javascript_ajax) && $object->statut == 0) {
2189 if (isModEnabled('subtotals')) {
2190 include DOL_DOCUMENT_ROOT.'/core/tpl/subtotal_ajaxrow.tpl.php';
2191 } else {
2192 include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
2193 }
2194 }
2195
2196 print '<div class="div-table-responsive-no-min">';
2197 print '<table id="tablelines" class="noborder noshadow centpercent nomarginbottom">';
2198 // Show object lines
2199 if (!empty($object->lines)) {
2200 $canchangeproduct = 1;
2201 $object->printObjectLines($action, $mysoc, $object->thirdparty, $lineid, 0); // No date selector for template invoice
2202 }
2203
2204 // Form to add new line
2205 if ($object->status == $object::STATUS_DRAFT && $user->hasRight('facture', 'creer') && $action != 'valid' && $action != 'editline') {
2206 if ($action != 'editline') {
2207 // Add free products/services
2208
2209 $parameters = array();
2210 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2211 if ($reshook < 0) {
2212 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2213 }
2214 if (empty($reshook)) {
2215 $object->formAddObjectLine(0, $mysoc, $object->thirdparty);
2216 } // No date selector for template invoice
2217 }
2218 }
2219
2220 print "</table>\n";
2221 print '</div>';
2222
2223 print "</form>\n";
2224
2225 print dol_get_fiche_end();
2226
2227
2228 /*
2229 * Action bar
2230 */
2231 print '<div class="tabsAction">';
2232
2233 $parameters = array();
2234 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2235 if (empty($reshook)) {
2236 $params = array(
2237 'attr' => array(
2238 'class' => 'classfortooltip',
2239 ),
2240 );
2241
2242 // Subtotal
2243 if (empty($object->suspended) && isModEnabled('subtotals')
2244 && (getDolGlobalInt('SUBTOTAL_TITLE_'.strtoupper($object->element)) || getDolGlobalInt('SUBTOTAL_'.strtoupper($object->element)) || getDolGlobalInt('SUBTOTAL_TEXT_'.strtoupper($object->element)))) {
2245 $langs->load("subtotals");
2246
2247 $url_button = array();
2248
2249 $url_button[] = array(
2250 'lang' => 'subtotals',
2251 'enabled' => (isModEnabled('invoice') && $object->status == Facture::STATUS_DRAFT && getDolGlobalInt('SUBTOTAL_TITLE_'.strtoupper($object->element))),
2252 'perm' => (bool) $usercancreate,
2253 'label' => $langs->trans('AddTitleLine'),
2254 'url' => '/compta/facture/card-rec.php?id='.$object->id.'&action=add_title_line&token='.newToken()
2255 );
2256
2257 $url_button[] = array(
2258 'lang' => 'subtotals',
2259 'enabled' => (isModEnabled('invoice') && $object->status == Facture::STATUS_DRAFT && getDolGlobalInt('SUBTOTAL_'.strtoupper($object->element))),
2260 'perm' => (bool) $usercancreate,
2261 'label' => $langs->trans('AddSubtotalLine'),
2262 'url' => '/compta/facture/card-rec.php?id='.$object->id.'&action=add_subtotal_line&token='.newToken()
2263 );
2264
2265 $url_button[] = array(
2266 'lang' => 'subtotals',
2267 'enabled' => (isModEnabled('invoice') && $object->status == Facture::STATUS_DRAFT && getDolGlobalInt('SUBTOTAL_TEXT_'.strtoupper($object->element))),
2268 'perm' => (bool) $usercancreate,
2269 'label' => $langs->trans('AddTextLine'),
2270 'url' => '/compta/facture/card-rec.php?id='.$object->id.'&action=add_text_line&token='.newToken()
2271 );
2272 print dolGetButtonAction('', $langs->trans('SubTotal'), 'default', $url_button, '', true);
2273 }
2274
2275 if (empty($object->suspended)) {
2276 if ($user->hasRight('facture', 'creer')) {
2277 if (!empty($object->frequency) && $object->nb_gen_max > 0 && ($object->nb_gen_done >= $object->nb_gen_max)) {
2278 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' . dol_escape_htmltag($langs->trans("MaxGenerationReached")) . '">' . $langs->trans("CreateBill") . '</a></div>';
2279 } else {
2280 if (empty($object->frequency) || $object->date_when <= $nowlasthour) {
2281 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>';
2282 } else {
2283 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' . dol_escape_htmltag($langs->trans("DateIsNotEnough")) . '">' . $langs->trans("CreateBill") . '</a></div>';
2284 }
2285 }
2286 } else {
2287 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#">' . $langs->trans("CreateBill") . '</a></div>';
2288 }
2289 }
2290
2291 if ($user->hasRight('facture', 'creer')) {
2292 if (empty($object->suspended)) {
2293 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>';
2294 } else {
2295 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>';
2296 }
2297 }
2298
2299 // Delete
2300 print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=delete&token=' . newToken(), 'delete', $user->hasRight('facture', 'supprimer'));
2301 }
2302 print '</div>';
2303
2304
2305
2306 print '<div class="fichecenter"><div class="fichehalfleft">';
2307 print '<a name="builddoc"></a>'; // ancre
2308
2309
2310 // Show links to link elements
2311 $tmparray = $form->showLinkToObjectBlock($object, array(), array('invoice'), 1);
2312 $linktoelem = $tmparray['linktoelem'];
2313 $htmltoenteralink = $tmparray['htmltoenteralink'];
2314 print $htmltoenteralink;
2315
2316 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
2317
2318
2319 print '</div>';
2320 print '<div class="fichehalfright">';
2321
2322 $MAXEVENT = 10;
2323
2324 $morehtmlcenter = '<div class="nowraponall">';
2325 //$morehtmlcenter .= dolGetButtonTitle($langs->trans('FullConversation'), '', 'fa fa-comments imgforviewmode', DOL_URL_ROOT.'/compta/facture/messaging.php?id='.$object->id);
2326 $morehtmlcenter .= dolGetButtonTitle($langs->trans('FullList'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/compta/facture/agenda-rec.php?id='.$object->id);
2327 $morehtmlcenter .= '</div>';
2328
2329 // List of actions on element
2330 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
2331 $formactions = new FormActions($db);
2332 $somethingshown = $formactions->showactions($object, $object->element, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlcenter);
2333
2334 print '</div>';
2335 print '</div>';
2336 } else {
2337 print $langs->trans("NoRecordFound");
2338 }
2339}
2340
2341// End of page
2342llxFooter();
2343$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
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:73
const STATUS_DRAFT
Draft status.
Class to manage a WYSIWYG editor.
Class to manage invoices.
const TYPE_REPLACEMENT
Replacement invoice.
const STATUS_DRAFT
Draft status.
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 to help generate other html components 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.
global $mysoc
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:651
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition date.lib.php:126
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.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
$date_start
Variables from include:
dol_now($mode='gmt')
Return date for now.
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...
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
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.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTFLOAT($paramname, $rounding='', $option=2)
Return the value of a $_GET or $_POST supervariable, converted into float.
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...
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
get_localtax($vatrate, $local, $thirdparty_buyer=null, $thirdparty_seller=null, $vatnpr=0)
Return localtax rate for a particular VAT rate, when selling a product with vat $vatrate,...
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.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
Definition html.lib.php:519
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
Definition html.lib.php:717
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dolGetButtonAction($label, $text='', $actionType='default', $url='', $id='', $userRight=1, $params=array())
Function dolGetButtonAction.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='', $textonpictotooltip='', $cssfordropdown='info_admin')
Show information in HTML for admin users or standard users.
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...
Definition html.lib.php:172
invoice_rec_prepare_head($object)
Return array head with list of tabs to view object information.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
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.