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