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