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