dolibarr 20.0.2
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 } else {
726 setEventMessages($object->error, $object->errors, 'errors');
727 }
728
729 $action = '';
730 }
731 }
732 } elseif ($action == 'updateline' && $usercancreate && ! GETPOST('cancel', 'alpha')) {
733 if (! $object->fetch($id) > 0) {
734 dol_print_error($db);
735 }
736 $object->fetch_thirdparty();
737
738 // Clean parameters
739 $date_start = '';
740 $date_end = '';
741 $description = dol_htmlcleanlastbr(GETPOST('product_desc', 'restricthtml') ? GETPOST('product_desc', 'restricthtml') : GETPOST('desc', 'restricthtml'));
742 $ref_fourn = GETPOST('fourn_ref', 'alpha');
743 $pu_ht = price2num(GETPOST('price_ht'), '', 2);
744 $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
745 $qty = GETPOST('qty');
746 $pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), '', 2);
747
748 // Define info_bits
749 $info_bits = 0;
750 if (preg_match('/\*/', $vat_rate)) {
751 $info_bits |= 0x01;
752 }
753
754 // Define vat_rate
755 $vat_rate = str_replace('*', '', $vat_rate);
756 $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty);
757 $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty);
758
759 // Extrafields
760 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
761 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line);
762
763 $objectline = new FactureFournisseurLigneRec($db);
764 if ($objectline->fetch(GETPOSTINT('lineid'))) {
765 $objectline->array_options = $array_options;
766 $result = $objectline->insertExtraFields();
767 if ($result < 0) {
768 setEventMessages($langs->trans('Error') . $result, null, 'errors');
769 }
770 }
771
772 $position = ($objectline->rang >= 0 ? $objectline->rang : 0);
773
774 // Unset extrafield
775 if (is_array($extralabelsline)) {
776 // Get extra fields
777 foreach ($extralabelsline as $key => $value) {
778 unset($_POST["options_" . $key]);
779 }
780 }
781
782 // Define special_code for special lines
783 $special_code = GETPOSTINT('special_code');
784 if (! GETPOST('qty', 'alpha')) {
785 $special_code = 3;
786 }
787
788 $remise_percent = price2num(GETPOST('remise_percent'), '', 2) ?: 0;
789
790 // Check minimum price
791 $productid = GETPOSTINT('productid');
792 if (!empty($productid)) {
793 $product = new Product($db);
794 $product->fetch($productid);
795
796 $type = $product->type;
797
798 $price_min = $product->price_min;
799 if (getDolGlobalString('PRODUIT_MULTIPRICES') && !empty($object->thirdparty->price_level)) {
800 $price_min = $product->multiprices_min[$object->thirdparty->price_level];
801 }
802
803 $label = $product->label;
804
805 // Check price is not lower than minimum (check is done only for standard or replacement invoices)
806 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))) {
807 setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)), null, 'errors');
808 $error++;
809 }
810 } else {
811 $type = GETPOSTINT('type');
812 $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
813
814 // Check parameters
815 if (GETPOSTINT('type') < 0) {
816 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
817 $error++;
818 }
819 }
820 if ($qty < 0) {
821 $langs->load("errors");
822 setEventMessages($langs->trans('ErrorQtyForSupplierInvoiceCantBeNegative'), null, 'errors');
823 $error++;
824 }
825
826 $date_start_fill = !empty(GETPOSTINT('date_start_fill')) ? GETPOSTINT('date_start_fill') : 'NULL';
827 $date_end_fill = !empty(GETPOSTINT('date_end_fill')) ? GETPOSTINT('date_end_fill') : 'NULL';
828
829 // Update line
830 if (! $error) {
831 $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);
832 if ($result >= 0) {
833 $object->fetch($object->id); // Reload lines
834
835 unset($_POST['qty']);
836 unset($_POST['type']);
837 unset($_POST['productid']);
838 unset($_POST['remise_percent']);
839 unset($_POST['price_ht']);
840 unset($_POST['multicurrency_price_ht']);
841 unset($_POST['price_ttc']);
842 unset($_POST['tva_tx']);
843 unset($_POST['product_ref']);
844 unset($_POST['product_label']);
845 unset($_POST['product_desc']);
846 unset($_POST['fournprice']);
847 unset($_POST['buying_price']);
848 unset($_POST['np_marginRate']);
849 unset($_POST['np_markRate']);
850 unset($_POST['dp_desc']);
851 unset($_POST['idprod']);
852 unset($_POST['units']);
853 unset($_POST['date_starthour']);
854 unset($_POST['date_startmin']);
855 unset($_POST['date_startsec']);
856 unset($_POST['date_startday']);
857 unset($_POST['date_startmonth']);
858 unset($_POST['date_startyear']);
859 unset($_POST['date_endhour']);
860 unset($_POST['date_endmin']);
861 unset($_POST['date_endsec']);
862 unset($_POST['date_endday']);
863 unset($_POST['date_endmonth']);
864 unset($_POST['date_endyear']);
865 unset($_POST['situations']);
866 unset($_POST['progress']);
867 } else {
868 setEventMessages($object->error, $object->errors, 'errors');
869 }
870 }
871 }
872}
873
874/*
875 * View
876 */
877
878$help_url = '';
879llxHeader('', $langs->trans("RepeatableSupplierInvoice"), $help_url);
880
881$form = new Form($db);
882$formother = new FormOther($db);
883if (isModEnabled('project')) {
884 $formproject = new FormProjets($db);
885}
886$companystatic = new Societe($db);
887$invoicerectmp = new FactureFournisseurRec($db);
888
889$now = dol_now();
890$nowlasthour = dol_get_last_hour($now);
891
892/*
893 * Create mode
894 */
895if ($action == 'create') {
896 print load_fiche_titre($langs->trans("CreateRepeatableInvoice"), '', 'bill');
897
898 $object = new FactureFournisseur($db); // Source invoice
899 $product_static = new Product($db);
900
901 if ($object->fetch($id) > 0) {
902 $result = $object->fetch_lines();
903
904 print '<form action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
905 print '<input type="hidden" name="token" value="' . newToken() . '">';
906 print '<input type="hidden" name="action" value="add">';
907 print '<input type="hidden" name="facid" value="' . $object->id . '">';
908
909 print dol_get_fiche_head(null, '', '', 0);
910
911 $rowspan = 4;
912 if (isModEnabled('project')) {
913 $rowspan++;
914 }
915 if ($object->fk_account > 0) {
916 $rowspan++;
917 }
918
919 print '<table class="border centpercent">';
920
921 $object->fetch_thirdparty();
922
923 // Title
924 print '<tr><td class="titlefieldcreate fieldrequired">' . $langs->trans("Title") . '</td><td>';
925 print '<input class="flat quatrevingtpercent" type="text" name="title" value="' . dol_escape_htmltag(GETPOST("title", 'alphanohtml')) . '" autofocus>';
926 print '</td></tr>';
927
928 // Ref supplier
929 print '<tr><td class="titlefieldcreate fieldrequired">' . $langs->trans("RefSupplier") . '</td><td>';
930 print '<input class="flat maxwidth500" type="text" name="ref_supplier" value="' . $object->ref_supplier . '">';
931 print '</td></tr>';
932
933 // Third party
934 print '<tr><td class="titlefieldcreate">' . $langs->trans("Supplier") . '</td><td>' . $object->thirdparty->getNomUrl(1, 'supplier') . '</td>';
935 print '</tr>';
936
937 // Invoice subtype
938 if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED')) {
939 print "<tr><td>".$langs->trans("InvoiceSubtype")."</td><td>";
940 print $form->getSelectInvoiceSubtype(GETPOSTISSET('subtype') ? GETPOST('subtype') : $object->subtype, 'subtype', 0, 0, '');
941 print "</td></tr>";
942 }
943
944 $note_public = GETPOSTISSET('note_public') ? GETPOST('note_public', 'restricthtml') : $object->note_public;
945 $note_private = GETPOSTISSET('note_private') ? GETPOST('note_private', 'restricthtml') : $object->note_private;
946
947 // Help for substitution key
948 $substitutionarray = getCommonSubstitutionArray($langs, 2, null, $object);
949
950 $substitutionarray['__INVOICE_PREVIOUS_MONTH__'] = $langs->trans("PreviousMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, -1, 'm'), '%m') . ')';
951 $substitutionarray['__INVOICE_MONTH__'] = $langs->trans("MonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($object->date, '%m') . ')';
952 $substitutionarray['__INVOICE_NEXT_MONTH__'] = $langs->trans("NextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, 1, 'm'), '%m') . ')';
953 $substitutionarray['__INVOICE_PREVIOUS_MONTH_TEXT__'] = $langs->trans("TextPreviousMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, -1, 'm'), '%B') . ')';
954 $substitutionarray['__INVOICE_MONTH_TEXT__'] = $langs->trans("TextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($object->date, '%B') . ')';
955 $substitutionarray['__INVOICE_NEXT_MONTH_TEXT__'] = $langs->trans("TextNextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, 1, 'm'), '%B') . ')';
956 $substitutionarray['__INVOICE_PREVIOUS_YEAR__'] = $langs->trans("PreviousYearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, -1, 'y'), '%Y') . ')';
957 $substitutionarray['__INVOICE_YEAR__'] = $langs->trans("YearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($object->date, '%Y') . ')';
958 $substitutionarray['__INVOICE_NEXT_YEAR__'] = $langs->trans("NextYearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, 1, 'y'), '%Y') . ')';
959 // Only on template invoices
960 $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_BEFORE_GEN__'] = $langs->trans("DateNextInvoiceBeforeGen") . (isset($object->date_when) ? ' (' . $langs->trans("Example") . ': ' .dol_print_date($object->date_when, 'dayhour') . ')' : '');
961 $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') . ')' : '');
962 $substitutionarray['__INVOICE_COUNTER_CURRENT__'] = $langs->trans("Count");
963 $substitutionarray['__INVOICE_COUNTER_MAX__'] = $langs->trans("MaxPeriodNumber");
964
965 $htmltext = '<i>' . $langs->trans("FollowingConstantsWillBeSubstituted") . ':<br>';
966 foreach ($substitutionarray as $key => $val) {
967 $htmltext .= $key . ' = ' . $langs->trans($val) . '<br>';
968 }
969 $htmltext .= '</i>';
970
971 // Label
972 print '<tr><td class="titlefieldcreate">' . $langs->trans("Label") . '</td><td>';
973 print '<input class="flat quatrevingtpercent" type="text" name="libelle" value="' . $object->label . '">';
974 print '</td></tr>';
975
976 // Author
977 print "<tr><td>" . $langs->trans("Author") . "</td><td>" . $user->getFullName($langs) . "</td></tr>";
978
979 // Payment term
980 print "<tr><td>" . $langs->trans("PaymentConditions") . "</td><td>";
981 print $form->getSelectConditionsPaiements(GETPOSTISSET('cond_reglement_id') ? GETPOST('cond_reglement_id', 'int') : $object->cond_reglement_id, 'cond_reglement_id', -1, 0, 0, '');
982 print "</td></tr>";
983
984 // Payment mode
985 print "<tr><td>" . $langs->trans("PaymentMode") . "</td><td>";
986 print img_picto('', 'payment', 'class="pictofixedwidth"');
987 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);
988 print "</td></tr>";
989
990 // Project
991 if (isModEnabled('project') && is_object($object->thirdparty) && $object->thirdparty->id > 0) {
992 $projectid = GETPOST('projectid') ? GETPOST('projectid') : $object->fk_project;
993 $langs->load('projects');
994 print '<tr><td>' . $langs->trans('Project') . '</td><td>';
995 $numprojet = $formproject->select_projects($object->thirdparty->id, $projectid, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, '');
996 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>';
997 print '</td></tr>';
998 }
999
1000 // Bank account
1001 if ($object->fk_account > 0) {
1002 print "<tr><td>" . $langs->trans('BankAccount') . "</td><td>";
1003 $form->formSelectAccount($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_account, 'none');
1004 print "</td></tr>";
1005 }
1006
1007 //extrafields
1008 $draft = new FactureFournisseur($db);
1009 $draft->fetch(GETPOST('facid', 'int'));
1010
1011 $extralabels = new ExtraFields($db);
1012 $extralabels = $extrafields->fetch_name_optionals_label($draft->table_element);
1013 if ($draft->fetch_optionals() > 0) {
1014 $object->array_options = array_merge($object->array_options, $draft->array_options);
1015 }
1016
1017 print $object->showOptionals($extrafields, 'create', $parameters);
1018
1019 // Model pdf
1020 print "<tr><td>" . $langs->trans('Model') . "</td><td>";
1021 include_once DOL_DOCUMENT_ROOT . '/core/modules/supplier_invoice/modules_facturefournisseur.php';
1023 print $form->selectarray('modelpdf', $list, $conf->global->INVOICE_SUPPLIER_ADDON_PDF);
1024 print "</td></tr>";
1025
1026 // Public note
1027 print '<tr>';
1028 print '<td class="tdtop">';
1029 print $form->textwithpicto($langs->trans('NotePublic'), $htmltext, 1, 'help', '', 0, 2, 'notepublic');
1030 print '</td>';
1031 print '<td>';
1032 $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%');
1033 print $doleditor->Create(1);
1034
1035 // Private note
1036 if (empty($user->socid)) {
1037 print '<tr>';
1038 print '<td class="tdtop">';
1039 print $form->textwithpicto($langs->trans('NotePrivate'), $htmltext, 1, 'help', '', 0, 2, 'noteprivate');
1040 print '</td>';
1041 print '<td>';
1042 $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%');
1043 print $doleditor->Create(1);
1044 print '</td></tr>';
1045 }
1046
1047 print "</table>";
1048
1049 print dol_get_fiche_end();
1050
1051 // Autogeneration
1052 $title = $langs->trans("Recurrence");
1053 print load_fiche_titre(img_picto('', 'recurring', 'class="pictofixedwidth"') . $title, '', '');
1054
1055 print '<span class="opacitymedium">'.$langs->trans("ToCreateARecurringInvoiceGeneAuto", $langs->transnoentitiesnoconv('Module2300Name')).'</span><br><br>';
1056
1057 print dol_get_fiche_head(null, '', '', 0);
1058
1059 print '<table class="border centpercent">';
1060
1061 // Frequency + unit
1062 print '<tr><td class="titlefieldcreate">' . $form->textwithpicto($langs->trans("Frequency"), $langs->transnoentitiesnoconv('toolTipFrequency')) . "</td><td>";
1063 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'));
1064 print "</td></tr>";
1065
1066 // Date next run
1067 print "<tr><td>" . $langs->trans('NextDateToExecution') . "</td><td>";
1068 $date_next_execution = isset($date_next_execution) ? $date_next_execution : (GETPOST('remonth') ? dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')) : -1);
1069 print $form->selectDate($date_next_execution, '', 1, 1, 0, "add", 1, 1);
1070 print "</td></tr>";
1071
1072 // Number max of generation
1073 print "<tr><td>" . $langs->trans("MaxPeriodNumber") . "</td><td>";
1074 print '<input type="text" name="nb_gen_max" value="' . GETPOST('nb_gen_max') . '" size="5" />';
1075 print "</td></tr>";
1076
1077 // Auto validate the invoice
1078 print "<tr><td>" . $langs->trans("StatusOfAutoGeneratedInvoices") . "</td><td>";
1079 $select = array('0' => $langs->trans('BillStatusDraft'), '1' => $langs->trans('BillStatusValidated'));
1080 print $form->selectarray('auto_validate', $select, GETPOST('auto_validate'));
1081 print "</td></tr>";
1082
1083 // Auto generate document
1084 if (getDolGlobalString('INVOICE_REC_CAN_DISABLE_DOCUMENT_FILE_GENERATION')) {
1085 print "<tr><td>" . $langs->trans("StatusOfGeneratedDocuments") . "</td><td>";
1086 $select = array('0' => $langs->trans('DoNotGenerateDoc'), '1' => $langs->trans('AutoGenerateDoc'));
1087 print $form->selectarray('generate_pdf', $select, GETPOST('generate_pdf'));
1088 print "</td></tr>";
1089 } else {
1090 print '<input type="hidden" name="generate_pdf" value="1">';
1091 }
1092
1093 print "</table>";
1094
1095 print dol_get_fiche_end();
1096
1097 $title = $langs->trans("ProductsAndServices");
1098 if (!isModEnabled("service")) {
1099 $title = $langs->trans("Products");
1100 } elseif (!isModEnabled("product")) {
1101 $title = $langs->trans("Services");
1102 }
1103
1104 print load_fiche_titre($title, '', '');
1105
1106 /*
1107 * Invoice lines
1108 */
1109 print '<div class="div-table-responsive-no-min">';
1110 print '<table id="tablelines" class="noborder noshadow" width="100%">';
1111 // Show object lines
1112 if (!empty($object->lines)) {
1113 $disableedit = 1;
1114 $disablemove = 1;
1115 $disableremove = 1;
1116 $object->printObjectLines('', $object->thirdparty, $mysoc, $lineid, 0); // No date selector for template invoice
1117 }
1118
1119 print "</table>\n";
1120 print '<div>';
1121 print '</td></tr>';
1122 print "</table>\n";
1123
1124 print $form->buttonsSaveCancel("Create");
1125
1126 print "</form>\n";
1127 } else {
1128 dol_print_error(null, "Error, no invoice " . $object->id);
1129 }
1130} else {
1131 /*
1132 * View mode
1133 */
1134 if ($object->id > 0) {
1135 $object->fetch($object->id);
1136 $object->fetch_thirdparty();
1137
1138 $formconfirm = '';
1139
1140 // Confirmation de la suppression d'une ligne produit
1141 if ($action == 'ask_deleteline') {
1142 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id . '&lineid=' . $lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1);
1143 }
1144
1145 // Confirm delete of repeatable invoice
1146 if ($action == 'ask_deleteinvoice') {
1147 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeleteRepeatableInvoice'), $langs->trans('ConfirmDeleteRepeatableInvoice'), 'confirm_deleteinvoice', '', 'no', 1);
1148 }
1149
1150 print $formconfirm;
1151
1152 $author = new User($db);
1153 $author->fetch($object->user_author);
1154
1155 $head = supplier_invoice_rec_prepare_head($object);
1156
1157 print dol_get_fiche_head($head, 'card', $langs->trans('RepeatableInvoice'), -1, 'bill'); // Add a div
1158
1159 // Recurring invoice content
1160
1161 $linkback = '<a href="' . DOL_URL_ROOT . '/fourn/facture/list-rec.php?restore_lastsearch_values=1' . (!empty($socid) ? '&socid=' . $socid : '') . '">' . $langs->trans('BackToList') . '</a>';
1162
1163 $morehtmlref = '';
1164 if ($action != 'edittitle') {
1165 $morehtmlref .= $form->editfieldkey($object->title, 'title', $object->title, $object, $usercancreate, '', '', 0, 2);
1166 } else {
1167 $morehtmlref .= $form->editfieldval('', 'title', $object->title, $object, $usercancreate, 'string');
1168 }
1169 $morehtmlref .= '<div class="refidno">';
1170 //Ref supplier
1171 $morehtmlref .= $form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $usercancreate, 'string', '', 0, 1);
1172 $morehtmlref .= $form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $usercancreate, 'string', '', null, null, '', 1);
1173 // Thirdparty
1174 $morehtmlref .= '<br>' . $langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1);
1175
1176 // Project
1177 if (isModEnabled('project')) {
1178 $langs->load('projects');
1179 $morehtmlref .= '<br>' . $langs->trans('Project') . ' ';
1180 if ($usercancreate) {
1181 if ($action != 'classify') {
1182 $morehtmlref .= '<a class="editfielda" href="' . $_SERVER['PHP_SELF'] . '?action=classify&token=' . newToken() . '&id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
1183 }
1184 if ($action == 'classify') {
1185 $morehtmlref .= '<form method="post" action="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '">';
1186 $morehtmlref .= '<input type="hidden" name="action" value="classin">';
1187 $morehtmlref .= '<input type="hidden" name="token" value="' . newToken() . '">';
1188 $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
1189 $morehtmlref .= '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
1190 $morehtmlref .= '</form>';
1191 } else {
1192 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300');
1193 }
1194 } else {
1195 if (!empty($object->fk_project)) {
1196 $project = new Project($db);
1197 $project->fetch($object->fk_project);
1198 $morehtmlref .= ' : ' . $project->getNomUrl(1);
1199 if ($project->title) {
1200 $morehtmlref .= ' - ' . $project->title;
1201 }
1202 } else {
1203 $morehtmlref .= '';
1204 }
1205 }
1206 }
1207 $morehtmlref .= '</div>';
1208
1209 $morehtmlstatus = '';
1210
1211 dol_banner_tab($object, 'ref', $linkback, 1, 'title', 'none', $morehtmlref, '', 0, '', $morehtmlstatus);
1212
1213 print '<div class="fichecenter">';
1214 print '<div class="fichehalfleft">';
1215 print '<div class="underbanner clearboth"></div>';
1216
1217 print '<table class="border centpercent tableforfield">';
1218
1219 // Invoice subtype
1220 if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED')) {
1221 print "<tr><td>".$langs->trans("InvoiceSubtype")."</td><td>";
1222 print $object->getSubtypeLabel('facture_fourn_rec');
1223 print "</td></tr>";
1224 }
1225
1226 print '<tr><td class="titlefield">' . $langs->trans('Author') . '</td><td>';
1227 print $author->getNomUrl(-1);
1228 print "</td></tr>";
1229
1230 // Label
1231 print '<tr>';
1232 print '<td>' . $form->editfieldkey("Label", 'libelle', $object->libelle, $object, $usercancreate) . '</td>';
1233 print '<td>' . $form->editfieldval("Label", 'libelle', $object->libelle, $object, $usercancreate) . '</td>';
1234 print '</tr>';
1235
1236 print '<tr><td>' . $langs->trans('AmountHT') . '</td>';
1237 print '<td>' . price($object->total_ht, 0, $langs, 1, -1, -1, $conf->currency) . '</td>';
1238 print '</tr>';
1239
1240 print '<tr><td>' . $langs->trans("AmountVAT") . '</td><td>' . price($object->total_tva, 0, $langs, 1, -1, -1, $conf->currency) . '</td>';
1241 print '</tr>';
1242
1243 // Amount Local Taxes
1244 if (($mysoc->localtax1_assuj == "1" && $mysoc->useLocalTax(1)) || $object->total_localtax1 != 0) { // Localtax1
1245 print '<tr><td>' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
1246 print '<td class="nowrap">' . price($object->total_localtax1, 1, '', 1, -1, -1, $conf->currency) . '</td></tr>';
1247 }
1248 if (($mysoc->localtax2_assuj == "1" && $mysoc->useLocalTax(2)) || $object->total_localtax2 != 0) { // Localtax2
1249 print '<tr><td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
1250 print '<td class=nowrap">' . price($object->total_localtax2, 1, '', 1, -1, -1, $conf->currency) . '</td></tr>';
1251 }
1252
1253 print '<tr><td>' . $langs->trans("AmountTTC") . '</td><td colspan="3">' . price($object->total_ttc, 0, $langs, 1, -1, -1, $conf->currency) . '</td>';
1254 print '</tr>';
1255
1256 // Payment term
1257 print '<tr><td>';
1258 print '<table class="nobordernopadding centpercent"><tr><td>';
1259 print $langs->trans('PaymentConditionsShort');
1260 print '</td>';
1261 if ($action != 'editconditions' && $usercancreate) {
1262 print '<td class="right"><a class="editfielda" href="' . $_SERVER["PHP_SELF"] . '?action=editconditions&token=' . newToken() . '&facid=' . $object->id . '">' . img_edit($langs->trans('SetConditions'), 1) . '</a></td>';
1263 }
1264 print '</tr></table>';
1265 print '</td><td>';
1266 if ($action == 'editconditions') {
1267 $form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->cond_reglement_id, 'cond_reglement_id');
1268 } else {
1269 $form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->cond_reglement_id, 'none');
1270 }
1271
1272 print '</td></tr>';
1273
1274 // Payment mode
1275 print '<tr><td>';
1276 print '<table class="nobordernopadding" width="100%"><tr><td>';
1277 print $langs->trans('PaymentMode');
1278 print '</td>';
1279 if ($action != 'editmode' && $usercancreate) {
1280 print '<td class="right"><a class="editfielda" href="' . $_SERVER["PHP_SELF"] . '?action=editmode&token=' . newToken() . '&facid=' . $object->id . '">' . img_edit($langs->trans('SetMode'), 1) . '</a></td>';
1281 }
1282 print '</tr></table>';
1283 print '</td><td>';
1284 if ($action == 'editmode') {
1285 $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->mode_reglement_id, 'mode_reglement_id', 'CRDT', 1, 1);
1286 } else {
1287 $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->mode_reglement_id, 'none');
1288 }
1289 print '</td></tr>';
1290
1291 // Multicurrency
1292 if (isModEnabled("multicurrency")) {
1293 // Multicurrency code
1294 print '<tr>';
1295 print '<td>';
1296 print '<table class="nobordernopadding" width="100%"><tr><td>';
1297 print $form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0);
1298 print '</td>';
1299 if ($usercancreate && $action != 'editmulticurrencycode' && $object->suspended == $object::STATUS_SUSPENDED) {
1300 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>';
1301 }
1302 print '</tr></table>';
1303 print '</td><td>';
1304 $htmlname = (($usercancreate && $action == 'editmulticurrencycode') ? 'multicurrency_code' : 'none');
1305 $form->form_multicurrency_code($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_code, $htmlname);
1306 print '</td></tr>';
1307
1308 // Multicurrency rate
1309 if ($object->multicurrency_code != $conf->currency || $object->multicurrency_tx != 1) {
1310 print '<tr>';
1311 print '<td>';
1312 print '<table class="nobordernopadding" width="100%"><tr><td>';
1313 print $form->editfieldkey('CurrencyRate', 'multicurrency_tx', '', $object, 0);
1314 print '</td>';
1315 if ($usercancreate && $action != 'editmulticurrencyrate' && $object->suspended == $object::STATUS_SUSPENDED && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) {
1316 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>';
1317 }
1318 print '</tr></table>';
1319 print '</td><td>';
1320 if ($action == 'editmulticurrencyrate' || $action == 'actualizemulticurrencyrate') {
1321 if ($action == 'actualizemulticurrencyrate') {
1322 list($object->fk_multicurrency, $object->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($object->db, $object->multicurrency_code);
1323 }
1324 $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, ($usercancreate ? 'multicurrency_tx' : 'none'), $object->multicurrency_code);
1325 } else {
1326 $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'none', $object->multicurrency_code);
1327 if ($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) {
1328 print '<div class="inline-block"> &nbsp; &nbsp; &nbsp; &nbsp; ';
1329 print '<a href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=actualizemulticurrencyrate">' . $langs->trans("ActualizeCurrency") . '</a>';
1330 print '</div>';
1331 }
1332 }
1333 print '</td></tr>';
1334 }
1335 }
1336
1337 // Help of substitution key
1338 $dateexample = dol_now();
1339 if (!empty($object->frequency) && !empty($object->date_when)) {
1340 $dateexample = $object->date_when;
1341 }
1342
1343 $substitutionarray = getCommonSubstitutionArray($langs, 2, null, $object);
1344
1345 $substitutionarray['__INVOICE_PREVIOUS_MONTH__'] = $langs->trans("PreviousMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%m') . ')';
1346 $substitutionarray['__INVOICE_MONTH__'] = $langs->trans("MonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($dateexample, '%m') . ')';
1347 $substitutionarray['__INVOICE_NEXT_MONTH__'] = $langs->trans("NextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%m') . ')';
1348 $substitutionarray['__INVOICE_PREVIOUS_MONTH_TEXT__'] = $langs->trans("TextPreviousMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%B') . ')';
1349 $substitutionarray['__INVOICE_MONTH_TEXT__'] = $langs->trans("TextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($dateexample, '%B') . ')';
1350 $substitutionarray['__INVOICE_NEXT_MONTH_TEXT__'] = $langs->trans("TextNextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%B') . ')';
1351 $substitutionarray['__INVOICE_PREVIOUS_YEAR__'] = $langs->trans("PreviousYearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, -1, 'y'), '%Y') . ')';
1352 $substitutionarray['__INVOICE_YEAR__'] = $langs->trans("YearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($dateexample, '%Y') . ')';
1353 $substitutionarray['__INVOICE_NEXT_YEAR__'] = $langs->trans("NextYearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, 1, 'y'), '%Y') . ')';
1354 // Only on template invoices
1355 $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') . ')';
1356 $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') . ')';
1357 $substitutionarray['__INVOICE_COUNTER_CURRENT__'] = $object->nb_gen_done;
1358 $substitutionarray['__INVOICE_COUNTER_MAX__'] = $object->nb_gen_max;
1359
1360 $htmltext = '<i>' . $langs->trans("FollowingConstantsWillBeSubstituted") . ':<br>';
1361 foreach ($substitutionarray as $key => $val) {
1362 $htmltext .= $key . ' = ' . $langs->trans($val) . '<br>';
1363 }
1364 $htmltext .= '</i>';
1365
1366 // Bank Account
1367 print '<tr><td class="nowrap">';
1368 print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
1369 print $langs->trans('BankAccount');
1370 print '<td>';
1371 if ($action != 'editbankaccount' && $usercancreate && $object->statut == FactureFournisseurRec::STATUS_NOTSUSPENDED) {
1372 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>';
1373 }
1374 print '</tr></table>';
1375 print '</td><td>';
1376 if ($action == 'editbankaccount') {
1377 $form->formSelectAccount($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_account, 'fk_account', 1);
1378 } else {
1379 $form->formSelectAccount($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_account, 'none');
1380 }
1381 print "</td>";
1382 print '</tr>';
1383
1384 // Extrafields
1385 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1386
1387 // Note public
1388 print '<tr><td>';
1389 print $form->editfieldkey($form->textwithpicto($langs->trans('NotePublic'), $htmltext, 1, 'help', '', 0, 2, 'notepublic'), 'note_public', $object->note_public, $object, $user->hasRight('facture', 'creer'));
1390 print '</td><td class="wordbreak">';
1391 print $form->editfieldval($langs->trans("NotePublic"), 'note_public', $object->note_public, $object, $user->hasRight('facture', 'creer'), 'textarea:'.ROWS_4.':90%', '', null, null, '', 1);
1392 print '</td>';
1393 print '</tr>';
1394
1395 // Note private
1396 print '<tr><td>';
1397 print $form->editfieldkey($form->textwithpicto($langs->trans("NotePrivate"), $htmltext, 1, 'help', '', 0, 2, 'noteprivate'), 'note_private', $object->note_private, $object, $user->hasRight('facture', 'creer'));
1398 print '</td><td class="wordbreak">';
1399 print $form->editfieldval($langs->trans("NotePrivate"), 'note_private', $object->note_private, $object, $user->hasRight('facture', 'creer'), 'textarea:'.ROWS_4.':90%', '', null, null, '', 1);
1400 print '</td>';
1401 print '</tr>';
1402
1403 // Model pdf
1404 print '<tr><td class="nowrap">';
1405 print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
1406 print $langs->trans('Model');
1407 print '<td>';
1408 if ($action != 'editmodelpdf' && $usercancreate && $object->statut == FactureFournisseurRec::STATUS_NOTSUSPENDED) {
1409 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>';
1410 }
1411 print '</tr></table>';
1412 print '</td><td>';
1413 if ($action == 'editmodelpdf') {
1414 include_once DOL_DOCUMENT_ROOT . '/core/modules/supplier_invoice/modules_facturefournisseur.php';
1415 $list = array();
1417 foreach ($models as $k => $model) {
1418 $list[] = str_replace(':', '|', $k) . ':' . $model;
1419 }
1420 $select = 'select;' . implode(',', $list);
1421 //TODO : Droits
1422 print $form->editfieldval($langs->trans('Model'), 'modelpdf', $object->model_pdf, $object, $usercancreate, $select);
1423 } else {
1424 print $object->model_pdf;
1425 }
1426 print "</td>";
1427 print '</tr>';
1428
1429 // Other attributes
1430 $cols = 2;
1431
1432 print '</table>';
1433
1434 print '</div>';
1435 print '<div class="fichehalfright">';
1436 print '<div class="underbanner clearboth"></div>';
1437
1438 /*
1439 * Recurrence
1440 */
1441 $title = $langs->trans("Recurrence");
1442 //print load_fiche_titre($title, '', 'calendar');
1443
1444 print '<table class="border centpercent tableforfield">';
1445
1446 print '<tr><td colspan="2">' . img_picto('', 'recurring', 'class="pictofixedwidth"') . $title . '</td></tr>';
1447
1448 // if "frequency" is empty or = 0, the recurrence is disabled
1449 print '<tr><td style="width: 50%">';
1450 print '<table class="nobordernopadding" width="100%"><tr><td>';
1451 print $langs->trans('Frequency');
1452 print '</td>';
1453 if ($action != 'editfrequency' && $usercancreate) {
1454 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>';
1455 }
1456 print '</tr></table>';
1457 print '</td><td>';
1458 if ($action == 'editfrequency') {
1459 print '<form method="post" action="' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '">';
1460 print '<input type="hidden" name="action" value="setfrequency">';
1461 print '<input type="hidden" name="token" value="' . newToken() . '">';
1462 print '<table class="nobordernopadding">';
1463 print '<tr><td>';
1464 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'));
1465 print '</td>';
1466 print '<td class="left"><input type="submit" class="button button-edit" value="' . $langs->trans("Modify") . '"></td>';
1467 print '</tr></table></form>';
1468 } else {
1469 if ($object->frequency > 0) {
1470 print $langs->trans('FrequencyPer_' . $object->unit_frequency, $object->frequency);
1471 } else {
1472 print $langs->trans("NotARecurringInvoiceTemplate");
1473 }
1474 }
1475 print '</td></tr>';
1476
1477 // Date when (next invoice generation)
1478 print '<tr><td>';
1479 if ($action == 'date_when' || $object->frequency > 0) {
1480 print $form->editfieldkey($langs->trans("NextDateToExecution"), 'date_when', $object->date_when, $object, $usercancreate, 'day');
1481 } else {
1482 print $langs->trans("NextDateToExecution");
1483 }
1484 print '</td><td>';
1485 if ($action == 'date_when' || $object->frequency > 0) {
1486 print $form->editfieldval($langs->trans("NextDateToExecution"), 'date_when', $object->date_when, $object, $usercancreate, 'day', $object->date_when, null, '', '', 0, 'strikeIfMaxNbGenReached');
1487 }
1488 //var_dump(dol_print_date($object->date_when+60, 'dayhour').' - '.dol_print_date($now, 'dayhour'));
1489 if (! $object->isMaxNbGenReached()) {
1490 if (! $object->suspended && $action != 'editdate_when' && $object->frequency > 0 && $object->date_when && $object->date_when < $now) {
1491 print img_warning($langs->trans("Late"));
1492 }
1493 } else {
1494 print img_info($langs->trans("MaxNumberOfGenerationReached"));
1495 }
1496 print '</td>';
1497 print '</tr>';
1498
1499 // Max period / Rest period
1500 print '<tr><td>';
1501 if ($action == 'nb_gen_max' || $object->frequency > 0) {
1502 print $form->editfieldkey($langs->trans("MaxPeriodNumber"), 'nb_gen_max', $object->nb_gen_max, $object, $usercancreate);
1503 } else {
1504 print $langs->trans("MaxPeriodNumber");
1505 }
1506 print '</td><td>';
1507 if ($action == 'nb_gen_max' || $object->frequency > 0) {
1508 print $form->editfieldval($langs->trans("MaxPeriodNumber"), 'nb_gen_max', $object->nb_gen_max ? $object->nb_gen_max : '', $object, $usercancreate);
1509 } else {
1510 print '';
1511 }
1512 print '</td>';
1513 print '</tr>';
1514
1515 // Status of generated invoices
1516 print '<tr><td>';
1517 if ($action == 'auto_validate' || $object->frequency > 0) {
1518 print $form->editfieldkey($langs->trans("StatusOfAutoGeneratedInvoices"), 'auto_validate', $object->auto_validate, $object, $usercancreate);
1519 } else {
1520 print $langs->trans("StatusOfAutoGeneratedInvoices");
1521 }
1522 print '</td><td>';
1523 $select = 'select;0:' . $langs->trans('BillStatusDraft') . ',1:' . $langs->trans('BillStatusValidated');
1524 if ($action == 'auto_validate' || $object->frequency > 0) {
1525 print $form->editfieldval($langs->trans("StatusOfAutoGeneratedInvoices"), 'auto_validate', $object->auto_validate, $object, $usercancreate, $select);
1526 }
1527 print '</td>';
1528 // Auto generate documents
1529 if (getDolGlobalString('INVOICE_REC_CAN_DISABLE_DOCUMENT_FILE_GENERATION')) {
1530 print '<tr>';
1531 print '<td>';
1532 if ($action == 'generate_pdf' || $object->frequency > 0) {
1533 print $form->editfieldkey($langs->trans("StatusOfGeneratedDocuments"), 'generate_pdf', $object->generate_pdf, $object, $usercancreate);
1534 } else {
1535 print $langs->trans("StatusOfGeneratedDocuments");
1536 }
1537 print '</td>';
1538 print '<td>';
1539 $select = 'select;0:' . $langs->trans('DoNotGenerateDoc') . ',1:' . $langs->trans('AutogenerateDoc');
1540 if ($action == 'generate_pdf' || $object->frequency > 0) {
1541 print $form->editfieldval($langs->trans("StatusOfGeneratedDocuments"), 'generate_pdf', $object->generate_pdf, $object, $usercancreate, $select);
1542 }
1543 print '</td>';
1544 print '</tr>';
1545 } else {
1546 print '<input type="hidden" name="generate_pdf" value="1">';
1547 }
1548
1549 print '</table>';
1550
1551 // Frequencry/Recurring section
1552 if ($object->frequency > 0) {
1553 print '<br>';
1554
1555 if (empty($conf->cron->enabled)) {
1556 print info_admin($langs->trans("EnableAndSetupModuleCron", $langs->transnoentitiesnoconv("Module2300Name")));
1557 }
1558
1559 print '<div class="underbanner clearboth"></div>';
1560 print '<table class="border centpercent tableforfield">';
1561
1562 // Nb of generation already done
1563 print '<tr><td style="width: 50%">' . $langs->trans("NbOfGenerationDone") . '</td>';
1564 print '<td>';
1565 print $object->nb_gen_done ? $object->nb_gen_done : '0';
1566 print '</td>';
1567 print '</tr>';
1568
1569 // Date last
1570 print '<tr><td>';
1571 print $langs->trans("DateLastGeneration");
1572 print '</td><td>';
1573 print dol_print_date($object->date_last_gen, 'dayhour');
1574 print '</td>';
1575 print '</tr>';
1576
1577 print '</table>';
1578
1579 print '<br>';
1580 }
1581
1582 print '</div>';
1583 print '</div>';
1584
1585 print '<div class="clearboth"></div><br>';
1586
1587 // Lines
1588 print ' <form name="addproduct" id="addproduct" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . (($action != 'editline') ? '#add' : '#line_' . GETPOSTINT('lineid')) . '" method="POST">
1589 <input type="hidden" name="token" value="' . newToken() . '">
1590 <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline') . '">
1591 <input type="hidden" name="mode" value="">
1592 <input type="hidden" name="id" value="' . $object->id . '">
1593 ';
1594
1595 if (!empty($conf->use_javascript_ajax) && $object->statut == 0) {
1596 include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
1597 }
1598
1599 print '<div class="div-table-responsive-no-min">';
1600 print '<table id="tablelines" class="noborder noshadow" width="100%">';
1601 $object->fetch_lines();
1602 // Show object lines
1603 if (!empty($object->lines)) {
1604 $canchangeproduct = 1;
1605 // To set ref for getNomURL function
1606 foreach ($object->lines as $line) {
1607 $line->ref = $line->label;
1608 $line->product_label = $line->label;
1609 $line->subprice = $line->pu_ht;
1610 }
1611
1612 global $canchangeproduct;
1613 $canchangeproduct = 0;
1614
1615 $object->statut = $object->suspended;
1616 $object->printObjectLines($action, $object->thirdparty, $mysoc, $lineid, 0); // No date selector for template invoice
1617 }
1618
1619 // Form to add new line
1620 //TODO : Droits
1621 if ($object->statut == $object::STATUS_DRAFT && $usercancreate && $action != 'valid' && $action != 'editline') {
1622 if ($action != 'editline') {
1623 // Add free products/services
1624
1625 $parameters = array();
1626 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1627 if ($reshook < 0) {
1628 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1629 }
1630 if (empty($reshook)) {
1631 global $senderissupplier;
1632 }
1633 $senderissupplier = 2;
1634 $object->formAddObjectLine(0, $object->thirdparty, $mysoc); // No date selector for template invoice
1635 }
1636 }
1637
1638 print "</table>\n";
1639 print '</div>';
1640
1641 print "</form>\n";
1642
1643 print dol_get_fiche_end();
1644
1645 /*
1646 * Action bar
1647 */
1648 print '<div class="tabsAction">';
1649
1650 if (empty($object->suspended)) {
1651 if ($usercancreate) {
1652 if (!empty($object->frequency) && $object->nb_gen_max > 0 && ($object->nb_gen_done >= $object->nb_gen_max)) {
1653 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' . dol_escape_htmltag($langs->trans("MaxGenerationReached")) . '">' . $langs->trans("CreateBill") . '</a></div>';
1654 } else {
1655 if (empty($object->frequency) || $object->date_when <= $nowlasthour) {
1656 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>';
1657 } else {
1658 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' . dol_escape_htmltag($langs->trans("DateIsNotEnough")) . '">' . $langs->trans("CreateBill") . '</a></div>';
1659 }
1660 }
1661 } else {
1662 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#">' . $langs->trans("CreateBill") . '</a></div>';
1663 }
1664 }
1665
1666 if ($usercancreate) {
1667 if (empty($object->suspended)) {
1668 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>';
1669 } else {
1670 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>';
1671 }
1672 }
1673
1674 // Delete
1675 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")));
1676
1677 print '</div>';
1678
1679 print '<div class="fichecenter"><div class="fichehalfleft">';
1680 print '<a name="builddoc"></a>'; // ancre
1681
1682 // Show links to link elements
1683 $linktoelem = $form->showLinkToObjectBlock($object, null, array('invoice'));
1684
1685 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
1686
1687 print '</div></div>';
1688 }
1689}
1690
1691// End of page
1692llxFooter();
1693$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.