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