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