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