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