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