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