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