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