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