dolibarr 22.0.5
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-2024 Frédéric France <frederic.france@free.fr>
12 * Copyright (C) 2023-2024 Nick Fragoulis
13 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 3 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program. If not, see <https://www.gnu.org/licenses/>.
27 */
28
35// Load Dolibarr environment
36require '../../main.inc.php';
37require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.facture-rec.class.php';
38require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.product.class.php';
39require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
40require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php';
41if (isModEnabled('project')) {
42 include_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
43}
44require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
45require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
46require_once DOL_DOCUMENT_ROOT . '/core/lib/invoice.lib.php';
47require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
48
58// Load translation files required by the page
59$langs->loadLangs(array('bills', 'companies', 'compta', 'admin', 'other', 'products', 'banks', 'suppliers'));
60
61$action = GETPOST('action', 'alpha');
62$massaction = GETPOST('massaction', 'alpha');
63$show_files = GETPOSTINT('show_files');
64$confirm = GETPOST('confirm', 'alpha');
65$cancel = GETPOST('cancel', 'alpha');
66$toselect = GETPOST('toselect', 'array');
67$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'supplierinvoicetemplatelist'; // To manage different context of search
68$backtopage = GETPOST('backtopage', 'alpha'); // if not set, a default page will be used
69$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); // if not set, $backtopage will be used
70
71
72$id = (GETPOSTINT('facid') ? GETPOSTINT('facid') : GETPOSTINT('id'));
73$lineid = GETPOSTINT('lineid');
74$ref = GETPOST('title', 'alphanohtml') ? GETPOST('title', 'alphanohtml') : GETPOST('ref', 'alphanohtml');
75$label = GETPOST('label', 'alphanohtml');
76$ref_supplier = GETPOST('ref_supplier', 'alphanohtml');
77$projectid = GETPOSTINT('projectid');
78$year_date_when = GETPOST('year_date_when');
79$month_date_when = GETPOST('month_date_when');
80// Security check
81$socid = GETPOSTINT('socid');
82if ($user->socid) {
83 $socid = $user->socid;
84}
85$objecttype = 'facture_fourn_rec';
86if ($action == "create" || $action == "add") {
87 $objecttype = '';
88}
89
90$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
91$sortfield = GETPOST("sortfield", 'aZ09comma');
92$sortorder = GETPOST("sortorder", 'aZ09comma');
93$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
94if (empty($page) || $page == -1) {
95 $page = 0;
96} // If $page is not defined, or '' or -1
97$offset = $limit * $page;
98if (! $sortorder) {
99 $sortorder = 'DESC';
100}
101if (! $sortfield) {
102 $sortfield = 'f.titre';
103}
104$pageprev = $page - 1;
105$pagenext = $page + 1;
106
108if (($id > 0 || $ref) && $action != 'create' && $action != 'add') {
109 $ret = $object->fetch($id, $ref);
110 if (! $ret) {
111 setEventMessages($langs->trans("ErrorRecordNotFound"), null, 'errors');
112 }
113}
114
115// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
116$hookmanager->initHooks(array('supplierinvoicereccard', 'globalcard'));
117$extrafields = new ExtraFields($db);
118
119// fetch optionals attributes and labels
120$extrafields->fetch_name_optionals_label($object->table_element);
121
122$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
123
124$permissionnote = $user->hasRight("fournisseur", "facture", "creer") || $user->hasRight("supplier_invoice", "creer"); // Used by the include of actions_setnotes.inc.php
125$permissiondellink = $user->hasRight("fournisseur", "facture", "creer") || $user->hasRight("supplier_invoice", "creer"); // Used by the include of actions_dellink.inc.php
126$permissiontoedit = $user->hasRight("fournisseur", "facture", "creer") || $user->hasRight("supplier_invoice", "creer"); // Used by the include of actions_lineupdonw.inc.php
127$permissiontoadd = $user->hasRight("fournisseur", "facture", "creer") || $user->hasRight("supplier_invoice", "creer");
128$permissiontodelete = ($user->hasRight("fournisseur", "facture", "supprimer") || $user->hasRight("supplier_invoice", "supprimer"));
129$permissiontoeditextra = $permissiontoadd;
130if (GETPOST('attribute', 'aZ09') && isset($extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')])) {
131 // For action 'update_extras', is there a specific permission set for the attribute to update
132 $permissiontoeditextra = dol_eval((string) $extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')]);
133}
134
135$usercanread = $user->hasRight("fournisseur", "facture", "lire") || $user->hasRight("supplier_invoice", "lire");
136$usercancreate = $user->hasRight("fournisseur", "facture", "creer") || $user->hasRight("supplier_invoice", "creer");
137$usercandelete = $user->hasRight("fournisseur", "facture", "supprimer") || $user->hasRight("supplier_invoice", "supprimer");
138$usercanvalidate = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !empty($usercancreate)) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight("fournisseur", "supplier_invoice_advance", "validate")));
139$usercansend = (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->hasRight("fournisseur", "supplier_invoice_advance", "send"));
140
141$usercanproductignorepricemin = ((getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight("produit", "ignore_price_min_advance")) || !getDolGlobalString('MAIN_USE_ADVANCED_PERMS'));
142$usercancreatemargin = $user->hasRight("margins", "creer");
143$usercanreadallmargin = $user->hasRight("margins", "liretous");
144$usercancreatewithdrarequest = $user->hasRight("prelevement", "bons", "creer");
145
146$now = dol_now();
147
148$error = 0;
149$predef = ''; // Legacy? Used in several cards, always ''
150
151// Security check
152$result = restrictedArea($user, 'supplier_invoicerec', $object->id, $objecttype);
153
154
155/*
156 * Actions
157 */
158
159if (GETPOST('cancel', 'alpha')) {
160 if ($action != 'updateline') {
161 $action = 'list';
162 $massaction = '';
163 } else {
164 $action = '';
165 $cancel = '';
166 }
167}
168if (! GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
169 $massaction = '';
170}
171
172$parameters = array('socid' => $socid);
173$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
174if ($reshook < 0) {
175 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
176}
177
178if (empty($reshook)) {
179 if (GETPOST('cancel', 'alpha')) {
180 $action = '';
181 }
182
183 // Selection of new fields
184 include DOL_DOCUMENT_ROOT . '/core/actions_changeselectedfields.inc.php';
185
186 // Set note
187 include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be 'include', not 'include_once'
188
189 include DOL_DOCUMENT_ROOT . '/core/actions_dellink.inc.php'; // Must be 'include', not 'include_once'
190
191 include DOL_DOCUMENT_ROOT . '/core/actions_lineupdown.inc.php'; // Must be 'include', not 'include_once'
192
193 // Create predefined invoice
194 if ($action == 'add' && $permissiontoadd) {
195 if (! GETPOST('title', 'alphanohtml')) {
196 setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("Title")), null, 'errors');
197 $action = "create";
198 $error++;
199 }
200
201 $frequency = GETPOSTINT('frequency');
202 $reyear = GETPOSTINT('reyear');
203 $remonth = GETPOSTINT('remonth');
204 $reday = GETPOSTINT('reday');
205 $rehour = GETPOSTINT('rehour');
206 $remin = GETPOSTINT('remin');
207 $nb_gen_max = GETPOSTINT('nb_gen_max');
208 //if (empty($nb_gen_max)) $nb_gen_max =0;
209
210 if (GETPOSTINT('frequency')) {
211 if (empty($reyear) || empty($remonth) || empty($reday)) {
212 setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("Date")), null, 'errors');
213 $action = "create";
214 $error++;
215 }
216 }
217
218 if (! $error) {
219 $object->subtype = GETPOSTINT('subtype');
220 $object->title = GETPOST('title', 'alphanohtml');
221 $object->ref = GETPOST('title', 'alphanohtml');
222 $object->label = GETPOST('label', 'alpha');
223 $object->ref_supplier = GETPOST('ref_supplier', 'alphanohtml');
224
225 $object->note_private = GETPOST('note_private', 'restricthtml');
226 $object->note_public = GETPOST('note_public', 'restricthtml');
227 $object->model_pdf = GETPOST('modelpdf', 'alpha');
228 $object->usenewprice = GETPOSTINT('usenewprice');
229
230 $object->frequency = $frequency;
231 $object->unit_frequency = GETPOST('unit_frequency', 'alpha');
232 $object->nb_gen_max = $nb_gen_max;
233 $object->auto_validate = GETPOSTINT('auto_validate');
234 $object->generate_pdf = GETPOSTINT('generate_pdf');
235 $object->fk_project = GETPOSTINT('projectid');
236
237 $date_next_execution = dol_mktime($rehour, $remin, 0, $remonth, $reday, $reyear);
238 $object->date_when = $date_next_execution;
239
240 $ret = $extrafields->setOptionalsFromPost(null, $object);
241 if ($ret < 0) {
242 setEventMessages($extrafields->error, $extrafields->errors, 'errors');
243 $error++;
244 }
245
246
247 $db->begin();
248
249 $oldinvoice = new FactureFournisseur($db);
250 $oldinvoice->fetch(GETPOSTINT('facid'));
251
252 $onlylines = GETPOST('toselect', 'array');
253
254 $result = $object->create($user, $oldinvoice->id, 0, $onlylines);
255
256 if ($result > 0) {
257 $result = $oldinvoice->delete($user, 1);
258 if ($result < 0) {
259 $error++;
260 setEventMessages($oldinvoice->error, $oldinvoice->errors, 'errors');
261 $action = "create";
262 }
263 } else {
264 $error++;
265 setEventMessages($object->error, $object->errors, 'errors');
266 $action = "create";
267 }
268
269 if (! $error) {
270 $db->commit();
271
272 header("Location: " . $_SERVER['PHP_SELF'] . '?facid=' . $object->id);
273 exit;
274 } else {
275 $db->rollback();
276
277 $action = "create";
278 }
279 }
280 }
281
282 // Delete
283 if ($action == 'confirm_deleteinvoice' && $confirm == 'yes' && $permissiontodelete) {
284 $object->delete($user);
285
286 header('Location: ' . DOL_URL_ROOT . '/fourn/facture/list-rec.php');
287 exit;
288 }
289
290 // Update field
291 // Set condition
292 if ($action == 'setconditions' && $usercancreate) {
293 $result = $object->setPaymentTerms(GETPOSTINT('cond_reglement_id'));
294 } elseif ($action == 'setmode' && $usercancreate) {
295 // Set mode
296 $result = $object->setPaymentMethods(GETPOSTINT('mode_reglement_id'));
297 } elseif ($action == 'classin' && $usercancreate) {
298 // Set project
299 $object->setProject(GETPOSTINT('projectid'));
300 } elseif ($action == 'setref_supplier' && $usercancreate) {
301 $result = $object->setValueFrom('ref_supplier', $ref_supplier, '', null, 'text', '', $user);
302
303 if ($result <= 0) {
304 $error++;
305 if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
306 $langs->load("errors");
307 setEventMessages($langs->trans('ErrorRefAlreadyExists', $ref_supplier), null, 'errors');
308 } else {
309 setEventMessages($object->error, $object->errors, 'errors');
310 }
311 }
312 } elseif ($action == 'settitle' && $permissiontoadd) {
313 $result = $object->setValueFrom('titre', $ref, '', null, 'text', '', $user);
314
315 if ($result > 0) {
316 $object->title = $ref;
317 $object->ref = $ref;
318 } else {
319 $error++;
320 if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
321 $langs->load("errors");
322 setEventMessages($langs->trans('ErrorTitreAlreadyExists', $ref), null, 'errors');
323 } else {
324 setEventMessages($object->error, $object->errors, 'errors');
325 }
326 }
327 } elseif ($action == 'setbankaccount' && $permissiontoadd) {
328 // Set bank account
329 $result = $object->setBankAccount(GETPOSTINT('fk_account'));
330 } elseif ($action == 'setfrequency' && $permissiontoadd) {
331 // Set frequency and unit frequency
332 $object->setFrequencyAndUnit((GETPOST('frequency') != '' ? GETPOSTINT('frequency') : null), GETPOST('unit_frequency', 'alpha'));
333 } elseif ($action == 'setdate_when' && $permissiontoadd) {
334 // Set next date of execution
335 $date = dol_mktime(GETPOSTINT('date_whenhour'), GETPOSTINT('date_whenmin'), 0, GETPOSTINT('date_whenmonth'), GETPOSTINT('date_whenday'), GETPOSTINT('date_whenyear'));
336 if (!empty($date)) {
337 $object->setNextDate($date);
338 }
339 } elseif ($action == 'setnb_gen_max' && $permissiontoadd) {
340 // Set max period
341 $object->setMaxPeriod(GETPOSTINT('nb_gen_max'));
342 } elseif ($action == 'setauto_validate' && $permissiontoadd) {
343 // Set auto validate
344 $object->setAutoValidate(GETPOSTINT('auto_validate'));
345 } elseif ($action == 'setgenerate_pdf' && $permissiontoadd) {
346 // Set generate pdf
347 $object->setGeneratepdf(GETPOSTINT('generate_pdf'));
348 } elseif ($action == 'setmodelpdf' && $permissiontoadd) {
349 // Set model pdf
350 $object->setModelpdf(GETPOST('modelpdf', 'alpha'));
351 } elseif ($action == 'disable' && $permissiontoadd) {
352 // Set status disabled
353 $db->begin();
354
355 $object->fetch($id);
356
357 $res = $object->setValueFrom('suspended', 1);
358 if ($res <= 0) {
359 $error++;
360 }
361
362 if (! $error) {
363 $db->commit();
364 } else {
365 $db->rollback();
366 setEventMessages($object->error, $object->errors, 'errors');
367 }
368 } elseif ($action == 'enable' && $permissiontoadd) {
369 // Set status enabled
370 $db->begin();
371
372 $object->context['actionmsg'] = $langs->trans("RecordEnabled");
373
374 $object->fetch($id);
375
376 $res = $object->setValueFrom('suspended', 0);
377 if ($res <= 0) {
378 $error++;
379 }
380
381 if (! $error) {
382 $db->commit();
383 } else {
384 $db->rollback();
385 setEventMessages($object->error, $object->errors, 'errors');
386 }
387 } elseif ($action == 'setmulticurrencycode' && $permissiontoadd) {
388 // Multicurrency Code
389 $result = $object->setMulticurrencyCode(GETPOST('multicurrency_code', 'alpha'));
390 } elseif ($action == 'setmulticurrencyrate' && $permissiontoadd) {
391 // Multicurrency rate
392 $result = $object->setMulticurrencyRate((float) price2num(GETPOST('multicurrency_tx')), GETPOSTINT('calculation_mode'));
393 } elseif ($action == 'setlabel' && $permissiontoadd) {
394 // Set bank account
395 $result = $object->setValueFrom('libelle', $label, '', null, 'text', '', $user);
396 }
397
398 // Delete line
399 if ($action == 'confirm_deleteline' && $confirm == 'yes' && $permissiontoadd) {
400 $object->fetch($id);
401 $object->fetch_thirdparty();
402
403 $db->begin();
404
405 $line = new FactureFournisseurLigneRec($db);
406
407 // For triggers
408 $line->id = $lineid;
409
410 if ($line->delete($user) > 0) {
411 $result = $object->update_price(1);
412
413 if ($result > 0) {
414 $db->commit();
415 $object->fetch($object->id); // Reload lines
416 } else {
417 $db->rollback();
418 setEventMessages($db->lasterror(), null, 'errors');
419 }
420 } else {
421 $db->rollback();
422 setEventMessages($line->error, $line->errors, 'errors');
423 }
424 } elseif ($action == 'update_extras' && $permissiontoeditextra) {
425 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
426
427 $attribute_name = GETPOST('attribute', 'aZ09');
428
429 // Fill array 'array_options' with data from update form
430 $ret = $extrafields->setOptionalsFromPost(null, $object, $attribute_name);
431 if ($ret < 0) {
432 $error++;
433 }
434
435 if (!$error) {
436 $result = $object->updateExtraField($attribute_name, 'BILLREC_MODIFY');
437 if ($result < 0) {
438 setEventMessages($object->error, $object->errors, 'errors');
439 $error++;
440 }
441 }
442
443 if ($error) {
444 $action = 'edit_extras';
445 }
446 }
447
448 // Add a new line
449 if ($action == 'addline' && $permissiontoadd) {
450 $langs->load('errors');
451 $error = 0;
452
453 // Set if we used free entry or predefined product
454 $predef = '';
455 $product_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : '');
456 $price_ht = price2num(GETPOST('price_ht'), 'MU', 2);
457 $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2);
458 $prod_entry_mode = GETPOST('prod_entry_mode', 'alpha');
459 if ($prod_entry_mode == 'free') {
460 $idprod = 0;
461 $tva_tx = (GETPOST('tva_tx', 'alpha') ? (string) GETPOST('tva_tx', 'alpha') : 0);
462 $ref_fournisseur = (GETPOSTISSET('fourn_ref') ? GETPOST('fourn_ref', 'restricthtml') : '');
463 } else {
464 $idprod = GETPOSTINT('idprod');
465 $tva_tx = '';
466 }
467
468 $qty = GETPOST('qty' . $predef, 'alpha');
469 $qty = ($qty === '') ? '' : (float) price2num(GETPOST('qty' . $predef, 'alpha'), 'MS', 2);
470 $remise_percent = price2num(GETPOST('remise_percent' . $predef), '', 2);
471
472 // Extrafields
473 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
474 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
475 // Unset extrafield
476 if (is_array($extralabelsline)) {
477 // Get extra fields
478 foreach ($extralabelsline as $key => $value) {
479 unset($_POST["options_" . $key . $predef]);
480 }
481 }
482
483 if ((empty($idprod) || $idprod < 0) && ($price_ht < 0) && ((float) $qty < 0)) {
484 setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), null, 'errors');
485 $error++;
486 }
487 if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && GETPOST('type') < 0) {
488 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors');
489 $error++;
490 }
491 if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && (! ($price_ht >= 0) || $price_ht == '')) { // Unit price can be 0 but not ''
492 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors');
493 $error++;
494 }
495 if ($qty == '') {
496 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
497 $error++;
498 }
499 if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && empty($product_desc)) {
500 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors');
501 $error++;
502 }
503 if ($qty < 0) {
504 $langs->load("errors");
505 setEventMessages($langs->trans('ErrorQtyForSupplierInvoiceCantBeNegative'), null, 'errors');
506 $error++;
507 }
508
509 $ref_fournisseur = null;
510 if ($prod_entry_mode != 'free' && empty($error)) { // With combolist mode idprodfournprice is > 0 or -1. With autocomplete, idprodfournprice is > 0 or ''
511 $productsupplier = new ProductFournisseur($db);
512
513 $idprod = 0;
514 if (GETPOST('idprodfournprice', 'alpha') == -1 || GETPOST('idprodfournprice', 'alpha') == '') {
515 $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, ...)
516 }
517 $reg = array();
518 if (preg_match('/^idprod_([0-9]+)$/', GETPOST('idprodfournprice', 'alpha'), $reg)) {
519 $idprod = (int) $reg[1];
520 $res = $productsupplier->fetch($idprod); // Load product from its id
521 // Call to init some price properties of $productsupplier
522 // So if a supplier price already exists for another thirdparty (first one found), we use it as reference price
523 if (getDolGlobalString('SUPPLIER_TAKE_FIRST_PRICE_IF_NO_PRICE_FOR_CURRENT_SUPPLIER')) {
524 $fksoctosearch = 0;
525 $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist
526 if ($productsupplier->fourn_socid != $socid) { // The price we found is for another supplier, so we clear supplier price
527 $productsupplier->ref_supplier = '';
528 }
529 } else {
530 $fksoctosearch = $object->thirdparty->id;
531 $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist
532 }
533 } elseif (GETPOSTINT('idprodfournprice') > 0) { // Not a string here
534 $qtytosearch = $qty; // Just to see if a price exists for the quantity. Not used to found vat.
535 $idprod = $productsupplier->get_buyprice(GETPOSTINT('idprodfournprice'), $qtytosearch);
536 $res = $productsupplier->fetch($idprod);
537 $ref_fournisseur = $productsupplier->ref_supplier;
538 }
539 }
540
541 if (! $error && ($qty >= 0) && (!empty($product_desc) || (!empty($idprod) && $idprod > 0))) {
542 $ret = $object->fetch($id);
543 if ($ret < 0) {
544 dol_print_error($db, $object->error);
545 exit();
546 }
547 $ret = $object->fetch_thirdparty();
548
549 // Clean parameters
550 $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'));
551 $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'));
552 $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT');
553
554 // Define special_code for special lines
555 $special_code = 0;
556 $price_min = 0;
557 // if (!GETPOST('qty')) $special_code=3; // Options should not exists on invoices
558
559 // Ecrase $pu par celui du produit
560 // Ecrase $desc par celui du produit
561 // Ecrase $tva_tx par celui du produit
562 // Ecrase $base_price_type par celui du produit
563 // Replaces $fk_unit with the product's
564 if (!empty($idprod) && $idprod > 0) {
565 $prod = new Product($db);
566 $prod->fetch($idprod);
567
568 $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : '');
569
570 // Update if prices fields are defined
571 $tva_tx = get_default_tva($object->thirdparty, $mysoc, $prod->id);
572 $tva_npr = get_default_npr($object->thirdparty, $mysoc, $prod->id);
573 if (empty($tva_tx)) {
574 $tva_npr = 0;
575 }
576
577 // Search the correct price into loaded array product_price_by_qty using id of array retrieved into POST['pqp'].
578 $pqp = (GETPOSTINT('pbq') ? GETPOSTINT('pbq') : 0);
579
580 $datapriceofproduct = $prod->getSellPrice($object->thirdparty, $mysoc, $pqp);
581
582 $pu_ht = $datapriceofproduct['pu_ht'];
583 $pu_ttc = $datapriceofproduct['pu_ttc'];
584 $price_min = $datapriceofproduct['price_min'];
585 $price_base_type = empty($datapriceofproduct['price_base_type']) ? 'HT' : $datapriceofproduct['price_base_type'];
586 $tva_tx = $datapriceofproduct['tva_tx'];
587 $tva_npr = $datapriceofproduct['tva_npr'];
588
589 $tmpvat = price2num(preg_replace('/\s*\‍(.*\‍)/', '', (string) $tva_tx));
590 $tmpprodvat = price2num(preg_replace('/\s*\‍(.*\‍)/', '', (string) $prod->tva_tx));
591
592 // if price ht was forced (ie: from gui when calculated by margin rate and cost price). TODO Why this ?
593 if (!empty($price_ht)) {
594 $pu_ht = price2num($price_ht, 'MU');
595 $pu_ttc = price2num((float) $pu_ht * (1 + ((float) $tmpvat / 100)), 'MU');
596 } elseif ($tmpvat != $tmpprodvat) {
597 // On reevalue prix selon taux tva car taux tva transaction peut etre different
598 // de ceux du produit par default (par example si pays different entre vendeur et acheteur).
599 if ($price_base_type != 'HT') {
600 $pu_ht = price2num($pu_ttc / (1 + ((float) $tmpvat / 100)), 'MU');
601 } else {
602 $pu_ttc = price2num($pu_ht * (1 + ((float) $tmpvat / 100)), 'MU');
603 }
604 }
605
606 $outputlangs = $langs;
607 $newlang = '';
608 $desc = '';
609
610 // Define output language
611 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
612 if (/* empty($newlang) && */ GETPOST('lang_id', 'aZ09')) {
613 $newlang = GETPOST('lang_id', 'aZ09');
614 }
615 if (empty($newlang)) {
616 $newlang = $object->thirdparty->default_lang;
617 }
618 if (!empty($newlang)) {
619 $outputlangs = new Translate("", $conf);
620 $outputlangs->setDefaultLang($newlang);
621 $outputlangs->load('products');
622 }
623
624 $desc = (!empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description;
625 } else {
626 $desc = $prod->description;
627 }
628
629 $desc = dol_concatdesc($desc, $product_desc);
630
631 // Add custom code and origin country into description
632 if (!getDolGlobalString('MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE') && (!empty($prod->customcode) || !empty($prod->country_code))) {
633 $tmptxt = '(';
634 // Define output language
635 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
636 if (!empty($prod->customcode)) {
637 $tmptxt .= $outputlangs->transnoentitiesnoconv("CustomsCode") . ': ' . $prod->customcode;
638 }
639 if (!empty($prod->customcode) && !empty($prod->country_code)) {
640 $tmptxt .= ' - ';
641 }
642 if (!empty($prod->country_code)) {
643 $tmptxt .= $outputlangs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, '', $db, $outputlangs, 0);
644 }
645 } else {
646 if (!empty($prod->customcode)) {
647 $tmptxt .= $langs->transnoentitiesnoconv("CustomsCode") . ': ' . $prod->customcode;
648 }
649 if (!empty($prod->customcode) && !empty($prod->country_code)) {
650 $tmptxt .= ' - ';
651 }
652 if (!empty($prod->country_code)) {
653 $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, '', $db, $langs, 0);
654 }
655 }
656 $tmptxt .= ')';
657 $desc = dol_concatdesc($desc, $tmptxt);
658 }
659
660 $type = $prod->type;
661 $fk_unit = $prod->fk_unit;
662 } else {
663 $pu_ht = price2num($price_ht, 'MU');
664 $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
665 $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
666 $tva_tx = str_replace('*', '', $tva_tx);
667 if (empty($tva_tx)) {
668 $tva_npr = 0;
669 }
670 $desc = $product_desc;
671 $type = GETPOST('type');
672 $fk_unit = GETPOSTINT('units');
673 }
674
675 $date_start_fill = GETPOSTINT('date_start_fill');
676 $date_end_fill = GETPOSTINT('date_end_fill');
677
678 // Margin
679 $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
680 $buyingprice = price2num(GETPOST('buying_price' . $predef) != '' ? GETPOST('buying_price' . $predef) : ''); // If buying_price is '0', we must keep this value
681
682 // Local Taxes
683 $localtax1_tx = get_localtax((string) $tva_tx, 1, $mysoc, $object->thirdparty, $tva_npr);
684 $localtax2_tx = get_localtax((string) $tva_tx, 2, $mysoc, $object->thirdparty, $tva_npr);
685 $info_bits = 0;
686 if ($tva_npr) {
687 $info_bits |= 0x01;
688 }
689
690 // To set vars in float type to avoid non-numeric warnings
691 $pu_ht = (float) price2num($pu_ht);
692 $remise_percent = (float) price2num($remise_percent);
693
694 $price_min = (float) price2num((float) $price_min);
695 if ($usercanproductignorepricemin && (!empty($price_min) && ($pu_ht * (1 - $remise_percent / 100) < $price_min))) {
696 $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
697 setEventMessages($mesg, null, 'errors');
698 } else {
699 // Insert line
700 $result = $object->addline($idprod, (string) $ref_fournisseur, $label, $desc, $pu_ht, $pu_ttc, (float) $qty, $remise_percent, (float) $tva_tx, $localtax1_tx, $localtax2_tx, $price_base_type, $type, $date_start_fill, $date_end_fill, $info_bits, $special_code, -1, $fk_unit);
701
702 if ($result > 0) {
703 $object->fetch($object->id); // Reload lines
704
705 unset($_POST['prod_entry_mode']);
706 unset($_POST['qty']);
707 unset($_POST['type']);
708 unset($_POST['remise_percent']);
709 unset($_POST['price_ht']);
710 unset($_POST['multicurrency_price_ht']);
711 unset($_POST['price_ttc']);
712 unset($_POST['tva_tx']);
713 unset($_POST['product_ref']);
714 unset($_POST['product_label']);
715 unset($_POST['product_desc']);
716 unset($_POST['fournprice']);
717 unset($_POST['buying_price']);
718 unset($_POST['np_marginRate']);
719 unset($_POST['np_markRate']);
720 unset($_POST['dp_desc']);
721 unset($_POST['idprod']);
722 unset($_POST['units']);
723 unset($_POST['date_starthour']);
724 unset($_POST['date_startmin']);
725 unset($_POST['date_startsec']);
726 unset($_POST['date_startday']);
727 unset($_POST['date_startmonth']);
728 unset($_POST['date_startyear']);
729 unset($_POST['date_endhour']);
730 unset($_POST['date_endmin']);
731 unset($_POST['date_endsec']);
732 unset($_POST['date_endday']);
733 unset($_POST['date_endmonth']);
734 unset($_POST['date_endyear']);
735 unset($_POST['date_start_fill']);
736 unset($_POST['date_end_fill']);
737 unset($_POST['situations']);
738 unset($_POST['progress']);
739 unset($_POST['fourn_ref']);
740 } else {
741 setEventMessages($object->error, $object->errors, 'errors');
742 }
743
744 $action = '';
745 }
746 }
747 } elseif ($action == 'updateline' && $permissiontoadd && ! GETPOST('cancel', 'alpha')) {
748 if (! $object->fetch($id) > 0) {
749 dol_print_error($db);
750 }
751 $object->fetch_thirdparty();
752
753 // Clean parameters
754 $date_start = '';
755 $date_end = '';
756 $description = dol_htmlcleanlastbr(GETPOST('product_desc', 'restricthtml') ? GETPOST('product_desc', 'restricthtml') : GETPOST('desc', 'restricthtml'));
757 $ref_fourn = GETPOST('fourn_ref', 'alpha');
758 $pu_ht = price2num(GETPOST('price_ht'), '', 2);
759 $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
760 $pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), '', 2);
761
762 $qty = (float) price2num(GETPOST('qty', 'alpha'), 'MS');
763
764 // Define info_bits
765 $info_bits = 0;
766 if (preg_match('/\*/', $vat_rate)) {
767 $info_bits |= 0x01;
768 }
769
770 // Define vat_rate
771 $vat_rate = str_replace('*', '', $vat_rate);
772 $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty);
773 $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty);
774
775 // Extrafields
776 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
777 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line);
778
779 $objectline = new FactureFournisseurLigneRec($db);
780 if ($objectline->fetch(GETPOSTINT('lineid'))) {
781 $objectline->array_options = $array_options;
782 $result = $objectline->insertExtraFields();
783 if ($result < 0) {
784 setEventMessages($langs->trans('Error') . $result, null, 'errors');
785 }
786 }
787
788 $position = ($objectline->rang >= 0 ? $objectline->rang : 0);
789
790 // Unset extrafield
791 if (is_array($extralabelsline)) {
792 // Get extra fields
793 foreach ($extralabelsline as $key => $value) {
794 unset($_POST["options_" . $key]);
795 }
796 }
797
798 // Define special_code for special lines
799 $special_code = GETPOSTINT('special_code');
800 if (! GETPOST('qty', 'alpha')) {
801 $special_code = 3;
802 }
803
804 $remise_percent = price2num(GETPOST('remise_percent'), '', 2) ?: 0;
805
806 // Check minimum price
807 $productid = GETPOSTINT('productid');
808 if (!empty($productid)) {
809 $product = new Product($db);
810 $product->fetch($productid);
811
812 $type = $product->type;
813
814 $price_min = $product->price_min;
815 if (getDolGlobalString('PRODUIT_MULTIPRICES') && !empty($object->thirdparty->price_level)) {
816 $price_min = $product->multiprices_min[$object->thirdparty->price_level];
817 }
818
819 $label = $product->label;
820
821 // Check price is not lower than minimum (check is done only for standard or replacement invoices)
822 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))) {
823 setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)), null, 'errors');
824 $error++;
825 }
826 } else {
827 $type = GETPOSTINT('type');
828 $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
829
830 // Check parameters
831 if (GETPOSTINT('type') < 0) {
832 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
833 $error++;
834 }
835 }
836 if ($qty < 0) {
837 $langs->load("errors");
838 setEventMessages($langs->trans('ErrorQtyForSupplierInvoiceCantBeNegative'), null, 'errors');
839 $error++;
840 }
841
842 $date_start_fill = GETPOSTINT('date_start_fill');
843 $date_end_fill = GETPOSTINT('date_end_fill');
844
845 // Update line
846 if (! $error) {
847 $result = $object->updateline(GETPOSTINT('lineid'), GETPOSTINT('productid'), $ref_fourn, $label, $description, (float) $pu_ht, (float) $qty, $remise_percent, (float) $vat_rate, $localtax1_rate, $localtax1_rate, 'HT', $type, $date_start_fill, $date_end_fill, $info_bits, $special_code, -1);
848 if ($result >= 0) {
849 $object->fetch($object->id); // Reload lines
850
851 unset($_POST['qty']);
852 unset($_POST['type']);
853 unset($_POST['productid']);
854 unset($_POST['remise_percent']);
855 unset($_POST['price_ht']);
856 unset($_POST['multicurrency_price_ht']);
857 unset($_POST['price_ttc']);
858 unset($_POST['tva_tx']);
859 unset($_POST['product_ref']);
860 unset($_POST['product_label']);
861 unset($_POST['product_desc']);
862 unset($_POST['fournprice']);
863 unset($_POST['buying_price']);
864 unset($_POST['np_marginRate']);
865 unset($_POST['np_markRate']);
866 unset($_POST['dp_desc']);
867 unset($_POST['idprod']);
868 unset($_POST['units']);
869 unset($_POST['date_starthour']);
870 unset($_POST['date_startmin']);
871 unset($_POST['date_startsec']);
872 unset($_POST['date_startday']);
873 unset($_POST['date_startmonth']);
874 unset($_POST['date_startyear']);
875 unset($_POST['date_endhour']);
876 unset($_POST['date_endmin']);
877 unset($_POST['date_endsec']);
878 unset($_POST['date_endday']);
879 unset($_POST['date_endmonth']);
880 unset($_POST['date_endyear']);
881 unset($_POST['situations']);
882 unset($_POST['progress']);
883 unset($_POST['fourn_ref']);
884 } else {
885 setEventMessages($object->error, $object->errors, 'errors');
886 }
887 }
888 }
889}
890
891
892/*
893 * View
894 */
895
896$title = $langs->trans("RepeatableSupplierInvoice");
897$help_url = '';
898llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-fourn-facture page-card-rec');
899
900$form = new Form($db);
901$formother = new FormOther($db);
902if (isModEnabled('project')) {
903 $formproject = new FormProjets($db);
904} else {
905 $formproject = null;
906}
907$companystatic = new Societe($db);
908$invoicerectmp = new FactureFournisseurRec($db);
909
910$now = dol_now();
911$nowlasthour = dol_get_last_hour($now);
912
913// Create mode
914if ($action == 'create') {
915 print load_fiche_titre($langs->trans("CreateRepeatableInvoice"), '', 'bill');
916
917 $object = new FactureFournisseur($db); // Source invoice
918 $product_static = new Product($db);
919
920 if ($object->fetch($id, $ref) > 0) {
921 $result = $object->fetch_lines();
922
923 print '<form action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
924 print '<input type="hidden" name="token" value="' . newToken() . '">';
925 print '<input type="hidden" name="action" value="add">';
926 print '<input type="hidden" name="facid" value="' . $object->id . '">';
927
928 print dol_get_fiche_head([], '', '', 0);
929
930 $rowspan = 4;
931 if (isModEnabled('project')) {
932 $rowspan++;
933 }
934 if ($object->fk_account > 0) {
935 $rowspan++;
936 }
937
938 print '<table class="border centpercent">';
939
940 $object->fetch_thirdparty();
941
942 // Title
943 print '<tr><td class="titlefieldcreate fieldrequired">' . $langs->trans("Title") . '</td><td>';
944 print '<input class="flat quatrevingtpercent" type="text" name="title" value="' . dol_escape_htmltag(GETPOST("title", 'alphanohtml')) . '" autofocus>';
945 print '</td></tr>';
946
947 // Ref supplier
948 print '<tr><td class="titlefieldcreate fieldrequired">' . $langs->trans("RefSupplier") . '</td><td>';
949 print '<input class="flat maxwidth500" type="text" name="ref_supplier" value="' . $object->ref_supplier . '">';
950 print '</td></tr>';
951
952 // Third party
953 print '<tr><td class="titlefieldcreate">' . $langs->trans("Supplier") . '</td><td>' . $object->thirdparty->getNomUrl(1, 'supplier') . '</td>';
954 print '</tr>';
955
956 // Invoice subtype
957 if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED')) {
958 print "<tr><td>".$langs->trans("InvoiceSubtype")."</td><td>";
959 print $form->getSelectInvoiceSubtype(GETPOSTISSET('subtype') ? GETPOST('subtype') : $object->subtype, 'subtype', 0, 0, '');
960 print "</td></tr>";
961 }
962
963 $note_public = GETPOSTISSET('note_public') ? GETPOST('note_public', 'restricthtml') : $object->note_public;
964 $note_private = GETPOSTISSET('note_private') ? GETPOST('note_private', 'restricthtml') : $object->note_private;
965
966 // Help for substitution key
967 $substitutionarray = getCommonSubstitutionArray($langs, 2, null, $object);
968
969 $substitutionarray['__INVOICE_PREVIOUS_MONTH__'] = $langs->trans("PreviousMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, -1, 'm'), '%m') . ')';
970 $substitutionarray['__INVOICE_MONTH__'] = $langs->trans("MonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($object->date, '%m') . ')';
971 $substitutionarray['__INVOICE_NEXT_MONTH__'] = $langs->trans("NextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, 1, 'm'), '%m') . ')';
972 $substitutionarray['__INVOICE_PREVIOUS_MONTH_TEXT__'] = $langs->trans("TextPreviousMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, -1, 'm'), '%B') . ')';
973 $substitutionarray['__INVOICE_MONTH_TEXT__'] = $langs->trans("TextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($object->date, '%B') . ')';
974 $substitutionarray['__INVOICE_NEXT_MONTH_TEXT__'] = $langs->trans("TextNextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, 1, 'm'), '%B') . ')';
975 $substitutionarray['__INVOICE_PREVIOUS_YEAR__'] = $langs->trans("PreviousYearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, -1, 'y'), '%Y') . ')';
976 $substitutionarray['__INVOICE_YEAR__'] = $langs->trans("YearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($object->date, '%Y') . ')';
977 $substitutionarray['__INVOICE_NEXT_YEAR__'] = $langs->trans("NextYearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, 1, 'y'), '%Y') . ')';
978 // Only on template invoices
979 $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_BEFORE_GEN__'] = $langs->trans("DateNextInvoiceBeforeGen") . (isset($object->date_when) ? ' (' . $langs->trans("Example") . ': ' .dol_print_date($object->date_when, 'dayhour') . ')' : '');
980 $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') . ')' : '');
981 $substitutionarray['__INVOICE_COUNTER_CURRENT__'] = $langs->trans("Count");
982 $substitutionarray['__INVOICE_COUNTER_MAX__'] = $langs->trans("MaxPeriodNumber");
983
984 $htmltext = '<i>' . $langs->trans("FollowingConstantsWillBeSubstituted") . ':<br>';
985 foreach ($substitutionarray as $key => $val) {
986 $htmltext .= $key . ' = ' . $langs->trans($val) . '<br>';
987 }
988 $htmltext .= '</i>';
989
990 // Label
991 print '<tr><td class="titlefieldcreate">' . $langs->trans("Label") . '</td><td>';
992 print '<input class="flat quatrevingtpercent" type="text" name="label" value="' . $object->label . '">';
993 print '</td></tr>';
994
995 // Author
996 print "<tr><td>" . $langs->trans("Author") . "</td><td>" . $user->getFullName($langs) . "</td></tr>";
997
998 // Payment term
999 print "<tr><td>" . $langs->trans("PaymentConditions") . "</td><td>";
1000 print $form->getSelectConditionsPaiements(GETPOSTISSET('cond_reglement_id') ? GETPOST('cond_reglement_id', 'int') : $object->cond_reglement_id, 'cond_reglement_id', -1, 0, 0, '');
1001 print "</td></tr>";
1002
1003 // Payment mode
1004 print "<tr><td>" . $langs->trans("PaymentMode") . "</td><td>";
1005 print img_picto('', 'payment', 'class="pictofixedwidth"');
1006 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);
1007 print "</td></tr>";
1008
1009 // Project
1010 if (isModEnabled('project') && $formproject !== null && is_object($object->thirdparty) && $object->thirdparty->id > 0) {
1011 $projectid = GETPOST('projectid') ? GETPOST('projectid') : $object->fk_project;
1012 $langs->load('projects');
1013 print '<tr><td>' . $langs->trans('Project') . '</td><td>';
1014 $numprojet = $formproject->select_projects($object->thirdparty->id, $projectid, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, '');
1015 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>';
1016 print '</td></tr>';
1017 }
1018
1019 // Bank account
1020 if ($object->fk_account > 0) {
1021 print "<tr><td>" . $langs->trans('BankAccount') . "</td><td>";
1022 $form->formSelectAccount($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->fk_account, 'none');
1023 print "</td></tr>";
1024 }
1025
1026 // Extrafields
1027 $draft = new FactureFournisseur($db);
1028 $draft->fetch(GETPOSTINT('facid'));
1029
1030 $extralabels = new ExtraFields($db);
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, $conf->global->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($_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_author);
1171
1172 $head = supplier_invoice_rec_prepare_head($object);
1173
1174 print dol_get_fiche_head($head, 'card', $langs->trans('RepeatableInvoice'), -1, 'bill'); // 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($object->socid, (string) $object->fk_project, 'projectid', $maxlength, 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 (empty($conf->cron->enabled)) {
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->printObjectLines($action, $object->thirdparty, $mysoc, $lineid, 0); // No date selector for template invoice
1542 }
1543
1544 // Form to add new line
1545 //TODO : Droits
1546 if ($object->statut == $object::STATUS_DRAFT && $usercancreate && $action != 'valid' && $action != 'editline') {
1547 if ($action != 'editline') {
1548 // Add free products/services
1549
1550 $parameters = array();
1551 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1552 if ($reshook < 0) {
1553 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1554 }
1555 if (empty($reshook)) {
1556 global $senderissupplier;
1557 }
1558 $senderissupplier = 2;
1559 $object->formAddObjectLine(0, $object->thirdparty, $mysoc); // No date selector for template invoice
1560 }
1561 }
1562
1563 print "</table>\n";
1564 print '</div>';
1565
1566 print "</form>\n";
1567
1568 print dol_get_fiche_end();
1569
1570 /*
1571 * Action bar
1572 */
1573 print '<div class="tabsAction">';
1574
1575 if (empty($object->suspended)) {
1576 if ($usercancreate) {
1577 if (!empty($object->frequency) && $object->nb_gen_max > 0 && ($object->nb_gen_done >= $object->nb_gen_max)) {
1578 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' . dol_escape_htmltag($langs->trans("MaxGenerationReached")) . '">' . $langs->trans("CreateBill") . '</a></div>';
1579 } else {
1580 if (empty($object->frequency) || $object->date_when <= $nowlasthour) {
1581 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>';
1582 } else {
1583 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' . dol_escape_htmltag($langs->trans("DateIsNotEnough")) . '">' . $langs->trans("CreateBill") . '</a></div>';
1584 }
1585 }
1586 } else {
1587 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#">' . $langs->trans("CreateBill") . '</a></div>';
1588 }
1589 }
1590
1591 if ($usercancreate) {
1592 if (empty($object->suspended)) {
1593 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>';
1594 } else {
1595 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>';
1596 }
1597 }
1598
1599 // Delete
1600 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")));
1601
1602 print '</div>';
1603
1604 print '<div class="fichecenter"><div class="fichehalfleft">';
1605 print '<a name="builddoc"></a>'; // ancre
1606
1607 // Show links to link elements
1608 $tmparray = $form->showLinkToObjectBlock($object, array(), array('invoice'), 1);
1609 $linktoelem = $tmparray['linktoelem'];
1610 $htmltoenteralink = $tmparray['htmltoenteralink'];
1611 print $htmltoenteralink;
1612
1613 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
1614
1615 print '</div></div>';
1616 }
1617}
1618
1619// End of page
1620llxFooter();
1621$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:48
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
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 permettant la generation de composants html autre Only common components are here.
Class to manage building of HTML components.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
Class to manage predefined suppliers products.
Class to manage products or services.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
Class to manage Dolibarr users.
getCountry($searchkey, $withcode='', $dbtouse=null, $outputlangs=null, $entconv=1, $searchlabel='')
Return country label, code or id from an id, code or label.
dol_get_last_hour($date, $gm='tzserver')
Return GMT time for last hour of a given GMT date (it replaces hours, min and second part to 23:59:59...
Definition date.lib.php:646
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition date.lib.php:125
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_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.
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 '.
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.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
newToken()
Return the value of token currently saved into session with name 'newtoken'.
dolGetButtonAction($label, $text='', $actionType='default', $url='', $id='', $userRight=1, $params=array())
Function dolGetButtonAction.
dol_htmlcleanlastbr($stringtodecode)
This function remove all ending and br at end.
get_default_npr(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that returns whether VAT must be recoverable collected VAT (e.g.: VAT NPR in France)
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_clone($object, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='')
Show information in HTML for admin users or standard users.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
get_localtax($vatrate, $local, $thirdparty_buyer=null, $thirdparty_seller=null, $vatnpr=0)
Return localtax rate for a particular vat, when selling a product with vat $vatrate,...
img_info($titlealt='default')
Show info logo.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
supplier_invoice_rec_prepare_head($object)
Return array head with list of tabs to view object information.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
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.