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