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