dolibarr 24.0.1
card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2002-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2020 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2004 Christophe Combelles <ccomb@free.fr>
5 * Copyright (C) 2005 Marc Barilley <marc@ocebo.fr>
6 * Copyright (C) 2005-2013 Regis Houssin <regis.houssin@inodbox.com>
7 * Copyright (C) 2010-2023 Juanjo Menent <jmenent@simnandez.es>
8 * Copyright (C) 2013-2022 Philippe Grand <philippe.grand@atoo-net.com>
9 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
10 * Copyright (C) 2014-2016 Marcos García <marcosgdf@gmail.com>
11 * Copyright (C) 2016-2026 Alexandre Spangaro <alexandre@inovea-conseil.com>
12 * Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
13 * Copyright (C) 2019 Ferran Marcet <fmarcet@2byte.es>
14 * Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
15 * Copyright (C) 2023 Nick Fragoulis
16 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
17 * Copyright (C) 2026 Vincent de Grandpré <vincent@de-grandpre.quebec>
18 * Copyright (C) 2026 Lionel Vessiller <lvessiller@open-dsi.fr>
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 3 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program. If not, see <https://www.gnu.org/licenses/>.
32 */
33
40// Load Dolibarr environment
41require '../../main.inc.php';
50require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
51require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
52require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php';
53require_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_invoice/modules_facturefournisseur.php';
54require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
55require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture-rec.class.php';
56require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php';
57require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
58require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php';
59require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
60require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
61require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
62if (isModEnabled("product")) {
63 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
64 require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
65}
66if (isModEnabled('project')) {
67 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
68 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
69}
70
71if (isModEnabled('variants')) {
72 require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination.class.php';
73}
74if (isModEnabled('accounting')) {
75 require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
76}
77
78$langs->loadLangs(array('bills', 'compta', 'suppliers', 'companies', 'products', 'banks', 'admin'));
79if (isModEnabled('incoterm')) {
80 $langs->load('incoterm');
81}
82
83$id = (GETPOSTINT('facid') ? GETPOSTINT('facid') : GETPOSTINT('id'));
84
85$action = GETPOST('action', 'aZ09');
86$confirm = GETPOST("confirm");
87$ref = GETPOST('ref', 'alpha');
88$cancel = GETPOST('cancel', 'alpha');
89$backtopage = GETPOST('backtopage', 'alpha');
90$backtopageforcancel = '';
91
92$lineid = GETPOSTINT('lineid');
93$projectid = GETPOSTINT('projectid');
94$origin = GETPOST('origin', 'alpha');
95$originid = GETPOSTINT('originid');
96$fac_recid = GETPOSTINT('fac_rec');
97$rank = (GETPOSTINT('rank') > 0) ? GETPOSTINT('rank') : -1;
98
99$date_pointoftax = dol_mktime(12, 0, 0, GETPOSTINT('date_pointoftaxmonth'), GETPOSTINT('date_pointoftaxday'), GETPOSTINT('date_pointoftaxyear'), 'tzserver');
100
101// PDF
102$hidedetails = (GETPOSTINT('hidedetails') ? GETPOSTINT('hidedetails') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS') ? 1 : 0));
103$hidedesc = (GETPOSTINT('hidedesc') ? GETPOSTINT('hidedesc') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DESC') ? 1 : 0));
104$hideref = (GETPOSTINT('hideref') ? GETPOSTINT('hideref') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF') ? 1 : 0));
105
106// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
107$hookmanager->initHooks(array('invoicesuppliercard', 'globalcard'));
108
110$extrafields = new ExtraFields($db);
111
112// fetch optionals attributes and labels
113$extrafields->fetch_name_optionals_label($object->table_element);
114
115// Load object
116if ($id > 0 || !empty($ref)) {
117 $ret = $object->fetch($id, $ref);
118 if ($ret < 0) {
119 dol_print_error($db, $object->error);
120 }
121 $ret = $object->fetch_thirdparty();
122 if ($ret < 0) {
123 dol_print_error($db, $object->error);
124 }
125}
126
127// Security check
128$socid = GETPOSTINT('socid');
129if (!empty($user->socid)) {
130 $socid = $user->socid;
131}
132
133$isdraft = (($object->status == FactureFournisseur::STATUS_DRAFT) ? 1 : 0);
134$result = restrictedArea($user, 'fournisseur', $id, 'facture_fourn', 'facture', 'fk_soc', 'rowid', $isdraft);
135
136// Common permissions
137$usercanread = ($user->hasRight("fournisseur", "facture", "lire") || $user->hasRight("supplier_invoice", "lire"));
138$usercancreate = ($user->hasRight("fournisseur", "facture", "creer") || $user->hasRight("supplier_invoice", "creer"));
139$usercandelete = (($user->hasRight("fournisseur", "facture", "supprimer") || $user->hasRight("supplier_invoice", "supprimer")) || ($usercancreate && $object->is_erasable() == 1));
140$usercancreatecontract = $user->hasRight("contrat", "creer");
141
142// Advanced permissions
143$usercanvalidate = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !empty($usercancreate)) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight("fournisseur", "supplier_invoice_advance", "validate")));
144$usercansend = (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->hasRight("fournisseur", "supplier_invoice_advance", "send"));
145$usercancreatecreditransfer = $user->hasRight('paymentbybanktransfer', 'create');
146
147// Permissions for includes
148$permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php
149$permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php
150$permissiontoedit = $usercancreate; // Used by the include of actions_lineupdown.inc.php
151$permissiontoadd = $usercancreate; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
152$permissiontodelete = $usercandelete;
153$permissiontoeditextra = $permissiontoadd;
154if (GETPOST('attribute', 'aZ09') && isset($extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')])) {
155 // For action 'update_extras', is there a specific permission set for the attribute to update
156 $permissiontoeditextra = dol_eval((string) $extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')]);
157}
158
159$error = 0;
160$classname = null;
161
162
163/*
164 * Actions
165 */
166
167$parameters = array('socid' => $socid);
168$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
169if ($reshook < 0) {
170 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
171}
172
173if (empty($reshook)) {
174 $backurlforlist = dolBuildUrl(DOL_URL_ROOT.'/fourn/facture/list.php');
175
176 if (empty($backtopage) || ($cancel && empty($id))) {
177 if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
178 if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
179 $backtopage = $backurlforlist;
180 } else {
181 $backtopage = dolBuildUrl(DOL_URL_ROOT.'/fourn/facture/card.php', ['id' => ((!empty($id) && $id > 0) ? $id : '__ID__')]);
182 }
183 }
184 }
185
186 if ($cancel) {
187 if (!empty($backtopageforcancel)) {
188 header("Location: ".$backtopageforcancel);
189 exit;
190 } elseif (!empty($backtopage)) {
191 header("Location: ".$backtopage);
192 exit;
193 }
194 $action = '';
195 }
196
197 include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be 'include', not 'include_once'
198
199 include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be 'include', not 'include_once'
200
201 include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be 'include', not 'include_once'
202
203 // Link invoice to order
204 if (GETPOST('linkedOrder') && empty($cancel) && $id > 0 && $permissiontoadd) {
205 $object->fetch($id);
206 $object->fetch_thirdparty();
207 $result = $object->add_object_linked('order_supplier', GETPOSTINT('linkedOrder'));
208 }
209
210 // Action clone object
211 if ($action == 'confirm_clone' && $confirm == 'yes' && $permissiontoadd) {
212 $objectutil = dol_clone($object, 1); // To avoid to denaturate loaded object when setting some properties for clone. We use native clone to keep this->db valid.
213 '@phan-var-force FactureFournisseur $objectutil'; // Same object type for cloned object
214
215 if (GETPOST('newsupplierref', 'alphanohtml')) {
216 $objectutil->ref_supplier = GETPOST('newsupplierref', 'alphanohtml');
217 }
218 $objectutil->date = dol_mktime(12, 0, 0, GETPOSTINT('newdatemonth'), GETPOSTINT('newdateday'), GETPOSTINT('newdateyear'));
219
220 $result = $objectutil->createFromClone($user, $id);
221 if ($result > 0) {
222 header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
223 exit;
224 } else {
225 $langs->load("errors");
226 setEventMessages($objectutil->error, $objectutil->errors, 'errors');
227 $action = '';
228 }
229 } elseif ($action == 'confirm_valid' && $confirm == 'yes' && $usercanvalidate) {
230 $idwarehouse = GETPOST('idwarehouse');
231
232 $object->fetch($id);
233 $object->fetch_thirdparty();
234
235 $qualified_for_stock_change = 0;
236 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
237 $qualified_for_stock_change = $object->hasProductsOrServices(2);
238 } else {
239 $qualified_for_stock_change = $object->hasProductsOrServices(1);
240 }
241
242 // Check parameters
243 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') && $qualified_for_stock_change) {
244 $langs->load("stocks");
245 if (!$idwarehouse || $idwarehouse == -1) {
246 $error++;
247 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
248 $action = '';
249 }
250 }
251
252 if (!$error) {
253 $db->begin();
254
255 $result = $object->validate($user, '', $idwarehouse);
256 if ($result < 0) {
257 $db->rollback();
258
259 setEventMessages($object->error, $object->errors, 'errors');
260 } else {
261 if (isModEnabled('category')) {
262 $categories = GETPOST('categories', 'array:int');
263 if (method_exists($object, 'setCategories')) {
264 $object->setCategories($categories);
265 }
266 }
267
268 $db->commit();
269
270 // Define output language
271 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
272 $outputlangs = $langs;
273 $newlang = '';
274 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
275 $newlang = GETPOST('lang_id', 'aZ09');
276 }
277 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
278 $newlang = $object->thirdparty->default_lang;
279 }
280 if (!empty($newlang)) {
281 $outputlangs = new Translate("", $conf);
282 $outputlangs->setDefaultLang($newlang);
283 }
284 $model = $object->model_pdf;
285 $ret = $object->fetch($id); // Reload to get new records
286
287 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
288 if ($result < 0) {
289 setEventMessages($object->error, $object->errors, 'errors');
290 }
291 }
292 }
293 }
294 } elseif ($action == 'confirm_delete' && $confirm == 'yes' && $permissiontodelete) {
295 $object->fetch($id);
296 $object->fetch_thirdparty();
297
298 $isErasable = $object->is_erasable();
299
300 if ($usercandelete && $isErasable > 0) {
301 $revertstock = GETPOST('revertstock');
302
303 if ($revertstock) {
304 $idwarehouse = GETPOSTINT('idwarehouse');
305
306 $qualified_for_stock_change = 0;
307 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
308 $qualified_for_stock_change = $object->hasProductsOrServices(2);
309 } else {
310 $qualified_for_stock_change = $object->hasProductsOrServices(1);
311 }
312
313 // Check parameters
314 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') && $qualified_for_stock_change) {
315 $langs->load("stocks");
316 if (!$idwarehouse || $idwarehouse == -1) {
317 $error++;
318 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
319 $action = 'delete';
320 } else {
321 $result = $object->setDraft($user, $idwarehouse);
322 if ($result < 0) {
323 $error++;
324 }
325 }
326 }
327 }
328
329 if (!$error) {
330 $result = $object->delete($user);
331 if ($result > 0) {
332 header('Location: list.php?restore_lastsearch_values=1');
333 exit;
334 } else {
335 setEventMessages($object->error, $object->errors, 'errors');
336 }
337 }
338 }
339 } elseif ($action == 'confirm_deleteline' && $confirm == 'yes' && $usercancreate) {
340 // Remove a product line
341 $result = $object->deleteLine($lineid);
342 if ($result > 0) {
343 // reorder lines
344 $object->line_order(true);
345 // Define output language
346 /*$outputlangs = $langs;
347 $newlang = '';
348 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id','aZ09'))
349 $newlang = GETPOST('lang_id','aZ09');
350 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang))
351 $newlang = $object->thirdparty->default_lang;
352 if (!empty($newlang)) {
353 $outputlangs = new Translate("", $conf);
354 $outputlangs->setDefaultLang($newlang);
355 }
356 if (!getDolGlobalStringempty('MAIN_DISABLE_PDF_AUTOUPDATE')) {
357 $ret = $object->fetch($object->id); // Reload to get new records
358 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
359 }*/
360
361 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
362 exit;
363 } else {
364 setEventMessages($object->error, $object->errors, 'errors');
365 /* Fix bug 1485 : Reset action to avoid asking again confirmation on failure */
366 $action = '';
367 }
368 } elseif ($action == 'unlinkdiscount' && $usercancreate) {
369 // Delete link of credit note to invoice
370 $discount = new DiscountAbsolute($db);
371 $result = $discount->fetch(GETPOSTINT("discountid"));
372 $discount->unlink_invoice();
373 } elseif ($action == 'confirm_paid' && $confirm == 'yes' && $usercancreate) {
374 $object->fetch($id);
375 $result = $object->setPaid($user);
376 if ($result < 0) {
377 setEventMessages($object->error, $object->errors, 'errors');
378 }
379 } elseif ($action == 'confirm_paid_partially' && $confirm == 'yes' && $usercancreate) {
380 // Classif "paid partially"
381 $object->fetch($id);
382 $close_code = GETPOST("close_code", 'restricthtml');
383 $close_note = GETPOST("close_note", 'restricthtml');
384 if ($close_code) {
385 $result = $object->setPaid($user, $close_code, $close_note);
386 if ($result < 0) {
387 setEventMessages($object->error, $object->errors, 'errors');
388 }
389 } else {
390 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), null, 'errors');
391 }
392 } elseif ($action == 'confirm_canceled' && $confirm == 'yes' && $usercancreate) {
393 // Classify "abandoned"
394 $object->fetch($id);
395 $close_code = GETPOST("close_code", 'restricthtml');
396 $close_note = GETPOST("close_note", 'restricthtml');
397 if ($close_code) {
398 $result = $object->setCanceled($user, $close_code, $close_note);
399 if ($result < 0) {
400 setEventMessages($object->error, $object->errors, 'errors');
401 }
402 } else {
403 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), null, 'errors');
404 }
405 }
406
407 // Set supplier ref
408 if ($action == 'setref_supplier' && $usercancreate) {
409 $object->ref_supplier = GETPOST('ref_supplier', 'alpha');
410
411 if ($object->update($user) < 0) {
412 setEventMessages($object->error, $object->errors, 'errors');
413 } else {
414 // Define output language
415 $outputlangs = $langs;
416 $newlang = '';
417 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
418 $newlang = GETPOST('lang_id', 'aZ09');
419 }
420 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
421 $newlang = $object->thirdparty->default_lang;
422 }
423 if (!empty($newlang)) {
424 $outputlangs = new Translate("", $conf);
425 $outputlangs->setDefaultLang($newlang);
426 }
427 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
428 $ret = $object->fetch($object->id); // Reload to get new records
429 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
430 }
431 }
432 }
433
434 // payments conditions
435 if ($action == 'setconditions' && $usercancreate) {
436 $object->fetch($id);
437 $object->cond_reglement_code = 0; // To clean property
438 $object->cond_reglement_id = 0; // To clean property
439
440 $error = 0;
441
442 $db->begin();
443
444 if (!$error) {
445 $result = $object->setPaymentTerms(GETPOSTINT('cond_reglement_id'));
446 if ($result < 0) {
447 $error++;
448 setEventMessages($object->error, $object->errors, 'errors');
449 }
450 }
451
452 if (!$error) {
453 $new_date_echeance = $object->calculate_date_lim_reglement();
454 if ($new_date_echeance) {
455 $object->date_echeance = $new_date_echeance;
456 }
457 if ($object->date_echeance < $object->date) {
458 $object->date_echeance = $object->date;
459 }
460 $result = $object->update($user);
461 if ($result < 0) {
462 $error++;
463 setEventMessages($object->error, $object->errors, 'errors');
464 }
465 }
466
467 if ($error) {
468 $db->rollback();
469 } else {
470 $db->commit();
471 }
472 } elseif ($action == 'set_incoterms' && isModEnabled('incoterm') && $usercancreate) {
473 // Set incoterm
474 $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOST('location_incoterms'));
475 } elseif ($action == 'settags' && isModEnabled('category') && $usercancreate) {
476 // Set tags
477 $result = $object->setCategories(GETPOST('categories', 'array'));
478 } elseif ($action == 'setmode' && $usercancreate) {
479 // payment mode
480 $result = $object->setPaymentMethods(GETPOSTINT('mode_reglement_id'));
481 } elseif ($action == 'setmulticurrencycode' && $usercancreate) {
482 // Multicurrency Code
483 $result = $object->setMulticurrencyCode(GETPOST('multicurrency_code', 'alpha'));
484 } elseif ($action == 'setmulticurrencyrate' && $usercancreate) {
485 // Multicurrency rate
486 $result = $object->setMulticurrencyRate((float) price2num(GETPOST('multicurrency_tx', 'alpha')), GETPOSTINT('calculation_mode'));
487 } elseif ($action == 'setbankaccount' && $usercancreate) {
488 // bank account
489 $result = $object->setBankAccount(GETPOSTINT('fk_account'));
490 } elseif ($action == 'setvatreversecharge' && $usercancreate) {
491 // vat reverse charge
492 $vatreversecharge = GETPOST('vat_reverse_charge') == 'on' ? 1 : 0;
493 $result = $object->setVATReverseCharge($vatreversecharge);
494 }
495
496 if ($action == 'settransportmode' && $usercancreate) {
497 // transport mode
498 $result = $object->setTransportMode(GETPOSTINT('transport_mode_id'));
499 } elseif ($action == 'setlabel' && $usercancreate) {
500 // Set label
501 $object->fetch($id);
502 $object->label = GETPOST('label');
503 $result = $object->update($user);
504 if ($result < 0) {
505 setEventMessages($object->error, $object->errors, 'errors');
506 }
507 } elseif ($action == 'setdatef' && $usercancreate) {
508 $newdate = dol_mktime(0, 0, 0, GETPOSTINT('datefmonth'), GETPOSTINT('datefday'), GETPOSTINT('datefyear'), 'tzserver');
509 if ($newdate > (dol_now('tzuserrel') + getDolGlobalInt('INVOICE_MAX_FUTURE_DELAY'))) {
510 if (!getDolGlobalString('INVOICE_MAX_FUTURE_DELAY')) {
511 setEventMessages($langs->trans("WarningInvoiceDateInFuture"), null, 'warnings');
512 } else {
513 setEventMessages($langs->trans("WarningInvoiceDateTooFarInFuture"), null, 'warnings');
514 }
515 }
516
517 $object->fetch($id);
518
519 $object->date = $newdate;
520 $date_echence_calc = $object->calculate_date_lim_reglement();
521 if (!empty($object->date_echeance)) {
522 $object->date_echeance = $date_echence_calc;
523 }
524 if ($object->date_echeance && $object->date_echeance < $object->date) {
525 $object->date_echeance = $object->date;
526 }
527
528 $result = $object->update($user);
529 if ($result < 0) {
530 setEventMessages($object->error, $object->errors, 'errors');
531 }
532 } elseif ($action == 'setdate_pointoftax' && $usercancreate) {
533 $object->fetch($id);
534
535 $date_pointoftax = dol_mktime(0, 0, 0, GETPOSTINT('date_pointoftaxmonth'), GETPOSTINT('date_pointoftaxday'), GETPOSTINT('date_pointoftaxyear'), 'tzserver');
536 $object->date_pointoftax = $date_pointoftax;
537
538 $result = $object->update($user);
539 if ($result < 0) {
540 setEventMessages($object->error, $object->errors, 'errors');
541 $action = 'editdate_pointoftax';
542 }
543 } elseif ($action == 'setdate_lim_reglement' && $usercancreate) {
544 $object->fetch($id);
545 $object->date_echeance = dol_mktime(12, 0, 0, GETPOSTINT('date_lim_reglementmonth'), GETPOSTINT('date_lim_reglementday'), GETPOSTINT('date_lim_reglementyear'));
546 if (!empty($object->date_echeance) && $object->date_echeance < $object->date) {
547 $object->date_echeance = $object->date;
548 setEventMessages($langs->trans("DatePaymentTermCantBeLowerThanObjectDate"), null, 'warnings');
549 }
550 $result = $object->update($user);
551 if ($result < 0) {
552 setEventMessages($object->error, $object->errors, 'errors');
553 }
554 } elseif ($action == "setabsolutediscount" && $usercancreate) {
555 $db->begin();
556 // We use the credit to reduce amount of invoice
557 if (GETPOSTINT("remise_id")) {
558 $ret = $object->fetch($id);
559 if ($ret > 0) {
560 $result = $object->insert_discount(GETPOSTINT("remise_id"));
561 if ($result < 0) {
562 setEventMessages($object->error, $object->errors, 'errors');
563 }
564 } else {
565 dol_print_error($db, $object->error);
566 }
567 }
568 // We use the credit to reduce remain to pay
569 if (GETPOSTINT("remise_id_for_payment")) {
570 require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
571 $discount = new DiscountAbsolute($db);
572 $discount->fetch(GETPOSTINT("remise_id_for_payment"));
573
574 //var_dump($object->getRemainToPay(0));
575 //var_dump($discount->amount_ttc);exit;
576 $remaintopay = $object->getRemainToPay(0);
577 if (price2num($discount->amount_ttc) > price2num($remaintopay)) {
578 // TODO Split the discount in 2 automatically
579 $error++;
580 setEventMessages($langs->trans("ErrorDiscountLargerThanRemainToPaySplitItBefore"), null, 'errors');
581 }
582
583 if (!$error) {
584 $result = $discount->link_to_invoice(0, $id);
585 if ($result < 0) {
586 $error++;
587 setEventMessages($discount->error, $discount->errors, 'errors');
588 }
589 }
590 if (!$error) {
591 $newremaintopay = $object->getRemainToPay(0);
592 if ($newremaintopay == 0) {
593 $object->setPaid($user);
594 }
595 }
596 }
597 if (!$error) {
598 $db->commit();
599 } else {
600 $db->rollback();
601 }
602 if (empty($error) && !getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
603 $outputlangs = $langs;
604 $newlang = '';
605 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
606 $newlang = GETPOST('lang_id', 'aZ09');
607 }
608 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
609 $newlang = $object->thirdparty->default_lang;
610 }
611 if (!empty($newlang)) {
612 $outputlangs = new Translate("", $conf);
613 $outputlangs->setDefaultLang($newlang);
614 }
615 $ret = $object->fetch($id); // Reload to get new records
616
617 $result = $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
618 if ($result < 0) {
619 setEventMessages($object->error, $object->errors, 'errors');
620 }
621 }
622 } elseif ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $usercancreate) {
623 // Convertir en reduc
624 $object->fetch($id);
625 $object->fetch_thirdparty();
626 //$object->fetch_lines(); // Already done into fetch
627
628 // Check if there is already a discount (protection to avoid duplicate creation when resubmit post)
629 $discountcheck = new DiscountAbsolute($db);
630 $result = $discountcheck->fetch(0, 0, $object->id);
631
632 $canconvert = 0;
633 if ($object->type == FactureFournisseur::TYPE_DEPOSIT && empty($discountcheck->id)) {
634 $canconvert = 1; // we can convert deposit into discount if deposit is paid (completely, partially or not at all) and not already converted (see real condition into condition used to show button converttoreduc)
635 }
636 if (($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_STANDARD) && $object->paid == 0 && empty($discountcheck->id)) {
637 $canconvert = 1; // we can convert credit note into discount if credit note is not refunded completely and not already converted and amount of payment is 0 (see also the real condition used as the condition to show button converttoreduc)
638 }
639 if ($canconvert) {
640 $db->begin();
641
642 $amount_ht = $amount_tva = $amount_ttc = array();
643 $multicurrency_amount_ht = $multicurrency_amount_tva = $multicurrency_amount_ttc = array();
644
645 // Loop on each vat rate
646 $i = 0;
647 foreach ($object->lines as $line) {
648 if ($line->product_type < 9 && $line->total_ht != 0) { // Remove lines with product_type greater than or equal to 9 and no need to create discount if amount is null
649 $keyforvatrate = $line->tva_tx.($line->vat_src_code ? ' ('.$line->vat_src_code.')' : '');
650
651 $amount_ht[$keyforvatrate] += $line->total_ht;
652 $amount_tva[$keyforvatrate] += $line->total_tva;
653 $amount_ttc[$keyforvatrate] += $line->total_ttc;
654 $multicurrency_amount_ht[$keyforvatrate] += $line->multicurrency_total_ht;
655 $multicurrency_amount_tva[$keyforvatrate] += $line->multicurrency_total_tva;
656 $multicurrency_amount_ttc[$keyforvatrate] += $line->multicurrency_total_ttc;
657 $i++;
658 }
659 }
660 '@phan-var-force array<string,float> $amount_ht
661 @phan-var-force array<string,float> $amount_tva
662 @phan-var-force array<string,float> $amount_ttc
663 @phan-var-force array<string,float> $multicurrency_amount_ht
664 @phan-var-force array<string,float> $multicurrency_amount_tva
665 @phan-var-force array<string,float> $multicurrency_amount_ttc';
666
667 // If some payments were already done, we change the amount to pay using same prorate
668 if (getDolGlobalString('SUPPLIER_INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED') && $object->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
669 $alreadypaid = $object->getSommePaiement(); // This can be not 0 if we allow to create credit to reuse from credit notes partially refunded.
670 if ($alreadypaid && abs($alreadypaid) < abs($object->total_ttc)) {
671 $ratio = abs(($object->total_ttc - $alreadypaid) / $object->total_ttc);
672 foreach ($amount_ht as $vatrate => $val) {
673 $amount_ht[$vatrate] = price2num($amount_ht[$vatrate] * $ratio, 'MU');
674 $amount_tva[$vatrate] = price2num($amount_tva[$vatrate] * $ratio, 'MU');
675 $amount_ttc[$vatrate] = price2num($amount_ttc[$vatrate] * $ratio, 'MU');
676 $multicurrency_amount_ht[$vatrate] = price2num($multicurrency_amount_ht[$vatrate] * $ratio, 'MU');
677 $multicurrency_amount_tva[$vatrate] = price2num($multicurrency_amount_tva[$vatrate] * $ratio, 'MU');
678 $multicurrency_amount_ttc[$vatrate] = price2num($multicurrency_amount_ttc[$vatrate] * $ratio, 'MU');
679 }
680 }
681 }
682 //var_dump($amount_ht);var_dump($amount_tva);var_dump($amount_ttc);exit;
683
684 // Insert one discount by VAT rate category
685 $discount = new DiscountAbsolute($db);
687 $discount->description = '(CREDIT_NOTE)';
688 } elseif ($object->type == FactureFournisseur::TYPE_DEPOSIT) {
689 $discount->description = '(DEPOSIT)';
691 $discount->description = '(EXCESS PAID)';
692 } else {
693 setEventMessages($langs->trans('CantConvertToReducAnInvoiceOfThisType'), null, 'errors');
694 }
695 $discount->discount_type = 1; // Supplier discount
696 $discount->fk_soc = $object->socid;
697 $discount->socid = $object->socid;
698 $discount->fk_invoice_supplier_source = $object->id;
699
700 $error = 0;
701
703 // If we're on a standard invoice, we have to get excess paid to create a discount in TTC without VAT
704
705 // Total payments
706 $sql = 'SELECT SUM(pf.amount) as total_paiements';
707 $sql .= ' FROM '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf, '.MAIN_DB_PREFIX.'paiementfourn as p';
708 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id AND c.entity IN ('.getEntity('c_paiement').')';
709 $sql .= ' WHERE pf.fk_facturefourn = '.((int) $object->id);
710 $sql .= ' AND pf.fk_paiementfourn = p.rowid';
711 $sql .= ' AND p.entity IN ('.getEntity('invoice').')';
712
713 $resql = $db->query($sql);
714 if (!$resql) {
716 }
717
718 $res = $db->fetch_object($resql);
719 $total_paiements = $res->total_paiements;
720
721 // Total credit note and deposit
722 $total_creditnote_and_deposit = 0;
723 $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
724 $sql .= " re.description, re.fk_invoice_supplier_source";
725 $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re";
726 $sql .= " WHERE fk_invoice_supplier = ".((int) $object->id);
727 $resql = $db->query($sql);
728 if (!empty($resql)) {
729 while ($obj = $db->fetch_object($resql)) {
730 $total_creditnote_and_deposit += $obj->amount_ttc;
731 }
732 } else {
734 }
735
736 $discount->amount_ht = $discount->amount_ttc = $total_paiements + $total_creditnote_and_deposit - $object->total_ttc;
737 $discount->amount_tva = 0;
738 $discount->tva_tx = 0;
739 $discount->vat_src_code = '';
740
741 // multi-currency
742 $discount->multicurrency_code = $object->multicurrency_code;
743 $discount->multicurrency_tx = $object->multicurrency_tx;
744 $discount->multicurrency_total_ht = $discount->multicurrency_total_ttc = (float) price2num((float) $discount->amount_ttc * (float) $object->multicurrency_tx, 'MT');
745 $discount->multicurrency_total_tva = 0;
746 // keep compatibility
747 $discount->multicurrency_amount_ht = $discount->multicurrency_amount_ttc = $discount->multicurrency_total_ttc;
748 $discount->multicurrency_amount_tva = 0;
749
750 $result = $discount->create($user);
751 if ($result < 0) {
752 $error++;
753 }
754 }
756 foreach ($amount_ht as $tva_tx => $xxx) {
757 $discount->amount_ht = abs((float) $amount_ht[$tva_tx]);
758 $discount->amount_tva = abs((float) $amount_tva[$tva_tx]);
759 $discount->amount_ttc = abs((float) $amount_ttc[$tva_tx]);
760 // multi-currency
761 $discount->multicurrency_code = $object->multicurrency_code;
762 $discount->multicurrency_tx = $object->multicurrency_tx;
763 $discount->multicurrency_total_ht = abs((float) $multicurrency_amount_ht[$tva_tx]);
764 $discount->multicurrency_total_tva = abs((float) $multicurrency_amount_tva[$tva_tx]);
765 $discount->multicurrency_total_ttc = abs((float) $multicurrency_amount_ttc[$tva_tx]);
766 // keep compatibility
767 $discount->multicurrency_amount_ht = abs((float) $discount->multicurrency_total_ht);
768 $discount->multicurrency_amount_tva = abs((float) $discount->multicurrency_total_tva);
769 $discount->multicurrency_amount_ttc = abs((float) $discount->multicurrency_total_ttc);
770
771 // Clean vat code
772 $reg = array();
773 $vat_src_code = '';
774 if (preg_match('/\‍((.*)\‍)/', $tva_tx, $reg)) {
775 $vat_src_code = $reg[1];
776 $tva_tx = preg_replace('/\s*\‍(.*\‍)/', '', $tva_tx); // Remove code into vatrate.
777 }
778
779 $discount->tva_tx = abs((float) $tva_tx);
780 $discount->vat_src_code = $vat_src_code;
781
782 $result = $discount->create($user);
783 if ($result < 0) {
784 $error++;
785 break;
786 }
787 }
788 }
789
790 if (empty($error)) {
792 // Set invoice as paid
793 $result = $object->setPaid($user);
794 if ($result >= 0) {
795 $db->commit();
796 } else {
797 setEventMessages($object->error, $object->errors, 'errors');
798 $db->rollback();
799 }
800 } else {
801 $db->commit();
802 }
803 } else {
804 setEventMessages($discount->error, $discount->errors, 'errors');
805 $db->rollback();
806 }
807 }
808 } elseif ($action == 'confirm_delete_paiement' && $confirm == 'yes' && $usercancreate) {
809 // Delete payment
810 $object->fetch($id);
811 if ($object->status == FactureFournisseur::STATUS_VALIDATED && $object->paid == 0) {
812 $paiementfourn = new PaiementFourn($db);
813 $result = $paiementfourn->fetch(GETPOSTINT('paiement_id'));
814 if ($result > 0) {
815 $result = $paiementfourn->delete($user);
816 if ($result > 0) {
817 header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
818 exit;
819 }
820 }
821 if ($result < 0) {
822 setEventMessages($paiementfourn->error, $paiementfourn->errors, 'errors');
823 }
824 }
825 } elseif ($action == 'add' && $usercancreate) {
826 // Insert new invoice in database
827 if ($socid > 0) {
828 $object->socid = GETPOSTINT('socid');
829 }
830 $selectedLines = GETPOST('toselect', 'array:int');
831
832 $db->begin();
833
834 $error = 0;
835 $tmpproject = 0; // Ensure a value
836
837 // Fill array 'array_options' with data from add form
838 $ret = $extrafields->setOptionalsFromPost(null, $object);
839 if ($ret < 0) {
840 $error++;
841 }
842
843 $dateinvoice = dol_mktime(0, 0, 0, GETPOSTINT('remonth'), GETPOSTINT('reday'), GETPOSTINT('reyear'), 'tzserver'); // If we enter the 02 january, we need to save the 02 january for server
844 $datedue = dol_mktime(0, 0, 0, GETPOSTINT('echmonth'), GETPOSTINT('echday'), GETPOSTINT('echyear'), 'tzserver');
845 //var_dump($dateinvoice.' '.dol_print_date($dateinvoice, 'dayhour'));
846 //var_dump(dol_now('tzuserrel').' '.dol_get_last_hour(dol_now('tzuserrel')).' '.dol_print_date(dol_now('tzuserrel'),'dayhour').' '.dol_print_date(dol_get_last_hour(dol_now('tzuserrel')), 'dayhour'));
847 //var_dump($db->idate($dateinvoice));
848 //exit;
849
850 // Replacement invoice
851 if (GETPOST('type') === '') {
852 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
853 $error++;
854 }
855
857 if (empty($dateinvoice)) {
858 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('DateInvoice')), null, 'errors');
859 $action = 'create';
860 //$_GET['socid'] = $_POST['socid'];
861 $error++;
862 } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + getDolGlobalInt('INVOICE_MAX_FUTURE_DELAY'))) {
863 $error++;
864 setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
865 $action = 'create';
866 }
867
868 if (!(GETPOSTINT('fac_replacement') > 0)) {
869 $error++;
870 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ReplaceInvoice")), null, 'errors');
871 }
872
873 if (!$error) {
874 // This is a replacement invoice
875 $result = $object->fetch(GETPOSTINT('fac_replacement'));
876 $object->fetch_thirdparty();
877
878 $object->ref = GETPOST('ref', 'alphanohtml');
879 $object->ref_supplier = GETPOST('ref_supplier', 'alpha');
880 $object->socid = GETPOSTINT('socid');
881 $object->label = GETPOST('label', 'alphanohtml');
882 $object->libelle = $object->label; // deprecated
883 $object->date = $dateinvoice;
884 $object->date_pointoftax = $date_pointoftax;
885 $object->date_echeance = $datedue;
886 $object->note_public = GETPOST('note_public', 'restricthtml');
887 $object->note_private = GETPOST('note_private', 'restricthtml');
888 $object->cond_reglement_id = GETPOSTINT('cond_reglement_id');
889 $object->mode_reglement_id = GETPOSTINT('mode_reglement_id');
890 $object->fk_account = GETPOSTINT('fk_account');
891 $object->vat_reverse_charge = GETPOST('vat_reverse_charge') == 'on' ? 1 : 0;
892 $object->fk_project = ($tmpproject > 0) ? $tmpproject : null;
893 $object->fk_incoterms = GETPOSTINT('incoterm_id');
894 $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
895 $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
896 $object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
897 $object->transport_mode_id = GETPOSTINT('transport_mode_id');
898
899 // Proprietes particulieres a facture de replacement
900 $object->fk_facture_source = GETPOSTINT('fac_replacement');
902
903 $id = $object->createFromCurrent($user);
904 if ($id <= 0) {
905 $error++;
906 setEventMessages($object->error, $object->errors, 'errors');
907 }
908 }
909 }
910
911 // Credit note invoice
913 $sourceinvoice = GETPOSTINT('fac_avoir');
914 if (!($sourceinvoice > 0) && !getDolGlobalString('INVOICE_CREDIT_NOTE_STANDALONE')) {
915 $error++;
916 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CorrectInvoice")), null, 'errors');
917 }
918 if (GETPOSTINT('socid') < 1) {
919 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('Supplier')), null, 'errors');
920 $action = 'create';
921 $error++;
922 }
923
924 if (empty($dateinvoice)) {
925 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('DateInvoice')), null, 'errors');
926 $action = 'create';
927 //$_GET['socid'] = $_POST['socid'];
928 $error++;
929 } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + getDolGlobalInt('INVOICE_MAX_FUTURE_DELAY'))) {
930 $error++;
931 setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
932 $action = 'create';
933 }
934
935 if (!GETPOST('ref_supplier')) {
936 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('RefSupplierBill')), null, 'errors');
937 $action = 'create';
938 //$_GET['socid'] = $_POST['socid'];
939 $error++;
940 }
941
942 if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED') && empty(GETPOST("subtype"))) {
943 $error++;
944 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("InvoiceSubtype")), null, 'errors');
945 $action = 'create';
946 }
947
948 if (!$error) {
949 $tmpproject = GETPOSTINT('projectid');
950
951 // Create Supplier Invoice
952 $object->ref = GETPOST('ref', 'alphanohtml');
953 $object->ref_supplier = GETPOST('ref_supplier', 'alphanohtml');
954 $object->subtype = GETPOSTINT('subtype');
955 $object->socid = GETPOSTINT('socid');
956 $object->label = GETPOST('label', 'alphanohtml');
957 $object->libelle = $object->label; // Deprecated
958 $object->date = $dateinvoice;
959 $object->date_pointoftax = $date_pointoftax;
960 $object->date_echeance = $datedue;
961 $object->note_public = GETPOST('note_public', 'restricthtml');
962 $object->note_private = GETPOST('note_private', 'restricthtml');
963 $object->cond_reglement_id = GETPOSTINT('cond_reglement_id');
964 $object->mode_reglement_id = GETPOSTINT('mode_reglement_id');
965 $object->fk_account = GETPOSTINT('fk_account');
966 $object->vat_reverse_charge = GETPOST('vat_reverse_charge') == 'on' ? 1 : 0;
967 $object->fk_project = ($tmpproject > 0) ? $tmpproject : null;
968 $object->fk_incoterms = GETPOSTINT('incoterm_id');
969 $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
970 $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
971 $object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
972 $object->transport_mode_id = GETPOSTINT('transport_mode_id');
973
974 // Proprietes particulieres a facture avoir
975 $object->fk_facture_source = $sourceinvoice > 0 ? $sourceinvoice : '';
977
978 $id = $object->create($user);
979
980 if ($id <= 0) {
981 $error++;
982 }
983
984 if (GETPOSTINT('invoiceAvoirWithLines') == 1 && $id > 0) {
985 $facture_source = new FactureFournisseur($db); // fetch origin object
986 if ($facture_source->fetch($object->fk_facture_source) > 0) {
987 $fk_parent_line = 0;
988
989 foreach ($facture_source->lines as $line) {
990 // Extrafields
991 if (method_exists($line, 'fetch_optionals')) {
992 $line->fetch_optionals();
993 }
994
995 // Reset fk_parent_line for no child products and special product
996 if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
997 $fk_parent_line = 0;
998 }
999
1000 $line->fk_facture_fourn = $object->id;
1001 $line->fk_parent_line = $fk_parent_line;
1002
1003 $line->subprice = -$line->subprice; // invert price for object
1004 $line->pa_ht = -((float) $line->pa_ht);
1005 $line->total_ht = -$line->total_ht;
1006 $line->total_tva = -$line->total_tva;
1007 $line->total_ttc = -$line->total_ttc;
1008 $line->total_localtax1 = -$line->total_localtax1;
1009 $line->total_localtax2 = -$line->total_localtax2;
1010 $line->multicurrency_total_ht = -$line->multicurrency_total_ht;
1011 $line->multicurrency_total_tva = -$line->multicurrency_total_tva;
1012 $line->multicurrency_total_ttc = -$line->multicurrency_total_ttc;
1013
1014 $result = $line->insert();
1015
1016 $object->lines[] = $line; // insert new line in current object
1017
1018 // Defined the new fk_parent_line
1019 if ($result > 0 && $line->product_type == 9) {
1020 $fk_parent_line = $result;
1021 }
1022 }
1023
1024 $object->update_price(1);
1025 }
1026 }
1027
1028 if (GETPOSTINT('invoiceAvoirWithPaymentRestAmount') == 1 && $id > 0) {
1029 $facture_source = new FactureFournisseur($db); // fetch origin object if not previously defined
1030 if ($facture_source->fetch($object->fk_facture_source) > 0) {
1031 $totalpaid = $facture_source->getSommePaiement();
1032 $totalcreditnotes = $facture_source->getSumCreditNotesUsed();
1033 $totaldeposits = $facture_source->getSumDepositsUsed();
1034 $remain_to_pay = abs($facture_source->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits);
1035 $desc = $langs->trans('invoiceAvoirLineWithPaymentRestAmount');
1036 // Pass the amount already signed: addline() forces -abs() on credit notes with the default setup, so this
1037 // changes nothing there, but it keeps the line negative when that forcing is relaxed (see addline()).
1038 $retAddLine = $object->addline($desc, -$remain_to_pay, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 'TTC');
1039
1040 if ($retAddLine < 0) {
1041 $error++;
1042 }
1043 }
1044 }
1045
1046 // Add link between credit note and origin objects
1047 if (!empty($object->fk_facture_source) && $id > 0) {
1048 $facture_source_link = new FactureFournisseur($db);
1049 if ($facture_source_link->fetch($object->fk_facture_source) > 0) {
1050 $facture_source_link->fetchObjectLinked();
1051 if (!empty($facture_source_link->linkedObjectsIds)) {
1052 foreach ($facture_source_link->linkedObjectsIds as $sourcetype => $TIds) {
1053 $object->add_object_linked($sourcetype, current($TIds));
1054 }
1055 }
1056 }
1057 }
1058 }
1059 } elseif ($fac_recid > 0 && (GETPOSTINT('type') == FactureFournisseur::TYPE_STANDARD || GETPOSTINT('type') == FactureFournisseur::TYPE_DEPOSIT)) {
1060 // Standard invoice or Deposit invoice, created from a Predefined template invoice
1061 if (empty($dateinvoice)) {
1062 $error++;
1063 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
1064 $action = 'create';
1065 } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + getDolGlobalInt('INVOICE_MAX_FUTURE_DELAY'))) {
1066 $error++;
1067 setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
1068 $action = 'create';
1069 }
1070
1071 if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED') && empty(GETPOST("subtype"))) {
1072 $error++;
1073 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("InvoiceSubtype")), null, 'errors');
1074 $action = 'create';
1075 }
1076
1077 if (!$error) {
1078 $object->socid = GETPOSTINT('socid');
1079 $object->type = GETPOSTINT('type');
1080 $object->subtype = GETPOSTINT('subtype');
1081 $object->ref = GETPOST('ref', 'alphanohtml');
1082 $object->date = $dateinvoice;
1083 $object->date_pointoftax = $date_pointoftax;
1084 $object->note_public = trim(GETPOST('note_public', 'restricthtml'));
1085 $object->note_private = trim(GETPOST('note_private', 'restricthtml'));
1086 $object->ref_supplier = GETPOST('ref_supplier', 'alphanohtml');
1087 $object->model_pdf = GETPOST('model', 'alphanohtml');
1088 $object->fk_project = GETPOSTINT('projectid');
1089 $object->cond_reglement_id = (GETPOSTINT('type') == 3 ? 1 : GETPOSTINT('cond_reglement_id'));
1090 $object->mode_reglement_id = GETPOSTINT('mode_reglement_id');
1091 $object->fk_account = GETPOSTINT('fk_account');
1092 $object->amount = (float) price2num(GETPOST('amount')); // FIXME: FactureFournisseur::$amount is deprecated and not used?
1093 $object->fk_incoterms = GETPOSTINT('incoterm_id');
1094 $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
1095 $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
1096 $object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
1097
1098 // Source facture
1099 $object->fac_rec = $fac_recid;
1100 $fac_rec = new FactureFournisseurRec($db);
1101 $fac_rec->fetch($object->fac_rec);
1102 $fac_rec->fetch_lines();
1103 $object->lines = $fac_rec->lines;
1104
1105 $id = $object->create($user); // This include recopy of links from recurring invoice and recurring invoice lines
1106 }
1107 } elseif ($fac_recid <= 0 && (GETPOSTINT('type') == FactureFournisseur::TYPE_STANDARD || GETPOSTINT('type') == FactureFournisseur::TYPE_DEPOSIT)) {
1108 // Standard invoice or Deposit invoice, not from a Predefined template invoice
1109 if (GETPOSTINT('socid') < 1) {
1110 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('Supplier')), null, 'errors');
1111 $action = 'create';
1112 $error++;
1113 }
1114
1115 if (empty($dateinvoice)) {
1116 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('DateInvoice')), null, 'errors');
1117 $action = 'create';
1118 //$_GET['socid'] = $_POST['socid'];
1119 $error++;
1120 } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + getDolGlobalInt('INVOICE_MAX_FUTURE_DELAY'))) {
1121 $error++;
1122 setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
1123 $action = 'create';
1124 }
1125
1126 if (!GETPOST('ref_supplier')) {
1127 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('RefSupplierBill')), null, 'errors');
1128 $action = 'create';
1129 //$_GET['socid'] = $_POST['socid'];
1130 $error++;
1131 }
1132
1133 if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED') && empty(GETPOST("subtype"))) {
1134 $error++;
1135 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("InvoiceSubtype")), null, 'errors');
1136 $action = 'create';
1137 }
1138
1139 if (!$error) {
1140 $tmpproject = GETPOSTINT('projectid');
1141
1142 // Creation invoice
1143 $object->socid = GETPOSTINT('socid');
1144 $object->type = GETPOSTINT('type');
1145 $object->subtype = GETPOSTINT('subtype');
1146 $object->ref = GETPOST('ref', 'alphanohtml');
1147 $object->ref_supplier = GETPOST('ref_supplier', 'alphanohtml');
1148 $object->socid = GETPOSTINT('socid');
1149 $object->label = GETPOST('label', 'alphanohtml');
1150 $object->libelle = $object->label; // deprecated
1151 $object->date = $dateinvoice;
1152 $object->date_pointoftax = $date_pointoftax;
1153 $object->date_echeance = $datedue;
1154 $object->note_public = GETPOST('note_public', 'restricthtml');
1155 $object->note_private = GETPOST('note_private', 'restricthtml');
1156 $object->cond_reglement_id = GETPOSTINT('cond_reglement_id');
1157 $object->mode_reglement_id = GETPOSTINT('mode_reglement_id');
1158 $object->fk_account = GETPOSTINT('fk_account');
1159 $object->vat_reverse_charge = GETPOST('vat_reverse_charge') == 'on' ? 1 : 0;
1160 $object->fk_project = ($tmpproject > 0) ? $tmpproject : null;
1161 $object->fk_incoterms = GETPOSTINT('incoterm_id');
1162 $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
1163 $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
1164 $object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
1165 $object->transport_mode_id = GETPOSTINT('transport_mode_id');
1166
1167 // Auto calculation of date due if not filled by user
1168 if (empty($object->date_echeance)) {
1169 $object->date_echeance = $object->calculate_date_lim_reglement();
1170 }
1171
1172 $object->fetch_thirdparty();
1173
1174 // If creation from another object of another module
1175 if (!$error && GETPOST('origin', 'alpha') && GETPOST('originid')) {
1176 // Parse element/subelement (ex: project_task)
1177 $element = $subelement = GETPOST('origin', 'alpha');
1178 /*if (preg_match('/^([^_]+)_([^_]+)/i', GETPOST('origin'),$regs))
1179 {
1180 $element = $regs[1];
1181 $subelement = $regs[2];
1182 }*/
1183
1184 // For compatibility
1185 if ($element == 'order') {
1186 $element = $subelement = 'commande';
1187 }
1188 if ($element == 'propal') {
1189 $element = 'comm/propal';
1190 $subelement = 'propal';
1191 }
1192 if ($element == 'contract') {
1193 $element = $subelement = 'contrat';
1194 }
1195 if ($element == 'order_supplier') {
1196 $element = 'fourn';
1197 $subelement = 'fournisseur.commande';
1198 }
1199 if ($element == 'project') {
1200 $element = 'projet';
1201 }
1202 $object->origin_type = GETPOST('origin', 'alpha');
1203 $object->origin = $object->origin_type;
1204 $object->origin_id = GETPOSTINT('originid');
1205
1206
1207 dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
1208 $classname = ucfirst($subelement);
1209 if ($classname == 'Fournisseur.commande') {
1210 $classname = 'CommandeFournisseur';
1211 }
1212 $objectsrc = new $classname($db);
1213 $objectsrc->fetch($originid);
1214 $objectsrc->fetch_thirdparty();
1215
1216 if (!empty($object->origin_type) && !empty($object->origin_id)) {
1217 $object->linkedObjectsIds[$object->origin_type][-1] = $object->origin_id;
1218 }
1219
1220 // Add also link with order if object is reception
1221 if ($object->origin_type == 'reception') {
1222 $objectsrc->fetchObjectLinked();
1223
1224 if (count($objectsrc->linkedObjectsIds['order_supplier']) > 0) {
1225 foreach ($objectsrc->linkedObjectsIds['order_supplier'] as $key => $value) {
1226 $object->linkedObjectsIds['order_supplier'][-1] = $value;
1227 }
1228 }
1229 }
1230
1231 $id = $object->create($user);
1232
1233 // Add lines
1234 if ($id > 0) {
1235 dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
1236 $classname = ucfirst($subelement);
1237 if ($classname == 'Fournisseur.commande') {
1238 $classname = 'CommandeFournisseur';
1239 }
1240 $srcobject = new $classname($db);
1241
1242 $result = $srcobject->fetch(GETPOSTINT('originid'));
1243
1244 // If deposit invoice - down payment with 1 line (fixed amount or percent)
1245 $typeamount = GETPOST('typedeposit', 'alpha');
1246 if (GETPOSTINT('type') == FactureFournisseur::TYPE_DEPOSIT && in_array($typeamount, array('amount', 'variable'))) {
1247 $valuedeposit = price2num(GETPOST('valuedeposit', 'alpha'), 'MU');
1248
1249 // Define the array $amountdeposit
1250 $amountdeposit = array();
1251 if (getDolGlobalString('MAIN_DEPOSIT_MULTI_TVA')) {
1252 if ($typeamount == 'amount') {
1253 $amount = $valuedeposit;
1254 } else {
1255 $amount = $srcobject->total_ttc * ((float) $valuedeposit / 100);
1256 }
1257
1258 $TTotalByTva = array();
1259 foreach ($srcobject->lines as &$line) {
1260 if (!empty($line->special_code)) {
1261 continue;
1262 }
1263 $TTotalByTva[$line->tva_tx] += $line->total_ttc;
1264 }
1265 '@phan-var-force array<string,float> $TTotalByTva';
1266
1267 $amount_ttc_diff = 0.;
1268 foreach ($TTotalByTva as $tva => &$total) {
1269 $coef = $total / $srcobject->total_ttc; // Calc coef
1270 $am = $amount * $coef;
1271 $amount_ttc_diff += $am;
1272 $amountdeposit[$tva] += $am / (1 + (float) $tva / 100); // Convert into HT for the addline
1273 }
1274 } else {
1275 if ($typeamount == 'amount') {
1276 $amountdeposit[0] = $valuedeposit;
1277 } elseif ($typeamount == 'variable') {
1278 if ($result > 0) {
1279 $totalamount = 0;
1280 $lines = $srcobject->lines;
1281 $numlines = count($lines);
1282 for ($i = 0; $i < $numlines; $i++) {
1283 $qualified = 1;
1284 if (empty($lines[$i]->qty)) {
1285 $qualified = 0; // We discard qty=0, it is an option
1286 }
1287 if (!empty($lines[$i]->special_code)) {
1288 $qualified = 0; // We discard special_code (frais port, ecotaxe, option, ...)
1289 }
1290 if ($qualified) {
1291 $totalamount += $lines[$i]->total_ht; // Fixme : is it not for the customer ? Shouldn't we take total_ttc ?
1292 $tva_tx = $lines[$i]->tva_tx;
1293 $amountdeposit[$tva_tx] += ($lines[$i]->total_ht * (float) $valuedeposit) / 100;
1294 }
1295 }
1296
1297 if ($totalamount == 0) {
1298 $amountdeposit[0] = 0;
1299 }
1300 } else {
1301 setEventMessages($srcobject->error, $srcobject->errors, 'errors');
1302 $error++;
1303 $amountdeposit[0] = 0;
1304 }
1305 }
1306
1307 $amount_ttc_diff = array_key_exists(0, $amountdeposit) ? $amountdeposit[0] : 0;
1308 }
1309
1310 foreach ($amountdeposit as $tva => $amount) {
1311 if (empty($amount)) {
1312 continue;
1313 }
1314
1315 $arraylist = array(
1316 'amount' => 'FixAmount',
1317 'variable' => 'VarAmount'
1318 );
1319 $descline = '(DEPOSIT)';
1320 //$descline.= ' - '.$langs->trans($arraylist[$typeamount]);
1321 if ($typeamount == 'amount') {
1322 $descline .= ' ('.price($valuedeposit, 0, $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)).')';
1323 } elseif ($typeamount == 'variable') {
1324 $descline .= ' ('.$valuedeposit.'%)';
1325 }
1326
1327 $descline .= ' - '.$srcobject->ref;
1328 $result = $object->addline(
1329 $descline,
1330 (float) $amount, // subprice
1331 $tva, // vat rate
1332 0, // localtax1_tx
1333 0, // localtax2_tx
1334 1, // quantity
1335 getDolGlobalInt('SUPPLIER_INVOICE_PRODUCTID_DEPOSIT', getDolGlobalInt('INVOICE_PRODUCTID_DEPOSIT')), // fk_product
1336 0, // remise_percent
1337 0, // date_start
1338 0, // date_end
1339 0,
1340 0, // info_bits
1341 'HT',
1342 0, // product_type
1343 1,
1344 0,
1345 array(), // array_options
1346 null,
1347 $object->origin_id,
1348 0,
1349 '',
1350 0, // special_code
1351 0,
1352 0,
1353 $object->origin_type
1354 );
1355 }
1356
1357 $diff = $object->total_ttc - $amount_ttc_diff;
1358
1359 if (getDolGlobalString('MAIN_DEPOSIT_MULTI_TVA') && $diff != 0) {
1360 $object->fetch_lines();
1361 $subprice_diff = $object->lines[0]->subprice - $diff / (1 + $object->lines[0]->tva_tx / 100);
1362 $object->updateline(
1363 $object->lines[0]->id,
1364 $object->lines[0]->desc,
1365 $subprice_diff,
1366 $object->lines[0]->tva_tx,
1367 $object->lines[0]->localtax1_tx,
1368 $object->lines[0]->localtax2_tx,
1369 $object->lines[0]->qty,
1370 $object->lines[0]->fk_product,
1371 'HT',
1372 $object->lines[0]->info_bits,
1373 $object->lines[0]->product_type,
1374 $object->lines[0]->remise_percent,
1375 0,
1376 $object->lines[0]->date_start,
1377 $object->lines[0]->date_end,
1378 array(), // array_options
1379 0,
1380 0,
1381 '',
1382 100
1383 );
1384 }
1385 } elseif ($result > 0) {
1386 $lines = $srcobject->lines;
1387 if (empty($lines) && method_exists($srcobject, 'fetch_lines')) {
1388 $srcobject->fetch_lines();
1389 $lines = $srcobject->lines;
1390 }
1391
1392 $num = count($lines);
1393 for ($i = 0; $i < $num; $i++) { // TODO handle subprice < 0
1394 if (!in_array($lines[$i]->id, $selectedLines)) {
1395 continue; // Skip unselected lines
1396 }
1397
1398 $desc = ($lines[$i]->desc ? $lines[$i]->desc : $lines[$i]->product_label);
1399 $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0);
1400
1401 // Extrafields
1402 if (method_exists($lines[$i], 'fetch_optionals')) {
1403 $lines[$i]->fetch_optionals();
1404 }
1405
1406 // Dates
1407 // TODO mutualiser
1408 $date_start = $lines[$i]->date_debut_prevue;
1409 if ($lines[$i]->date_debut_reel) {
1410 $date_start = $lines[$i]->date_debut_reel;
1411 }
1412 if ($lines[$i]->date_start) {
1413 $date_start = $lines[$i]->date_start;
1414 }
1415 $date_end = $lines[$i]->date_fin_prevue;
1416 if ($lines[$i]->date_fin_reel) {
1417 $date_end = $lines[$i]->date_fin_reel;
1418 }
1419 if ($lines[$i]->date_end) {
1420 $date_end = $lines[$i]->date_end;
1421 }
1422
1423 $tva_tx = $lines[$i]->tva_tx;
1424 // @phan-suppress-next-line PhanTypeMismatchArgumentInternal
1425 if (!empty($lines[$i]->vat_src_code) && !preg_match('/\‍(/', (string) $tva_tx)) {
1426 $tva_tx .= ' ('.$lines[$i]->vat_src_code.')';
1427 }
1428
1429 // FIXME Missing special_code into addline and updateline methods
1430 $object->special_code = $lines[$i]->special_code;
1431
1432 // FIXME If currency different from main currency, take multicurrency price
1433 if ($object->multicurrency_code != $conf->currency || $object->multicurrency_tx != 1) {
1434 $pu = 0;
1435 $pu_currency = $lines[$i]->multicurrency_subprice;
1436 } else {
1437 $pu = $lines[$i]->subprice;
1438 $pu_currency = 0;
1439 }
1440
1441 // FIXME Missing $lines[$i]->ref_supplier and $lines[$i]->label into addline and updateline methods. They are filled when coming from order for example.
1442 $result = $object->addline(
1443 $desc,
1444 $pu,
1445 $tva_tx,
1446 $lines[$i]->localtax1_tx,
1447 $lines[$i]->localtax2_tx,
1448 $lines[$i]->qty,
1449 $lines[$i]->fk_product,
1450 $lines[$i]->remise_percent,
1451 (int) $date_start,
1452 (int) $date_end,
1453 0,
1454 $lines[$i]->info_bits,
1455 'HT',
1456 $product_type,
1457 $lines[$i]->rang,
1458 0,
1459 $lines[$i]->array_options,
1460 $lines[$i]->fk_unit,
1461 $lines[$i]->id,
1462 $pu_currency,
1463 $lines[$i]->ref_supplier,
1464 $lines[$i]->special_code
1465 );
1466
1467 if ($result < 0) {
1468 $error++;
1469 break;
1470 }
1471 }
1472
1473 // Now reload line
1474 $object->fetch_lines();
1475 } else {
1476 $error++;
1477 }
1478
1479 if (!$error) {
1480 // Hooks
1481 $parameters = array('objFrom' => $srcobject);
1482 $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been
1483 // modified by hook
1484 if ($reshook < 0) {
1485 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1486 $error++;
1487 }
1488 }
1489 } else {
1490 $error++;
1491 }
1492 } elseif (!$error) {
1493 $id = $object->create($user);
1494 if ($id < 0) {
1495 $error++;
1496 }
1497 }
1498 }
1499 }
1500
1501 if ($error) {
1502 $langs->load("errors");
1503 $db->rollback();
1504
1505 setEventMessages($object->error, $object->errors, 'errors');
1506 $action = 'create';
1507 //$_GET['socid'] = $_POST['socid'];
1508 } else {
1509 $db->commit();
1510
1511 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1512 $outputlangs = $langs;
1513 $result = $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1514 if ($result < 0) {
1515 dol_print_error($db, $object->error, $object->errors);
1516 exit;
1517 }
1518 }
1519
1520 header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
1521 exit;
1522 }
1523 } elseif ($action == 'updateline' && $usercancreate) {
1524 // Edit line
1525 $db->begin();
1526
1527 if (! $object->fetch($id) > 0) {
1529 }
1530 $object->fetch_thirdparty();
1531
1532 $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
1533 $tva_tx = str_replace('*', '', $tva_tx);
1534
1535 if (GETPOST('price_ht') != '' || GETPOST('multicurrency_subprice') != '') {
1536 $up = price2num(GETPOST('price_ht'), '', 2);
1537 $price_base_type = 'HT';
1538 } else {
1539 $up = price2num(GETPOST('price_ttc'), '', 2);
1540 $price_base_type = 'TTC';
1541 }
1542
1543 if (GETPOST('productid') > 0) {
1544 $productsupplier = new ProductFournisseur($db);
1545 if (getDolGlobalInt('SUPPLIER_INVOICE_WITH_PREDEFINED_PRICES_ONLY') == 1) { // Not the common case
1546 if (GETPOST('productid') > 0 && $productsupplier->get_buyprice(0, (float) price2num(GETPOST('qty')), GETPOSTINT('productid'), 'restricthtml', GETPOSTINT('socid')) < 0) {
1547 setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'warnings');
1548 }
1549 }
1550
1551 $prod = new Product($db);
1552 $prod->fetch(GETPOSTINT('productid'));
1553 $label = $prod->description;
1554 if (trim(GETPOST('product_desc', 'restricthtml')) != trim($label)) {
1555 $label = GETPOST('product_desc', 'restricthtml');
1556 }
1557
1558 $type = $prod->type;
1559 } else {
1560 $label = GETPOST('product_desc', 'restricthtml');
1561 $type = GETPOSTINT("type");
1562 }
1563
1564 $date_start = dol_mktime(GETPOSTINT('date_starthour'), GETPOSTINT('date_startmin'), GETPOSTINT('date_startsec'), GETPOSTINT('date_startmonth'), GETPOSTINT('date_startday'), GETPOSTINT('date_startyear'));
1565 $date_end = dol_mktime(GETPOSTINT('date_endhour'), GETPOSTINT('date_endmin'), GETPOSTINT('date_endsec'), GETPOSTINT('date_endmonth'), GETPOSTINT('date_endday'), GETPOSTINT('date_endyear'));
1566
1567 // Define info_bits
1568 $info_bits = 0;
1569 if (preg_match('/\*/', $tva_tx)) {
1570 $info_bits |= 0x01;
1571 }
1572
1573 // Define vat_rate
1574 $tva_tx = str_replace('*', '', $tva_tx);
1575 $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty);
1576 $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty);
1577
1578 $remise_percent = price2num(GETPOST('remise_percent'), '', 2);
1579 $pu_devise = price2num(GETPOST('multicurrency_subprice'), 'MU', 2);
1580
1581 // Extrafields Lines
1582 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
1583 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line);
1584 // Unset extrafield POST Data
1585 if (is_array($extralabelsline)) {
1586 foreach ($extralabelsline as $key => $value) {
1587 unset($_POST["options_".$key]);
1588 }
1589 }
1590
1591 $result = $object->updateline(
1592 GETPOSTINT('lineid'),
1593 $label,
1594 (float) $up,
1595 $tva_tx,
1596 $localtax1_tx,
1597 $localtax2_tx,
1598 (float) price2num(GETPOST('qty'), 'MS'),
1599 GETPOSTINT('productid'),
1600 $price_base_type,
1601 $info_bits,
1602 $type,
1603 (float) $remise_percent,
1604 0,
1606 $date_end,
1607 $array_options,
1608 GETPOST('units') != '' ? GETPOSTINT('units') : null,
1609 (float) $pu_devise,
1610 GETPOST('fourn_ref', 'alpha')
1611 );
1612 if ($result >= 0) {
1613 unset($_POST['label']);
1614 unset($_POST['fourn_ref']);
1615 unset($_POST['date_starthour']);
1616 unset($_POST['date_startmin']);
1617 unset($_POST['date_startsec']);
1618 unset($_POST['date_startday']);
1619 unset($_POST['date_startmonth']);
1620 unset($_POST['date_startyear']);
1621 unset($_POST['date_endhour']);
1622 unset($_POST['date_endmin']);
1623 unset($_POST['date_endsec']);
1624 unset($_POST['date_endday']);
1625 unset($_POST['date_endmonth']);
1626 unset($_POST['date_endyear']);
1627 unset($_POST['price_ttc']);
1628 unset($_POST['price_ht']);
1629
1630 $db->commit();
1631 } else {
1632 $db->rollback();
1633 setEventMessages($object->error, $object->errors, 'errors');
1634 }
1635 } elseif ($action == 'addline' && GETPOST('submitforalllines', 'aZ09') && (GETPOST('alldate_start', 'alpha') || GETPOST('alldate_end', 'alpha')) && $usercancreate) {
1636 // Define date start and date end for all line
1637 $alldate_start = dol_mktime(GETPOSTINT('alldate_starthour'), GETPOSTINT('alldate_startmin'), 0, GETPOSTINT('alldate_startmonth'), GETPOSTINT('alldate_startday'), GETPOSTINT('alldate_startyear'));
1638 $alldate_end = dol_mktime(GETPOSTINT('alldate_endhour'), GETPOSTINT('alldate_endmin'), 0, GETPOSTINT('alldate_endmonth'), GETPOSTINT('alldate_endday'), GETPOSTINT('alldate_endyear'));
1639 foreach ($object->lines as $line) {
1640 if ($line->product_type == 1) { // only service line
1641 $result = $object->updateline($line->id, $line->desc, $line->subprice, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->qty, $line->fk_product, 'HT', $line->info_bits, $line->product_type, $line->remise_percent, 0, $alldate_start, $alldate_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice, $line->ref_supplier, $line->rang);
1642 }
1643 }
1644 } elseif ($action == 'addline' && GETPOST('submitforalllines', 'alpha') && GETPOST('remiseforalllines', 'alpha') !== '' && $usercancreate) {
1645 // Define vat_rate
1646 $remise_percent = (GETPOST('remiseforalllines') ? GETPOST('remiseforalllines') : 0);
1647 $remise_percent = (float) str_replace('*', '', $remise_percent);
1648 foreach ($object->lines as $line) {
1649 $result = $object->updateline($line->id, $line->desc, $line->subprice, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->qty, $line->fk_product, 'HT', $line->info_bits, $line->product_type, $remise_percent, 0, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice, $line->ref_supplier, $line->rang);
1650 }
1651 } elseif ($action == 'addline' && GETPOST('submitforalllines', 'aZ09') && GETPOST('vatforalllines', 'alpha') != '' && $usercancreate) {
1652 // Define vat_rate
1653 $vat_rate = (GETPOST('vatforalllines') ? GETPOST('vatforalllines') : 0);
1654 $vat_rate = str_replace('*', '', $vat_rate);
1655 $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty, $mysoc);
1656 $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty, $mysoc);
1657 foreach ($object->lines as $line) {
1658 $result = $object->updateline($line->id, $line->desc, $line->subprice, $vat_rate, $localtax1_rate, $localtax2_rate, $line->qty, $line->fk_product, 'HT', $line->info_bits, $line->product_type, $line->remise_percent, 0, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice, $line->ref_supplier, $line->rang);
1659 }
1660 } elseif ($action == 'addline' && $usercancreate) {
1661 // Add a product line
1662 $db->begin();
1663
1664 $ret = $object->fetch($id);
1665 if ($ret < 0) {
1666 dol_print_error($db, $object->error);
1667 exit;
1668 }
1669 $ret = $object->fetch_thirdparty();
1670
1671 $langs->load('errors');
1672 $error = 0;
1673
1674 // Set if we used free entry or predefined product
1675 $predef = '';
1676 $line_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : '');
1677 $date_start = dol_mktime(GETPOSTINT('date_start'.$predef.'hour'), GETPOSTINT('date_start'.$predef.'min'), GETPOSTINT('date_start'.$predef.'sec'), GETPOSTINT('date_start'.$predef.'month'), GETPOSTINT('date_start'.$predef.'day'), GETPOSTINT('date_start'.$predef.'year'));
1678 $date_end = dol_mktime(GETPOSTINT('date_end'.$predef.'hour'), GETPOSTINT('date_end'.$predef.'min'), GETPOSTINT('date_end'.$predef.'sec'), GETPOSTINT('date_end'.$predef.'month'), GETPOSTINT('date_end'.$predef.'day'), GETPOSTINT('date_end'.$predef.'year'));
1679
1680 $prod_entry_mode = GETPOST('prod_entry_mode');
1681 if ($prod_entry_mode == 'free') {
1682 $idprod = 0;
1683 } else {
1684 $idprod = GETPOSTINT('idprod');
1685 }
1686
1687 $price_ht = '';
1688 $price_ht_devise = '';
1689 $price_ttc = '';
1690 $price_ttc_devise = '';
1691
1692 if (GETPOST('price_ht') !== '') {
1693 $price_ht = price2num(GETPOST('price_ht'), 'MU', 2);
1694 }
1695 if (GETPOST('multicurrency_price_ht') !== '') {
1696 $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2);
1697 }
1698 if (GETPOST('price_ttc') !== '') {
1699 $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2);
1700 }
1701 if (GETPOST('multicurrency_price_ttc') !== '') {
1702 $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2);
1703 }
1704
1705 $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); // Can be '1.2' or '1.2 (CODE)'
1706
1707 $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS');
1708
1709 $remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef, 'alpha'), '', 2) : 0);
1710 if (empty($remise_percent)) {
1711 $remise_percent = 0;
1712 }
1713
1714 // Extrafields
1715 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
1716 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
1717 // Unset extrafield
1718 if (is_array($extralabelsline)) {
1719 // Get extra fields
1720 foreach ($extralabelsline as $key => $value) {
1721 unset($_POST["options_".$key]);
1722 }
1723 }
1724
1725 if ($prod_entry_mode == 'free' && GETPOST('price_ht') < 0 && $qty < 0) {
1726 setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPrice'), $langs->transnoentitiesnoconv('Qty')), null, 'errors');
1727 $error++;
1728 }
1729 if ($prod_entry_mode == 'free' && (!GETPOST('idprodfournprice') || GETPOST('idprodfournprice') == '-1') && GETPOSTINT('type') < 0) {
1730 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors');
1731 $error++;
1732 }
1733
1734 // Do not allow negative lines for free products (invite to enter a discount instead)
1735 if ($prod_entry_mode == 'free' && (!GETPOST('idprodfournprice') || GETPOST('idprodfournprice') == '-1')
1736 && (((float) $price_ht < 0 && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES')) || $price_ht === '')
1737 && (((float) $price_ht_devise < 0 && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES')) || $price_ht_devise === '')
1738 && ((float) $price_ttc < 0 && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES') || $price_ttc === '')
1739 && ((float) $price_ttc_devise < 0 && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES') || $price_ttc_devise === '')
1740 && $object->type != $object::TYPE_CREDIT_NOTE) { // Unit price can be 0 but not ''
1741 if (((float) $price_ht < 0 || (float) $price_ttc < 0) && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES')) {
1742 $langs->load("errors");
1743 if ($object->type == $object::TYPE_DEPOSIT) {
1744 // Using negative lines on deposit lead to headach and blocking problems when you want to consume them.
1745 setEventMessages($langs->trans("ErrorLinesCantBeNegativeOnDeposits"), null, 'errors');
1746 } else {
1747 setEventMessages($langs->trans("ErrorFieldCantBeNegativeOnInvoice", $langs->transnoentitiesnoconv("UnitPrice"), $langs->transnoentitiesnoconv("CustomerAbsoluteDiscountShort")), null, 'errors');
1748 }
1749 $error++;
1750 }
1751 }
1752 if ($prod_entry_mode == 'free' && (!GETPOST('idprodfournprice') || GETPOST('idprodfournprice') == '-1') && GETPOST('price_ht') === '' && GETPOST('price_ttc') === '' && $price_ht_devise === '') { // Unit price can be 0 but not ''
1753 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('UnitPrice')), null, 'errors');
1754 $error++;
1755 }
1756
1757 if ($prod_entry_mode == 'free' && (!GETPOST('idprodfournprice') || GETPOST('idprodfournprice') == '-1') && !GETPOST('dp_desc')) {
1758 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors');
1759 $error++;
1760 }
1761 if (!GETPOST('qty', 'alpha')) { // 0 is NOT allowed for invoices
1762 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
1763 $error++;
1764 }
1765
1766 if (!$error && isModEnabled('variants') && $prod_entry_mode != 'free') {
1767 if ($combinations = GETPOST('combinations', 'array:alphanohtml')) {
1768 //Check if there is a product with the given combination
1769 $prodcomb = new ProductCombination($db);
1770
1771 if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) {
1772 $idprod = $res->fk_product_child;
1773 } else {
1774 setEventMessages($langs->trans('ErrorProductCombinationNotFound'), null, 'errors');
1775 $error++;
1776 }
1777 }
1778 }
1779
1780 if ($prod_entry_mode != 'free' && empty($error)) { // With combolist mode idprodfournprice is > 0 or -1. With autocomplete, idprodfournprice is > 0 or ''
1781 $productsupplier = new ProductFournisseur($db);
1782
1783 $idprod = 0;
1784 if (GETPOST('idprodfournprice', 'alpha') == -1 || GETPOST('idprodfournprice', 'alpha') == '') {
1785 $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, ...)
1786 }
1787
1788 $reg = array();
1789 if (preg_match('/^idprod_([0-9]+)$/', GETPOST('idprodfournprice', 'alpha'), $reg)) {
1790 $idprod = (int) $reg[1];
1791 $res = $productsupplier->fetch($idprod); // Load product from its id
1792 // Call to init some price properties of $productsupplier
1793 // So if a supplier price already exists for another thirdparty (first one found), we use it as reference price
1794 if (getDolGlobalString('SUPPLIER_TAKE_FIRST_PRICE_IF_NO_PRICE_FOR_CURRENT_SUPPLIER')) {
1795 $fksoctosearch = 0;
1796 $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist
1797 if ($productsupplier->fourn_socid != $socid) { // The price we found is for another supplier, so we clear supplier price
1798 $productsupplier->ref_supplier = '';
1799 }
1800 } else {
1801 $fksoctosearch = $object->thirdparty->id;
1802 $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist
1803 }
1804 } elseif (GETPOSTINT('idprodfournprice') > 0) { // Should be an int at this point
1805 $qtytosearch = (float) $qty; // Just to see if a price exists for the quantity. Not used to found vat.
1806 //$qtytosearch=-1; // We force qty to -1 to be sure to find if a supplier price exist
1807 $idprod = $productsupplier->get_buyprice(GETPOSTINT('idprodfournprice'), $qtytosearch);
1808 $res = $productsupplier->fetch($idprod);
1809 }
1810
1811 if ($idprod > 0) {
1812 $label = $productsupplier->label;
1813 // Define output language
1814 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
1815 $outputlangs = $langs;
1816 $newlang = '';
1817 if (/* empty($newlang) && */ GETPOST('lang_id', 'aZ09')) {
1818 $newlang = GETPOST('lang_id', 'aZ09');
1819 }
1820 if (empty($newlang)) {
1821 $newlang = $object->thirdparty->default_lang;
1822 }
1823 if (!empty($newlang)) {
1824 $outputlangs = new Translate("", $conf);
1825 $outputlangs->setDefaultLang($newlang);
1826 }
1827 $desc = (!empty($productsupplier->multilangs[$outputlangs->defaultlang]["description"])) ? $productsupplier->multilangs[$outputlangs->defaultlang]["description"] : $productsupplier->description;
1828 } else {
1829 $desc = $productsupplier->description;
1830 }
1831 // if we use supplier description of the products
1832 if (!empty($productsupplier->desc_supplier) && getDolGlobalString('PRODUIT_FOURN_TEXTS')) {
1833 $desc = $productsupplier->desc_supplier;
1834 }
1835
1836 if (getDolGlobalInt('PRODUIT_AUTOFILL_DESC') == 0) {
1837 // 'DoNotAutofillButAutoConcat'
1838 $desc = dol_concatdesc($desc, $line_desc, false, getDolGlobalString('MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION') ? true : false);
1839 } else {
1840 //'AutoFillFormFieldBeforeSubmit' or 'DoNotUseDescriptionOfProdut' => User has already done the modification they want
1841 $desc = $line_desc;
1842 }
1843
1844 $ref_supplier = $productsupplier->ref_supplier;
1845
1846 // Get vat rate
1847 if (!GETPOSTISSET('tva_tx')) { // If vat rate not provided from the form (the form has the priority)
1848 $tmpidprodfournprice = GETPOST('idprodfournprice', 'alpha'); // can be an id of price, or -1, -2, -99 or 'idprod_...'
1849 if (is_numeric($tmpidprodfournprice) && (int) $tmpidprodfournprice > 0) {
1850 $tmpidprodfournprice = (int) $tmpidprodfournprice;
1851 } else {
1852 $tmpidprodfournprice = 0;
1853 }
1854
1855 $tva_tx = get_default_tva($object->thirdparty, $mysoc, $productsupplier->id, $tmpidprodfournprice);
1856 $tva_npr = get_default_npr($object->thirdparty, $mysoc, $productsupplier->id, $tmpidprodfournprice);
1857 }
1858 if (empty($tva_tx) || empty($tva_npr)) {
1859 $tva_npr = 0;
1860 }
1861 $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty, $tva_npr);
1862 $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty, $tva_npr);
1863
1864 $type = $productsupplier->type;
1865 if (GETPOST('price_ht') != '' || GETPOST('multicurrency_price_ht') != '') {
1866 $price_base_type = 'HT';
1867 $pu = price2num($price_ht, 'MU');
1868 $pu_devise = price2num($price_ht_devise, 'CU');
1869 } elseif (GETPOST('price_ttc') != '' || GETPOST('multicurrency_price_ttc') != '') {
1870 $price_base_type = 'TTC';
1871 $pu = price2num($price_ttc, 'MU');
1872 $pu_devise = price2num($price_ttc_devise, 'CU');
1873 } else {
1874 $price_base_type = ($productsupplier->fourn_price_base_type ? $productsupplier->fourn_price_base_type : 'HT');
1875 if (empty($object->multicurrency_code) || ($productsupplier->fourn_multicurrency_code != $object->multicurrency_code)) { // If object is in a different currency and price not in this currency
1876 $pu = $productsupplier->fourn_pu;
1877 $pu_devise = 0;
1878 } else {
1879 $pu = $productsupplier->fourn_pu;
1880 $pu_devise = $productsupplier->fourn_multicurrency_unitprice;
1881 }
1882 }
1883
1884 $ref_supplier = $productsupplier->ref_supplier;
1885
1886 if (empty($pu)) {
1887 $pu = 0; // If pu is '' or null, we force to have a numeric value
1888 }
1889
1890 $result = $object->addline(
1891 $desc,
1892 $pu,
1893 $tva_tx,
1894 $localtax1_tx,
1895 $localtax2_tx,
1896 (float) $qty,
1897 $idprod,
1898 $remise_percent,
1900 $date_end,
1901 0,
1902 $tva_npr,
1903 $price_base_type,
1904 $type,
1905 min($rank, count($object->lines) + 1),
1906 0,
1907 $array_options,
1908 $productsupplier->fk_unit,
1909 0,
1910 $pu_devise,
1911 GETPOST('fourn_ref', 'alpha'),
1912 0
1913 );
1914 }
1915 if ($idprod == -99 || $idprod == 0) {
1916 // Product not selected
1917 $error++;
1918 $langs->load("errors");
1919 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductOrService")), null, 'errors');
1920 }
1921 if ($idprod == -1) {
1922 // Quantity too low
1923 $error++;
1924 $langs->load("errors");
1925 setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'errors');
1926 }
1927 } elseif (empty($error)) { // $price_ht is already set
1928 $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
1929 $tva_tx = str_replace('*', '', $tva_tx);
1930 $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
1931 $desc = $line_desc;
1932 $type = GETPOSTINT('type');
1933 $ref_supplier = GETPOST('fourn_ref', 'alpha');
1934
1935 $fk_unit = GETPOST('units') !== '' ? GETPOSTINT('units') : null;
1936
1937 if (!preg_match('/\‍((.*)\‍)/', $tva_tx)) {
1938 $tva_tx = price2num($tva_tx); // $txtva can have format '5,1' or '5.1' or '5.1(XXX)', we must clean only if '5,1'
1939 }
1940
1941 // Local Taxes
1942 $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty);
1943 $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty);
1944
1945 if (GETPOST('price_ht') != '' || GETPOST('multicurrency_price_ht') != '') {
1946 $pu_ht = price2num($price_ht, 'MU'); // $pu_ht must be rounded according to settings
1947 } else {
1948 $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
1949 $pu_ht = price2num((float) $pu_ttc / (1 + ((float) $tva_tx / 100)), 'MU'); // $pu_ht must be rounded according to settings
1950 }
1951 $price_base_type = 'HT';
1952 $pu_devise = price2num($price_ht_devise, 'CU');
1953
1954 $result = $object->addline($line_desc, (float) $pu_ht, $tva_tx, $localtax1_tx, $localtax2_tx, (float) $qty, 0, $remise_percent, $date_start, $date_end, 0, $tva_npr, $price_base_type, $type, -1, 0, $array_options, $fk_unit, 0, (float) $pu_devise, $ref_supplier);
1955 }
1956
1957 //print "xx".$tva_tx; exit;
1958 if (!$error && $result > 0) {
1959 $db->commit();
1960
1961 // Define output language
1962 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1963 $outputlangs = $langs;
1964 $newlang = '';
1965 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
1966 $newlang = GETPOST('lang_id', 'aZ09');
1967 }
1968 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1969 $newlang = $object->thirdparty->default_lang;
1970 }
1971 if (!empty($newlang)) {
1972 $outputlangs = new Translate("", $conf);
1973 $outputlangs->setDefaultLang($newlang);
1974 }
1975 $model = $object->model_pdf;
1976 $ret = $object->fetch($id); // Reload to get new records
1977
1978 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1979 if ($result < 0) {
1980 setEventMessages($object->error, $object->errors, 'errors');
1981 }
1982 }
1983
1984 unset($_POST ['prod_entry_mode']);
1985
1986 unset($_POST['qty']);
1987 unset($_POST['type']);
1988 unset($_POST['remise_percent']);
1989 unset($_POST['pu']);
1990 unset($_POST['price_ht']);
1991 unset($_POST['multicurrency_price_ht']);
1992 unset($_POST['price_ttc']);
1993 unset($_POST['fourn_ref']);
1994 unset($_POST['tva_tx']);
1995 unset($_POST['label']);
1996 unset($localtax1_tx);
1997 unset($localtax2_tx);
1998 unset($_POST['np_marginRate']);
1999 unset($_POST['np_markRate']);
2000 unset($_POST['dp_desc']);
2001 unset($_POST['idprodfournprice']);
2002 unset($_POST['units']);
2003
2004 unset($_POST['date_starthour']);
2005 unset($_POST['date_startmin']);
2006 unset($_POST['date_startsec']);
2007 unset($_POST['date_startday']);
2008 unset($_POST['date_startmonth']);
2009 unset($_POST['date_startyear']);
2010 unset($_POST['date_endhour']);
2011 unset($_POST['date_endmin']);
2012 unset($_POST['date_endsec']);
2013 unset($_POST['date_endday']);
2014 unset($_POST['date_endmonth']);
2015 unset($_POST['date_endyear']);
2016 } else {
2017 $db->rollback();
2018 setEventMessages($object->error, $object->errors, 'errors');
2019 }
2020
2021 $action = '';
2022 } elseif ($action == 'classin' && $usercancreate) {
2023 $object->fetch($id);
2024 $result = $object->setProject($projectid);
2025 } elseif ($action == 'confirm_edit' && $confirm == 'yes' && $usercancreate) {
2026 // Set invoice to draft status
2027 $object->fetch($id);
2028
2029 $totalpaid = $object->getSommePaiement();
2030 $resteapayer = $object->total_ttc - $totalpaid;
2031
2032 // We check that lines of invoices are exported in accountancy
2033 $ventilExportCompta = $object->getVentilExportCompta();
2034
2035 if (!$ventilExportCompta) {
2036 // We verify that no payment was done
2037 if ($resteapayer == price2num($object->total_ttc, 'MT', 1) && $object->status == FactureFournisseur::STATUS_VALIDATED) {
2038 $idwarehouse = GETPOST('idwarehouse');
2039
2040 $object->fetch_thirdparty();
2041
2042 $qualified_for_stock_change = 0;
2043 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
2044 $qualified_for_stock_change = $object->hasProductsOrServices(2);
2045 } else {
2046 $qualified_for_stock_change = $object->hasProductsOrServices(1);
2047 }
2048
2049 // Check parameters
2050 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') && $qualified_for_stock_change) {
2051 $langs->load("stocks");
2052 if (!$idwarehouse || $idwarehouse == -1) {
2053 $error++;
2054 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
2055 $action = '';
2056 }
2057 }
2058
2059 $object->setDraft($user, $idwarehouse);
2060
2061 // Define output language
2062 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
2063 $outputlangs = $langs;
2064 $newlang = '';
2065 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
2066 $newlang = GETPOST('lang_id', 'aZ09');
2067 }
2068 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
2069 $newlang = $object->thirdparty->default_lang;
2070 }
2071 if (!empty($newlang)) {
2072 $outputlangs = new Translate("", $conf);
2073 $outputlangs->setDefaultLang($newlang);
2074 }
2075 $model = $object->model_pdf;
2076 $ret = $object->fetch($id); // Reload to get new records
2077
2078 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
2079 if ($result < 0) {
2080 dol_print_error($db, $object->error, $object->errors);
2081 }
2082 }
2083
2084 $action = '';
2085 }
2086 }
2087 } elseif ($action == 'reopen' && $usercancreate) {
2088 // Set invoice to validated/unpaid status
2089 $result = $object->fetch($id);
2091 || ($object->status == FactureFournisseur::STATUS_ABANDONED && $object->close_code != 'replaced')) {
2092 $result = $object->setUnpaid($user);
2093 if ($result > 0) {
2094 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);
2095 exit;
2096 } else {
2097 setEventMessages($object->error, $object->errors, 'errors');
2098 }
2099 }
2100 }
2101
2102 // Actions when printing a doc from card
2103 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
2104
2105 // Actions to send emails
2106 $triggersendname = 'BILL_SUPPLIER_SENTBYMAIL';
2107 $paramname = 'id';
2108 $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO';
2109 $trackid = 'sinv'.$object->id;
2110 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
2111
2112 // Actions to build doc
2113 $upload_dir = getMultidirOutput($object);
2114 $permissiontoadd = $usercancreate;
2115 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
2116
2117 // Make calculation according to calculationrule
2118 if ($action == 'calculate' && $usercancreate) {
2119 $calculationrule = GETPOST('calculationrule');
2120
2121 $object->fetch($id);
2122 $object->fetch_thirdparty();
2123 $result = $object->update_price(0, (($calculationrule == 'totalofround') ? '0' : '1'), 0, $object->thirdparty);
2124 if ($result <= 0) {
2125 dol_print_error($db, $object->error, $object->errors);
2126 exit;
2127 }
2128 }
2129 if ($action == 'update_extras' && $permissiontoeditextra) {
2130 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
2131
2132 $attribute_name = GETPOST('attribute', 'aZ09');
2133
2134 // Fill array 'array_options' with data from update form
2135 $ret = $extrafields->setOptionalsFromPost(null, $object, $attribute_name);
2136 if ($ret < 0) {
2137 $error++;
2138 }
2139
2140 if (!$error) {
2141 $result = $object->updateExtraField($attribute_name, 'BILL_SUPPLIER_MODIFY');
2142 if ($result < 0) {
2143 setEventMessages($object->error, $object->errors, 'errors');
2144 $error++;
2145 }
2146 }
2147
2148 if ($error) {
2149 $action = 'edit_extras';
2150 }
2151 }
2152
2153 if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
2154 if ($action == 'addcontact' && $usercancreate) {
2155 $result = $object->fetch($id);
2156
2157 if ($result > 0 && $id > 0) {
2158 $contactid = (GETPOST('userid') ? GETPOSTINT('userid') : GETPOSTINT('contactid'));
2159 $typeid = (GETPOST('typecontact') ? GETPOSTINT('typecontact') : GETPOSTINT('type'));
2160 $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09'));
2161 }
2162
2163 if ($result >= 0) {
2164 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
2165 exit;
2166 } else {
2167 if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
2168 $langs->load("errors");
2169 setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
2170 } else {
2171 setEventMessages($object->error, $object->errors, 'errors');
2172 }
2173 }
2174 } elseif ($action == 'swapstatut' && $usercancreate) {
2175 // bascule du statut d'un contact
2176 if ($object->fetch($id)) {
2177 $result = $object->swapContactStatus(GETPOSTINT('ligne'));
2178 } else {
2180 }
2181 } elseif ($action == 'deletecontact' && $usercancreate) {
2182 // Efface un contact
2183 $object->fetch($id);
2184 $result = $object->delete_contact(GETPOSTINT("lineid"));
2185
2186 if ($result >= 0) {
2187 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
2188 exit;
2189 } else {
2191 }
2192 }
2193 }
2194}
2195
2196
2197/*
2198 * View
2199 */
2200
2201$form = new Form($db);
2202$formfile = new FormFile($db);
2203$bankaccountstatic = new Account($db);
2204$paymentstatic = new PaiementFourn($db);
2205if (isModEnabled('project')) {
2206 $formproject = new FormProjets($db);
2207}
2208
2209$now = dol_now();
2210
2211$title = $object->ref." - ".$langs->trans('Card');
2212if ($action == 'create') {
2213 $title = $langs->trans("NewSupplierInvoice");
2214}
2215$help_url = 'EN:Module_Suppliers_Invoices|FR:Module_Fournisseurs_Factures|ES:Módulo_Facturas_de_proveedores|DE:Modul_Lieferantenrechnungen';
2216llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-fourn-facture page-card');
2217
2218// Mode creation
2219if ($action == 'create') {
2220 $facturestatic = new FactureFournisseur($db);
2221 $selectedLines = array(); // Ensure initialised
2222
2223 print load_fiche_titre($langs->trans('NewSupplierInvoice'), '', 'supplier_invoice');
2224
2226
2227 $currency_code = $conf->currency;
2228 $vat_reverse_charge = 0;
2229
2230 $societe = '';
2231 if (GETPOSTINT('socid') > 0) {
2232 $societe = new Societe($db);
2233 $societe->fetch(GETPOSTINT('socid'));
2234 if (isModEnabled("multicurrency") && !empty($societe->multicurrency_code)) {
2235 $currency_code = $societe->multicurrency_code;
2236 }
2237 }
2238
2239 $objectsrc = null; // Initialise
2240 if (!empty($origin) && !empty($originid)) {
2241 // Parse element/subelement (ex: project_task)
2242 $element = $subelement = $origin;
2243
2244 if ($element == 'project') {
2245 $projectid = $originid;
2246 $element = 'projet';
2247 }
2248
2249 // For compatibility
2250 if ($element == 'order') {
2251 $element = $subelement = 'commande';
2252 }
2253 if ($element == 'propal') {
2254 $element = 'comm/propal';
2255 $subelement = 'propal';
2256 }
2257 if ($element == 'contract') {
2258 $element = $subelement = 'contrat';
2259 }
2260 if ($element == 'order_supplier') {
2261 $element = 'fourn';
2262 $subelement = 'fournisseur.commande';
2263 }
2264
2265 dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
2266 $classname = ucfirst($subelement);
2267 if ($classname == 'Fournisseur.commande') {
2268 $classname = 'CommandeFournisseur';
2269 }
2270 $objectsrc = new $classname($db);
2271 '@phan-var-force Project|Commande|Propal|Facture|Contrat|CommandeFournisseur|CommonObject $objectsrc';
2273 $objectsrc->fetch($originid);
2274 $objectsrc->fetch_thirdparty();
2275
2276 $projectid = (int) $objectsrc->fk_project;
2277 //$ref_client = (!empty($objectsrc->ref_client)?$object->ref_client:'');
2278 $soc = $objectsrc->thirdparty;
2279
2280 $cond_reglement_id = 0;
2281 $mode_reglement_id = 0;
2282 $fk_account = 0;
2283 $transport_mode_id = 0;
2284
2285 // set from object source
2286 if (!empty($objectsrc->cond_reglement_id)) {
2287 $cond_reglement_id = $objectsrc->cond_reglement_id;
2288 }
2289 if (!empty($objectsrc->mode_reglement_id)) {
2290 $mode_reglement_id = $objectsrc->mode_reglement_id;
2291 }
2292 if (!empty($objectsrc->fk_account)) {
2293 $fk_account = $objectsrc->fk_account;
2294 }
2295 if (!empty($objectsrc->transport_mode_id)) {
2296 $transport_mode_id = $objectsrc->transport_mode_id;
2297 }
2298
2299 if (empty($cond_reglement_id)
2300 || empty($mode_reglement_id)
2301 || empty($fk_account)
2302 || empty($transport_mode_id)
2303 ) {
2304 if ($origin == 'reception') {
2305 // try to get from source of reception (supplier order)
2306 if (!isset($objectsrc->supplier_order)) {
2307 $objectsrc->fetch_origin();
2308 }
2309
2310 if (!empty($objectsrc->origin_object)) {
2311 $originObject = $objectsrc->origin_object;
2312 if (empty($cond_reglement_id) && !empty($originObject->cond_reglement_id)) {
2313 $cond_reglement_id = $originObject->cond_reglement_id;
2314 }
2315 if (empty($mode_reglement_id) && !empty($originObject->mode_reglement_id)) {
2316 $mode_reglement_id = $originObject->mode_reglement_id;
2317 }
2318 if (empty($fk_account) && !empty($originObject->fk_account)) {
2319 $fk_account = $originObject->fk_account;
2320 }
2321 if (empty($transport_mode_id) && !empty($originObject->transport_mode_id)) {
2322 $transport_mode_id = $originObject->transport_mode_id;
2323 }
2324 }
2325 }
2326
2327 // try to get from third-party of source object
2328 if (!empty($soc)) {
2329 if (empty($cond_reglement_id) && !empty($soc->cond_reglement_supplier_id)) {
2330 $cond_reglement_id = $soc->cond_reglement_supplier_id;
2331 }
2332 if (empty($mode_reglement_id) && !empty($soc->mode_reglement_supplier_id)) {
2333 $mode_reglement_id = $soc->mode_reglement_supplier_id;
2334 }
2335 if (empty($fk_account) && !empty($soc->fk_account)) {
2336 $fk_account = $soc->fk_account;
2337 }
2338 if (empty($transport_mode_id) && !empty($soc->transport_mode_id)) {
2339 $transport_mode_id = $soc->transport_mode_id;
2340 }
2341 }
2342 }
2343
2344 if (isModEnabled("multicurrency")) {
2345 if (!empty($objectsrc->multicurrency_code)) {
2346 $currency_code = $objectsrc->multicurrency_code;
2347 }
2348 if (getDolGlobalString('MULTICURRENCY_USE_ORIGIN_TX') && !empty($objectsrc->multicurrency_tx)) {
2349 $currency_tx = $objectsrc->multicurrency_tx;
2350 }
2351 }
2352
2353 $datetmp = dol_mktime(12, 0, 0, GETPOSTINT('remonth'), GETPOSTINT('reday'), GETPOSTINT('reyear'));
2354 $dateinvoice = ($datetmp == '' ? (getDolGlobalString('MAIN_AUTOFILL_DATE') ? '' : -1) : $datetmp);
2355 $datetmp = dol_mktime(12, 0, 0, GETPOSTINT('echmonth'), GETPOSTINT('echday'), GETPOSTINT('echyear'));
2356 $datedue = ($datetmp == '' ? -1 : $datetmp);
2357
2358 // Replicate extrafields
2359 $objectsrc->fetch_optionals();
2360 $object->array_options = $objectsrc->array_options;
2361 } else {
2362 $cond_reglement_id = !empty($societe->cond_reglement_supplier_id) ? $societe->cond_reglement_supplier_id : 0;
2363 $mode_reglement_id = !empty($societe->mode_reglement_supplier_id) ? $societe->mode_reglement_supplier_id : 0;
2364 $vat_reverse_charge = (empty($societe) ? '' : $societe->vat_reverse_charge);
2365 $transport_mode_id = !empty($societe->transport_mode_supplier_id) ? $societe->transport_mode_supplier_id : 0;
2366 $fk_account = !empty($societe->fk_account) ? $societe->fk_account : 0;
2367 $datetmp = dol_mktime(12, 0, 0, GETPOSTINT('remonth'), GETPOSTINT('reday'), GETPOSTINT('reyear'));
2368 $dateinvoice = ($datetmp == '' ? (getDolGlobalInt('MAIN_AUTOFILL_DATE') ? '' : -1) : $datetmp);
2369 $datetmp = dol_mktime(12, 0, 0, GETPOSTINT('echmonth'), GETPOSTINT('echday'), GETPOSTINT('echyear'));
2370 $datedue = ($datetmp == '' ? -1 : $datetmp);
2371
2372 if (isModEnabled("multicurrency") && !empty($societe->multicurrency_code)) {
2373 $currency_code = $societe->multicurrency_code;
2374 }
2375 }
2376
2377 // when payment condition is empty (means not override by payment condition form a other object, like third-party), try to use default value
2378 if (empty($cond_reglement_id)) {
2379 $cond_reglement_id = GETPOST("cond_reglement_id");
2380 }
2381
2382 // when payment mode is empty (means not override by payment condition form a other object, like third-party), try to use default value
2383 if (empty($mode_reglement_id)) {
2384 $mode_reglement_id = GETPOST("mode_reglement_id");
2385 }
2386
2387 // If form was posted (but error returned), we must reuse the value posted in priority (standard Dolibarr behaviour)
2388 if (!GETPOST('changecompany')) {
2389 if (GETPOSTISSET('cond_reglement_id')) {
2390 $cond_reglement_id = GETPOSTINT('cond_reglement_id');
2391 }
2392 if (GETPOSTISSET('mode_reglement_id')) {
2393 $mode_reglement_id = GETPOSTINT('mode_reglement_id');
2394 }
2395 if (GETPOSTISSET('cond_reglement_id')) {
2396 $fk_account = GETPOSTINT('fk_account');
2397 }
2398 }
2399
2400 $note_public = $object->getDefaultCreateValueFor('note_public', ((!empty($origin) && !empty($originid) && is_object($objectsrc) && getDolGlobalString('FACTUREFOURN_REUSE_NOTES_ON_CREATE_FROM')) ? $objectsrc->note_public : null));
2401 $note_private = $object->getDefaultCreateValueFor('note_private', ((!empty($origin) && !empty($originid) && is_object($objectsrc) && getDolGlobalString('FACTUREFOURN_REUSE_NOTES_ON_CREATE_FROM')) ? $objectsrc->note_private : null));
2402
2403 if ($origin == 'contrat') {
2404 $langs->load("admin");
2405 $text = $langs->trans("ToCreateARecurringInvoice");
2406 $text .= ' '.$langs->trans("ToCreateARecurringInvoiceGene", $langs->transnoentitiesnoconv("MenuFinancial"), $langs->transnoentitiesnoconv("SupplierBills"), $langs->transnoentitiesnoconv("ListOfTemplates"));
2407 if (!getDolGlobalString('INVOICE_DISABLE_AUTOMATIC_RECURRING_INVOICE')) {
2408 $text .= ' '.$langs->trans("ToCreateARecurringInvoiceGeneAuto", $langs->transnoentitiesnoconv('Module2300Name'));
2409 }
2410 print info_admin($text, 0, 0, '0', 'opacitymedium').'<br>';
2411 }
2412
2413 print '<form name="add" action="'.$_SERVER["PHP_SELF"].'" method="post">';
2414 print '<input type="hidden" name="token" value="'.newToken().'">';
2415 print '<input type="hidden" name="action" value="add">';
2416 print '<input type="hidden" name="changecompany" value="0">'; // will be set to 1 by javascript so we know post is done after a company change
2417
2418 if (!empty($societe->id) && $societe->id > 0) {
2419 print '<input type="hidden" name="socid" value="'.$societe->id.'">'."\n";
2420 }
2421 print '<input type="hidden" name="origin" value="'.$origin.'">';
2422 print '<input type="hidden" name="originid" value="'.$originid.'">';
2423 if (!empty($currency_tx)) {
2424 print '<input type="hidden" name="originmulticurrency_tx" value="'.$currency_tx.'">';
2425 }
2426 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
2427
2428 print dol_get_fiche_head();
2429
2430 // Call Hook tabContentCreateSupplierInvoice
2431 $parameters = array();
2432 // Note that $action and $object may be modified by hook
2433 $reshook = $hookmanager->executeHooks('tabContentCreateSupplierInvoice', $parameters, $object, $action);
2434 if (empty($reshook)) {
2435 print '<table class="border centpercent">';
2436
2437 // Ref
2438 //print '<tr><td class="titlefieldcreate">'.$langs->trans('Ref').'</td><td>'.$langs->trans('Draft').'</td></tr>';
2439
2440 $exampletemplateinvoice = new FactureFournisseurRec($db);
2441 $invoice_predefined = new FactureFournisseurRec($db);
2442 if (empty($origin) && empty($originid) && $fac_recid > 0) {
2443 $invoice_predefined->fetch($fac_recid);
2444 }
2445
2446 // Third party
2447 print '<tr><td class="fieldrequired">'.$langs->trans('Supplier').'</td>';
2448 print '<td>';
2449
2450 if (!empty($societe->id) && $societe->id > 0 && ($fac_recid <= 0 || !empty($invoice_predefined->frequency))) {
2451 $absolute_discount = $societe->getAvailableDiscounts(null, '', 0, 1);
2452 print $societe->getNomUrl(1, 'supplier');
2453 print '<input type="hidden" name="socid" value="'.$societe->id.'">';
2454 } else {
2455 $filter = '((s.fournisseur:=:1) AND (s.status:=:1))';
2456 print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company(empty($societe->id) ? 0 : $societe->id, 'socid', $filter, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth175 widthcentpercentminusxx maxwidth500');
2457 // reload page to retrieve supplier information
2458 if (!getDolGlobalString('RELOAD_PAGE_ON_SUPPLIER_CHANGE_DISABLED')) {
2459 print '<script type="text/javascript">
2460 $(document).ready(function() {
2461 $("#socid").change(function() {
2462 console.log("We have changed the company - Reload page");
2463 // reload page
2464 $("input[name=action]").val("create");
2465 $("input[name=changecompany]").val("1");
2466 $("form[name=add]").submit();
2467 });
2468 });
2469 </script>';
2470 }
2471 if ($fac_recid <= 0) {
2472 print ' <a href="'.DOL_URL_ROOT.'/societe/card.php?action=create&client=0&fournisseur=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create').'"><span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddThirdParty").'"></span></a>';
2473 }
2474 }
2475 print '</td></tr>';
2476
2477 // Overwrite some values if creation of invoice is from a predefined invoice
2478 if (empty($origin) && empty($originid) && $fac_recid > 0) {
2479 $invoice_predefined->fetch($fac_recid);
2480
2481 $dateinvoice = $invoice_predefined->date_when; // To use next gen date by default later
2482 if (empty($projectid)) {
2483 $projectid = $invoice_predefined->fk_project;
2484 }
2485 $cond_reglement_id = $invoice_predefined->cond_reglement_id;
2486 $mode_reglement_id = $invoice_predefined->mode_reglement_id;
2487 $fk_account = $invoice_predefined->fk_account;
2488 $note_public = $invoice_predefined->note_public;
2489 $note_private = $invoice_predefined->note_private;
2490
2491 if (!empty($invoice_predefined->multicurrency_code)) {
2492 $currency_code = $invoice_predefined->multicurrency_code;
2493 }
2494 if (!empty($invoice_predefined->multicurrency_tx)) {
2495 $currency_tx = $invoice_predefined->multicurrency_tx;
2496 }
2497
2498 $sql = 'SELECT r.rowid, r.titre as title, r.total_ttc';
2499 $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_rec as r';
2500 $sql .= ' WHERE r.fk_soc = '. (int) $invoice_predefined->socid;
2501
2502 $resql = $db->query($sql);
2503 if ($resql) {
2504 $num = $db->num_rows($resql);
2505 $i = 0;
2506
2507 if ($num > 0) {
2508 print '<tr><td>'.$langs->trans('CreateFromRepeatableInvoice').'</td><td>';
2509 //print '<input type="hidden" name="fac_rec" id="fac_rec" value="'.$fac_recid.'">';
2510 print '<select class="flat" id="fac_rec" name="fac_rec">'; // We may want to change the template to use
2511 print '<option value="0" selected></option>';
2512 while ($i < $num) {
2513 $objp = $db->fetch_object($resql);
2514 print '<option value="'.$objp->rowid.'"';
2515 if ($fac_recid == $objp->rowid) {
2516 print ' selected';
2517 $exampletemplateinvoice->fetch($fac_recid);
2518 }
2519 print '>'.$objp->title.' ('.price($objp->total_ttc).' '.$langs->trans("TTC").')</option>';
2520 $i++;
2521 }
2522 print '</select>';
2523 // Option to reload page to retrieve customer information. Note, this clear other input
2524 if (!getDolGlobalString('RELOAD_PAGE_ON_TEMPLATE_CHANGE_DISABLED')) {
2525 print '<script type="text/javascript">
2526 $(document).ready(function() {
2527 $("#fac_rec").change(function() {
2528 console.log("We have changed the template invoice - Reload page");
2529 // reload page
2530 $("input[name=action]").val("create");
2531 $("form[name=add]").submit();
2532 });
2533 });
2534 </script>';
2535 }
2536 print '</td></tr>';
2537 }
2538 $db->free($resql);
2539 } else {
2541 }
2542 }
2543
2544 print '<tr><td class="tdtop fieldrequired">'.$langs->trans('Type').'</td><td>';
2545
2546 print '<div class="tagtable">'."\n";
2547
2548 // Standard invoice
2549 print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2550 $tmp = '<input type="radio" id="radio_standard" name="type" value="0"'.(GETPOSTINT('type') ? '' : 'checked').'> ';
2551 $desc = $form->textwithpicto($tmp.'<label for="radio_standard">'.$langs->trans("InvoiceStandardAsk").'</label>', $langs->transnoentities("InvoiceStandardDesc"), 1, 'help', '', 0, 3);
2552 print $desc;
2553 print '</div></div>';
2554
2555 if (empty($origin) || (($origin == 'supplier_proposal' || $origin == 'order_supplier' || $origin == 'reception') && !empty($originid))) {
2556 // Deposit - Down payment
2557 if (!getDolGlobalString('INVOICE_DISABLE_DEPOSIT')) {
2558 print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2559 $tmp = '<input type="radio" id="radio_deposit" name="type" value="3"' . (GETPOSTINT('type') == 3 ? ' checked' : '') . '> ';
2560 print '<script type="text/javascript">
2561 jQuery(document).ready(function() {
2562 jQuery("#typestandardinvoice, #valuestandardinvoice").click(function() {
2563 jQuery("#radio_standard").prop("checked", true);
2564 });
2565 jQuery("#typedeposit, #valuedeposit").click(function() {
2566 jQuery("#radio_deposit").prop("checked", true);
2567 });
2568 jQuery("#typedeposit").change(function() {
2569 console.log("We change type of down payment");
2570 jQuery("#radio_deposit").prop("checked", true);
2571 setRadioForTypeOfInvoice();
2572 });
2573 jQuery("#radio_standard, #radio_deposit, #radio_replacement, #radio_template").change(function() {
2574 setRadioForTypeOfInvoice();
2575 });
2576 function setRadioForTypeOfInvoice() {
2577 console.log("Change radio");
2578 if (jQuery("#radio_deposit").prop("checked") && (jQuery("#typedeposit").val() == \'amount\' || jQuery("#typedeposit").val() == \'variable\')) {
2579 jQuery(".checkforselect").prop("disabled", true);
2580 jQuery(".checkforselect").prop("checked", false);
2581 } else {
2582 jQuery(".checkforselect").prop("disabled", false);
2583 jQuery(".checkforselect").prop("checked", true);
2584 }
2585 }
2586 });
2587 </script>';
2588
2589 $tmp = $tmp.'<label for="radio_deposit" >'.$langs->trans("InvoiceDeposit").'</label>';
2590 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
2591 $desc = $form->textwithpicto($tmp, $langs->transnoentities("InvoiceDepositDesc"), 1, 'help', '', 0, 3);
2592 print '<table class="nobordernopadding"><tr>';
2593 print '<td>';
2594 print $desc;
2595 print '</td>';
2596 if ($origin == 'supplier_proposal' || $origin == 'order_supplier' || $origin == 'reception') {
2597 print '<td class="nowrap" style="padding-left: 15px">';
2598 $arraylist = array(
2599 'amount' => $langs->transnoentitiesnoconv('FixAmount', $langs->transnoentitiesnoconv('Deposit')),
2600 'variable' => $langs->transnoentitiesnoconv('VarAmountOneLine', $langs->transnoentitiesnoconv('Deposit')),
2601 'variablealllines' => $langs->transnoentitiesnoconv('VarAmountAllLines')
2602 );
2603 $typedeposit = GETPOST('typedeposit', 'aZ09');
2604 $valuedeposit = GETPOST('valuedeposit', 'int');
2605 $deposit_percent = null;
2606 if ($origin == 'reception') {
2607 // try to get from source of reception (supplier order)
2608 if (!isset($objectsrc->origin_object)) {
2609 $objectsrc->fetch_origin();
2610 }
2611 if (!empty($objectsrc->origin_object)) {
2612 $deposit_percent = $objectsrc->origin_object->deposit_percent;
2613 }
2614 } elseif (!empty($objectsrc->deposit_percent)) {
2615 $deposit_percent = $objectsrc->deposit_percent;
2616 }
2617 if (empty($typedeposit) && !empty($deposit_percent)) {
2618 $origin_payment_conditions_deposit_percent = getDictionaryValue('c_payment_term', 'deposit_percent', $objectsrc->cond_reglement_id);
2619 if (!empty($origin_payment_conditions_deposit_percent)) {
2620 $typedeposit = 'variable';
2621 }
2622 }
2623 if (empty($valuedeposit) && $typedeposit == 'variable' && !empty($deposit_percent)) {
2624 $valuedeposit = $deposit_percent;
2625 }
2626 print $form->selectarray('typedeposit', $arraylist, $typedeposit, 0, 0, 0, '', 1);
2627 print '</td>';
2628 print '<td class="nowrap" style="padding-left: 5px">';
2629 print '<span class="opacitymedium paddingleft">'.$langs->trans("AmountOrPercent").'</span><input type="text" id="valuedeposit" name="valuedeposit" class="width75 right" value="' . $valuedeposit . '"/>';
2630 print '</td>';
2631 }
2632 print '</tr></table>';
2633
2634 print '</div></div>';
2635 }
2636 }
2637
2638 /* Not yet supported for supplier
2639 if ($societe->id > 0)
2640 {
2641 // Replacement
2642 if (empty($conf->global->INVOICE_DISABLE_REPLACEMENT))
2643 {
2644 // Type invoice
2645 $facids = $facturestatic->list_replacable_supplier_invoices($societe->id);
2646 if ($facids < 0) {
2647 dol_print_error($db, $facturestatic->error, $facturestatic->errors);
2648 exit();
2649 }
2650 $options = "";
2651 foreach ($facids as $facparam)
2652 {
2653 $options .= '<option value="' . $facparam ['id'] . '"';
2654 if ($facparam ['id'] == GETPOST('fac_replacement') {
2655 $options .= ' selected';
2656 }
2657 $options .= '>' . $facparam ['ref'];
2658 $options .= ' (' . $facturestatic->LibStatut(0, $facparam ['status']) . ')';
2659 $options .= '</option>';
2660 }
2661
2662 print '<!-- replacement line -->';
2663 print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2664 $tmp='<input type="radio" name="type" id="radio_replacement" value="1"' . (GETPOSTINT('type') == 1 ? ' checked' : '');
2665 if (! $options) $tmp.=' disabled';
2666 $tmp.='> ';
2667 print '<script type="text/javascript">
2668 jQuery(document).ready(function() {
2669 jQuery("#fac_replacement").change(function() {
2670 jQuery("#radio_replacement").prop("checked", true);
2671 });
2672 });
2673 </script>';
2674 $text = $tmp.$langs->trans("InvoiceReplacementAsk") . ' ';
2675 $text .= '<select class="flat" name="fac_replacement" id="fac_replacement"';
2676 if (! $options)
2677 $text .= ' disabled';
2678 $text .= '>';
2679 if ($options) {
2680 $text .= '<option value="-1">&nbsp;</option>';
2681 $text .= $options;
2682 } else {
2683 $text .= '<option value="-1">' . $langs->trans("NoReplacableInvoice") . '</option>';
2684 }
2685 $text .= '</select>';
2686 $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceReplacementDesc"), 1, 'help', '', 0, 3);
2687 print $desc;
2688 print '</div></div>';
2689 }
2690 }
2691 else
2692 {
2693 print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2694 $tmp='<input type="radio" name="type" id="radio_replacement" value="0" disabled> ';
2695 $text = $tmp.$langs->trans("InvoiceReplacement") . ' ';
2696 $text.= '('.$langs->trans("YouMustCreateInvoiceFromSupplierThird").') ';
2697 $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceReplacementDesc"), 1, 'help', '', 0, 3);
2698 print $desc;
2699 print '</div></div>';
2700 }
2701 */
2702
2703 if (empty($origin)) {
2704 if (!empty($societe->id) && $societe->id > 0) {
2705 // Credit note
2706 if (!getDolGlobalString('INVOICE_DISABLE_CREDIT_NOTE')) {
2707 // Show link for credit note
2708 $facids = $facturestatic->list_qualified_avoir_supplier_invoices($societe->id);
2709 if ($facids < 0) {
2710 dol_print_error($db, $facturestatic->error, $facturestatic->errors);
2711 exit;
2712 }
2713 $optionsav = "";
2714 $newinvoice_static = new FactureFournisseur($db);
2715 foreach ($facids as $key => $valarray) {
2716 $newinvoice_static->id = $key;
2717 $newinvoice_static->ref = $valarray ['ref'];
2718 $newinvoice_static->status = $valarray ['status'];
2719 $newinvoice_static->statut = $valarray ['status'];
2720 $newinvoice_static->type = $valarray ['type'];
2721 $newinvoice_static->paid = $valarray ['paye'];
2722 $newinvoice_static->paye = $valarray ['paye'];
2723
2724 $optionsav .= '<option value="'.$key.'"';
2725 if ($key == GETPOSTINT('fac_avoir')) {
2726 $optionsav .= ' selected';
2727 // pre-fill extra fields with selected source invoice
2728 $newinvoice_static->fetch_optionals($key);
2729 $object->array_options = $newinvoice_static->array_options;
2730 }
2731 $optionsav .= '>';
2732 $optionsav .= $newinvoice_static->ref;
2733 $optionsav .= ' ('.$newinvoice_static->getLibStatut(1, $valarray ['paymentornot']).')';
2734 $optionsav .= '</option>';
2735 }
2736
2737 print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2738 $tmp = '<input type="radio" id="radio_creditnote" name="type" value="2"'.(GETPOSTINT('type') == 2 ? ' checked' : '');
2739 if (!$optionsav && !getDolGlobalString('INVOICE_CREDIT_NOTE_STANDALONE')) {
2740 $tmp .= ' disabled';
2741 }
2742 $tmp .= '> ';
2743 // Show credit note options only if we checked credit note
2744 print '<script type="text/javascript">
2745 jQuery(document).ready(function() {
2746 if (! jQuery("#radio_creditnote").is(":checked"))
2747 {
2748 jQuery("#credit_note_options").hide();
2749 }
2750 jQuery("#radio_creditnote").click(function() {
2751 jQuery("#credit_note_options").show();
2752 });
2753 jQuery("#radio_standard, #radio_replacement, #radio_deposit").click(function() {
2754 jQuery("#credit_note_options").hide();
2755 });
2756 });
2757 </script>';
2758 $text = $tmp.'<label for="radio_creditnote">'.$langs->transnoentities("InvoiceAvoirAsk").'</label> ';
2759 // $text.='<input type="text" value="">';
2760 $text .= '<select class="flat valignmiddle" name="fac_avoir" id="fac_avoir"';
2761 if (!$optionsav) {
2762 $text .= ' disabled';
2763 }
2764 $text .= '>';
2765 if ($optionsav) {
2766 $text .= '<option value="-1"></option>';
2767 $text .= $optionsav;
2768 } else {
2769 $text .= '<option value="-1">'.$langs->trans("NoInvoiceToCorrect").'</option>';
2770 }
2771 $text .= '</select>';
2772 $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1, 'help', '', 0, 3);
2773 print $desc;
2774
2775 print '<div id="credit_note_options" class="clearboth">';
2776 print '&nbsp;&nbsp;&nbsp; <input type="checkbox" name="invoiceAvoirWithLines" id="invoiceAvoirWithLines" value="1" onclick="if($(this).is(\':checked\') ) { $(\'#radio_creditnote\').prop(\'checked\', true); $(\'#invoiceAvoirWithPaymentRestAmount\').removeAttr(\'checked\'); }" '.(GETPOSTINT('invoiceAvoirWithLines') > 0 ? 'checked' : '').' /> ';
2777 print '<label for="invoiceAvoirWithLines">'.$langs->trans('invoiceAvoirWithLines')."</label>";
2778 print '<br>&nbsp;&nbsp;&nbsp; <input type="checkbox" name="invoiceAvoirWithPaymentRestAmount" id="invoiceAvoirWithPaymentRestAmount" value="1" onclick="if($(this).is(\':checked\') ) { $(\'#radio_creditnote\').prop(\'checked\', true); $(\'#invoiceAvoirWithLines\').removeAttr(\'checked\'); }" '.(GETPOSTINT('invoiceAvoirWithPaymentRestAmount') > 0 ? 'checked' : '').' /> ';
2779 print '<label for="invoiceAvoirWithPaymentRestAmount">'.$langs->trans('invoiceAvoirWithPaymentRestAmount')."</label>";
2780 print '</div>';
2781
2782 print '</div></div>';
2783 }
2784 } else {
2785 print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2786 if (!getDolGlobalString('INVOICE_CREDIT_NOTE_STANDALONE')) {
2787 $tmp = '<input type="radio" name="type" id="radio_creditnote" value="0" disabled> ';
2788 } else {
2789 $tmp = '<input type="radio" name="type" id="radio_creditnote" value="2"> ';
2790 }
2791 $text = $tmp.$langs->trans("InvoiceAvoir").' ';
2792 $text .= '<span class="opacitymedium">('.$langs->trans("YouMustCreateInvoiceFromSupplierThird").')</span> ';
2793 $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1, 'help', '', 0, 3);
2794 print $desc;
2795 print '</div></div>'."\n";
2796 }
2797 }
2798
2799 print '</div><br>';
2800
2801 print '</td></tr>';
2802
2803
2804 // Ref supplier
2805 print '<tr><td class="fieldrequired">';
2806 print $form->textwithpicto($langs->trans('RefSupplierBill'), $langs->trans("RefOfOnVendorSide", $langs->trans("SupplierBill"))).'</td><td>';
2807 print '<input name="ref_supplier" value="'.(GETPOSTISSET('ref_supplier') ? GETPOST('ref_supplier') : (!empty($objectsrc->ref_supplier) ? $objectsrc->ref_supplier : '')).'" type="text" spellcheck="false"';
2808 if (!empty($societe->id) && $societe->id > 0) {
2809 print ' autofocus';
2810 }
2811 print '></td>';
2812 print '</tr>';
2813
2814
2815 // Invoice Subtype
2816 if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED')) {
2817 print '<tr><td class="fieldrequired">'.$langs->trans('InvoiceSubtype').'</td><td colspan="2">';
2818 print $form->getSelectInvoiceSubtype(GETPOSTINT('subtype'), 'subtype', 1, 0, '');
2819 print '</td></tr>';
2820 }
2821
2822 if (!empty($societe->id) && $societe->id > 0) {
2823 // Discounts for third party
2824 print '<tr><td>'.$langs->trans('Discounts').'</td><td>';
2825
2826 $thirdparty = $societe;
2827 $discount_type = 1;
2828 $backtopage = urlencode($_SERVER["PHP_SELF"].'?socid='.$societe->id.'&action='.$action.'&origin='.GETPOST('origin').'&originid='.GETPOST('originid'));
2829 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
2830
2831 print '</td></tr>';
2832 }
2833
2834 // Label
2835 print '<tr><td>'.$langs->trans('Label').'</td><td><input class="minwidth300" name="label" value="'.dol_escape_htmltag(GETPOST('label')).'" type="text"></td></tr>';
2836
2837
2838 // Date invoice
2839 print '<tr><td class="fieldrequired">'.$langs->trans('DateInvoice').'</td><td>';
2840 print img_picto('', 'action', 'class="pictofixedwidth"');
2841 print $form->selectDate($dateinvoice ? (int) $dateinvoice : '', '', 0, 0, 0, "add", 1, 1);
2842 print '</td></tr>';
2843
2844 // Date point of tax
2845 if (getDolGlobalString('INVOICE_POINTOFTAX_DATE')) {
2846 print '<tr><td class="fieldrequired">'.$langs->trans('DatePointOfTax').'</td><td>';
2847 print img_picto('', 'action', 'class="pictofixedwidth"');
2848 print $form->selectDate($date_pointoftax ? $date_pointoftax : -1, 'date_pointoftax', 0, 0, 0, "add", 1, 1);
2849 print '</td></tr>';
2850 }
2851
2852 // Payment term
2853 print '<tr><td class="nowrap">'.$langs->trans('PaymentConditionsShort').'</td><td>';
2854 print img_picto('', 'payment', 'class="pictofixedwidth"');
2855 print $form->getSelectConditionsPaiements($cond_reglement_id, 'cond_reglement_id', -1, 1, 0, 'maxwidth200 widthcentpercentminusx');
2856 print '</td></tr>';
2857
2858 // Due date
2859 print '<tr><td>'.$langs->trans('DateMaxPayment').'</td><td>';
2860 print img_picto('', 'action', 'class="pictofixedwidth"');
2861 print $form->selectDate($datedue, 'ech', 0, 0, 0, "add", 1, 1);
2862 print '</td></tr>';
2863
2864 // Payment mode
2865 print '<tr><td>'.$langs->trans('PaymentMode').'</td><td>';
2866 print img_picto('', 'bank', 'class="pictofixedwidth"');
2867 $form->select_types_paiements((string) $mode_reglement_id, 'mode_reglement_id', 'DBIT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx');
2868 print '</td></tr>';
2869
2870 // Bank Account
2871 if (isModEnabled("bank")) {
2872 print '<tr><td>'.$langs->trans('BankAccount').'</td><td>';
2873 // when bank account is empty (means not override by payment mode form a other object, like third-party), try to use default value
2874 print img_picto('', 'bank_account', 'class="pictofixedwidth"').$form->select_comptes((int) $fk_account, 'fk_account', 0, '', 1, '', 0, 'maxwidth200 widthcentpercentminusx', 1);
2875 print '</td></tr>';
2876 }
2877
2878 // Project
2879 if (isModEnabled('project')) {
2880 $formproject = new FormProjets($db);
2881
2882 $langs->load('projects');
2883 print '<tr><td>'.$langs->trans('Project').'</td><td>';
2884 print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects((!getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx');
2885 print ' <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.(!empty($soc->id) ? $soc->id : 0).'&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create&socid='.(!empty($soc->id) ? $soc->id : 0).($fac_recid > 0 ? '&fac_rec='.$fac_recid : '')).'"><span class="fa fa-plus-circle valignmiddle" title="'.$langs->trans("AddProject").'"></span></a>';
2886 print '</td></tr>';
2887 }
2888
2889 // Incoterms
2890 if (isModEnabled('incoterm')) {
2891 print '<tr>';
2892 print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), !empty($objectsrc->label_incoterms) ? $objectsrc->label_incoterms : '', 1).'</label></td>';
2893 print '<td colspan="3" class="maxwidthonsmartphone">';
2894 print img_picto('', 'incoterm', 'class="pictofixedwidth"');
2895 print $form->select_incoterms(GETPOSTISSET('incoterm_id') ? GETPOST('incoterm_id', 'alphanohtml') : (!empty($objectsrc->fk_incoterms) ? $objectsrc->fk_incoterms : ''), GETPOSTISSET('location_incoterms') ? GETPOST('location_incoterms', 'alphanohtml') : (!empty($objectsrc->location_incoterms) ? $objectsrc->location_incoterms : ''));
2896 print '</td></tr>';
2897 }
2898
2899 // Vat reverse-charge by default
2900 if (getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
2901 require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
2902 print '<tr><td>' . $langs->trans('VATReverseCharge') . '</td><td>';
2903 // Try to propose to use VAT reverse charge even if the VAT reverse charge is not activated in the supplier card, if this corresponds to the context of use, the activation is proposed
2904 if (GETPOSTISSET('vat_reverse_charge')) { // Check if form was submitted previously
2905 $vat_reverse_charge = (GETPOST('vat_reverse_charge', 'alpha') == 'on' || GETPOST('vat_reverse_charge', 'alpha') == '1') ? 1 : 0;
2906 } elseif ($vat_reverse_charge == 1 || $societe->vat_reverse_charge == 1 || ($societe->country_code != 'FR' && isInEEC($societe) && !empty($societe->tva_intra))) {
2907 $vat_reverse_charge = 1;
2908 } else {
2909 $vat_reverse_charge = 0;
2910 }
2911
2912 print '<input type="checkbox" name="vat_reverse_charge"'. (!empty($vat_reverse_charge) ? ' checked ' : '') . '>';
2913 print '</td></tr>';
2914 }
2915
2916 // Multicurrency
2917 if (isModEnabled("multicurrency")) {
2918 print '<tr>';
2919 print '<td>'.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).'</td>';
2920 print '<td class="maxwidthonsmartphone">';
2921 print img_picto('', 'currency', 'class="pictofixedwidth"');
2922 $used_currency_code = $currency_code;
2923 if (!GETPOST('changecompany')) {
2924 $used_currency_code = GETPOSTISSET('multicurrency_code') ? GETPOST('multicurrency_code', 'alpha') : $currency_code;
2925 }
2926 print $form->selectMultiCurrency($used_currency_code, 'multicurrency_code');
2927 print '</td></tr>';
2928 }
2929
2930 // Help of substitution key
2931 $htmltext = '';
2932 if ($fac_recid > 0) {
2933 $dateexample = $dateinvoice;
2934 if (empty($dateexample)) {
2935 $dateexample = dol_now();
2936 }
2937 $substitutionarray = array(
2938 '__TOTAL_HT__' => $langs->trans("AmountHT").' ('.$langs->trans("Example").': '.price($exampletemplateinvoice->total_ht).')',
2939 '__TOTAL_TTC__' => $langs->trans("AmountTTC").' ('.$langs->trans("Example").': '.price($exampletemplateinvoice->total_ttc).')',
2940 '__INVOICE_PREVIOUS_MONTH__' => $langs->trans("PreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%m').')',
2941 '__INVOICE_MONTH__' => $langs->trans("MonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%m').')',
2942 '__INVOICE_NEXT_MONTH__' => $langs->trans("NextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%m').')',
2943 '__INVOICE_PREVIOUS_MONTH_TEXT__' => $langs->trans("TextPreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%B').')',
2944 '__INVOICE_MONTH_TEXT__' => $langs->trans("TextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%B').')',
2945 '__INVOICE_NEXT_MONTH_TEXT__' => $langs->trans("TextNextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%B').')',
2946 '__INVOICE_PREVIOUS_YEAR__' => $langs->trans("PreviousYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'y'), '%Y').')',
2947 '__INVOICE_YEAR__' => $langs->trans("YearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%Y').')',
2948 '__INVOICE_NEXT_YEAR__' => $langs->trans("NextYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'y'), '%Y').')'
2949 );
2950
2951 $htmltext = '<i>'.$langs->trans("FollowingConstantsWillBeSubstituted").':<br>';
2952 foreach ($substitutionarray as $key => $val) {
2953 $htmltext .= $key.' = '.$langs->trans($val).'<br>';
2954 }
2955 $htmltext .= '</i>';
2956 }
2957
2958 // Intracomm report
2959 if (isModEnabled('intracommreport')) {
2960 $langs->loadLangs(array("intracommreport"));
2961 print '<!-- If module intracomm on -->'."\n";
2962 print '<tr><td>'.$langs->trans('IntracommReportTransportMode').'</td><td>';
2963 $form->selectTransportMode(GETPOSTISSET('transport_mode_id') ? GETPOST('transport_mode_id') : $transport_mode_id, 'transport_mode_id');
2964 print '</td></tr>';
2965 }
2966
2967 if (empty($reshook)) {
2968 print $object->showOptionals($extrafields, 'create');
2969 }
2970
2971 // Categories
2972 if (isModEnabled("category")) {
2973 print '<tr><td>'.$langs->trans("Categories").'</td><td colspan="3">';
2974 print $form->selectCategories(Categorie::TYPE_SUPPLIER_INVOICE, 'categories', $object);
2975 print "</td></tr>";
2976 }
2977
2978 // Public note
2979 print '<tr><td>'.$langs->trans('NotePublic').'</td>';
2980 print '<td>';
2981 $doleditor = new DolEditor('note_public', (GETPOSTISSET('note_public') ? GETPOST('note_public', 'restricthtml') : $note_public), '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%');
2982 print $doleditor->Create(1);
2983 print '</td>';
2984 // print '<td><textarea name="note" wrap="soft" cols="60" rows="'.ROWS_5.'"></textarea></td>';
2985 print '</tr>';
2986
2987 // Private note
2988 print '<tr><td>'.$langs->trans('NotePrivate').'</td>';
2989 print '<td>';
2990 $doleditor = new DolEditor('note_private', (GETPOSTISSET('note_private') ? GETPOST('note_private', 'restricthtml') : $note_private), '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%');
2991 print $doleditor->Create(1);
2992 print '</td>';
2993 // print '<td><textarea name="note" wrap="soft" cols="60" rows="'.ROWS_5.'"></textarea></td>';
2994 print '</tr>';
2995
2996
2997 if (!empty($objectsrc) && $classname !== null) {
2998 print "\n<!-- ".$classname." info -->";
2999 print "\n";
3000 print '<input type="hidden" name="amount" value="'.$objectsrc->total_ht.'">'."\n";
3001 print '<input type="hidden" name="total" value="'.$objectsrc->total_ttc.'">'."\n";
3002 print '<input type="hidden" name="tva" value="'.$objectsrc->total_tva.'">'."\n";
3003 print '<input type="hidden" name="origin" value="'.$objectsrc->element.'">';
3004 print '<input type="hidden" name="originid" value="'.$objectsrc->id.'">';
3005
3006 $txt = $langs->trans($classname);
3007 if ($classname == 'CommandeFournisseur') {
3008 $langs->load('orders');
3009 $txt = $langs->trans("SupplierOrder");
3010 }
3011 print '<tr><td>'.$txt.'</td><td>'.$objectsrc->getNomUrl(1);
3012 // We check if Origin document (id and type is known) has already at least one invoice attached to it
3013 $objectsrc->fetchObjectLinked($originid, $origin, null, 'invoice_supplier');
3014
3015 if (isset($objectsrc->linkedObjects['invoice_supplier'])) {
3016 $invoice_supplier = $objectsrc->linkedObjects['invoice_supplier'];
3017 } else {
3018 $invoice_supplier = [];
3019 }
3020 '@phan-var-force null|FactureFournisseur[] $invoice_supplier';
3021
3022 // count function need a array as argument (Note: the array must implement Countable too)
3023 if (is_array($invoice_supplier)) {
3024 $cntinvoice = count($invoice_supplier);
3025
3026 if ($cntinvoice >= 1) {
3027 setEventMessages('WarningBillExist', null, 'warnings');
3028 echo ' ('.$langs->trans('LatestRelatedBill').end($invoice_supplier)->getNomUrl(1).')';
3029 }
3030 }
3031
3032 print '</td></tr>';
3033 print '<tr><td>'.$langs->trans('AmountHT').'</td><td>'.price($objectsrc->total_ht).'</td></tr>';
3034 print '<tr><td>'.$langs->trans('AmountVAT').'</td><td>'.price($objectsrc->total_tva)."</td></tr>";
3035 if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) { //Localtax1
3036 print '<tr><td>'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax1)."</td></tr>";
3037 }
3038
3039 if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) { //Localtax2
3040 print '<tr><td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax2)."</td></tr>";
3041 }
3042 print '<tr><td>'.$langs->trans('AmountTTC').'</td><td>'.price($objectsrc->total_ttc)."</td></tr>";
3043
3044 if (isModEnabled("multicurrency")) {
3045 print '<tr><td>'.$langs->trans('MulticurrencyAmountHT').'</td><td>'.price($objectsrc->multicurrency_total_ht, 0, $langs, 1, -1, -1, $objectsrc->multicurrency_code).'</td></tr>';
3046 print '<tr><td>'.$langs->trans('MulticurrencyAmountVAT').'</td><td>'.price($objectsrc->multicurrency_total_tva, 0, $langs, 1, -1, -1, $objectsrc->multicurrency_code)."</td></tr>";
3047 print '<tr><td>'.$langs->trans('MulticurrencyAmountTTC').'</td><td>'.price($objectsrc->multicurrency_total_ttc, 0, $langs, 1, -1, -1, $objectsrc->multicurrency_code)."</td></tr>";
3048 }
3049 }
3050
3051 // Other options
3052 $parameters = array();
3053 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
3054 print $hookmanager->resPrint;
3055
3056
3057 print "</table>\n";
3058 }
3059
3060 print dol_get_fiche_end();
3061
3062 print $form->buttonsSaveCancel("CreateDraft");
3063
3064 // Show origin lines
3065 if (!empty($objectsrc)) {
3066 print '<br>';
3067
3068 $title = $langs->trans('ProductsAndServices');
3069 print load_fiche_titre($title);
3070
3071 print '<div class="div-table-responsive-no-min">';
3072 print '<table class="noborder centpercent">';
3073
3074 $objectsrc->printOriginLinesList('', $selectedLines);
3075
3076 print '</table>';
3077 print '</div>';
3078 }
3079
3080 print "</form>\n";
3081} else {
3082 if ($id > 0 || !empty($ref)) {
3083 //
3084 // View or edit mode
3085 //
3086 $now = dol_now();
3087
3088 $result = $object->fetch($id, $ref);
3089 if ($result <= 0) {
3090 recordNotFound('', 0);
3091 }
3092
3093 $result = $object->fetch_thirdparty();
3094 if ($result < 0) {
3095 dol_print_error($db, $object->error, $object->errors);
3096 exit;
3097 }
3098
3099 $societe = $object->thirdparty;
3100
3101 $totalpaid = $object->getSommePaiement();
3102 $totalcreditnotes = $object->getSumCreditNotesUsed();
3103 $totaldeposits = $object->getSumDepositsUsed();
3104 // print "totalpaid=".$totalpaid." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits."
3105 // selleruserrevenuestamp=".$selleruserevenustamp;
3106
3107 // We can also use bcadd to avoid pb with floating points
3108 // For example print 239.2 - 229.3 - 9.9; does not return 0.
3109 // $resteapayer=bcadd($object->total_ttc,$totalpaid,$conf->global->MAIN_MAX_DECIMALS_TOT);
3110 // $resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT);
3111 $resteapayer = price2num($object->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits, 'MT');
3112
3113 // Multicurrency
3114 $multicurrency_resteapayer = 0;
3115 if (isModEnabled("multicurrency")) {
3116 $multicurrency_totalpaid = $object->getSommePaiement(1);
3117 $multicurrency_totalcreditnotes = $object->getSumCreditNotesUsed(1);
3118 $multicurrency_totaldeposits = $object->getSumDepositsUsed(1);
3119 $multicurrency_resteapayer = price2num($object->multicurrency_total_ttc - $multicurrency_totalpaid - $multicurrency_totalcreditnotes - $multicurrency_totaldeposits, 'MT');
3120 // Code to fix case of corrupted data
3121 // TODO We should not need this. Also data comes from not reliable value of $object->multicurrency_total_ttc that may be wrong if it was
3122 // calculated by summing lines that were in a currency for some of them and into another for others (lines from discount/down payment into another currency for example)
3123 if ($resteapayer == 0 && $multicurrency_resteapayer != 0 && $object->multicurrency_code != $conf->currency) {
3124 $resteapayer = price2num((float) $multicurrency_resteapayer / $object->multicurrency_tx, 'MT');
3125 }
3126 }
3127
3128 if ($object->paid) {
3129 $resteapayer = 0;
3130 }
3131 $resteapayeraffiche = $resteapayer;
3132
3133 if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) { // Never use this
3134 $filterabsolutediscount = "fk_invoice_supplier_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
3135 $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
3136 } else {
3137 $filterabsolutediscount = "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')";
3138 $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')";
3139 }
3140
3141 $absolute_discount = $societe->getAvailableDiscounts(null, $filterabsolutediscount, 0, 1);
3142 $absolute_creditnote = $societe->getAvailableDiscounts(null, $filtercreditnote, 0, 1);
3143 $absolute_discount = price2num($absolute_discount, 'MT');
3144 $absolute_creditnote = price2num($absolute_creditnote, 'MT');
3145
3146 // View card
3147
3148 $objectidnext = $object->getIdReplacingInvoice();
3149
3150 $head = facturefourn_prepare_head($object);
3151 $titre = $langs->trans('SupplierInvoice');
3152
3153 print dol_get_fiche_head($head, 'card', $titre, -1, 'supplier_invoice', 0, '', '', 0, '', 1);
3154
3155 $formconfirm = '';
3156
3157 // Confirmation de la conversion de l'avoir en reduc
3158 if ($action == 'converttoreduc') {
3159 $type_fac = '';
3161 $type_fac = 'ExcessPaid';
3162 } elseif ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
3163 $type_fac = 'CreditNote';
3164 } elseif ($object->type == FactureFournisseur::TYPE_DEPOSIT) {
3165 $type_fac = 'Deposit';
3166 }
3167 $text = $langs->trans('ConfirmConvertToReducSupplier', strtolower($langs->transnoentities($type_fac)));
3168 $text .= '<br>'.$langs->trans('ConfirmConvertToReducSupplier2');
3169 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id, $langs->trans('ConvertToReduc'), $text, 'confirm_converttoreduc', '', "yes", 2);
3170 }
3171
3172 // Clone confirmation
3173 if ($action == 'clone') {
3174 // Create an array for form
3175 $formquestion = array(
3176 array('type' => 'text', 'name' => 'newsupplierref', 'label' => $langs->trans("RefSupplierBill"), 'value' => $langs->trans("CopyOf").' '.$object->ref_supplier),
3177 array('type' => 'date', 'name' => 'newdate', 'label' => $langs->trans("Date"), 'value' => dol_now())
3178 );
3179 // Ask confirmation to clone
3180 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneInvoice', $object->ref), 'confirm_clone', $formquestion, 'yes', 1, 0);
3181 }
3182
3183 // Confirmation of validation
3184 if ($action == 'valid') {
3185 // We check if number is temporary number
3186 if (preg_match('/^[\‍(]?PROV/i', $object->ref) || empty($object->ref)) {
3187 // empty should not happened, but when it occurs, the test save life
3188 $numref = $object->getNextNumRef($societe);
3189 } else {
3190 $numref = (string) $object->ref;
3191 }
3192
3193 if ($numref < 0) {
3194 setEventMessages($object->error, $object->errors, 'errors');
3195 $action = '';
3196 } else {
3197 $text = $langs->trans('ConfirmValidateBill', $numref);
3198 /*if (isModEnabled('notification'))
3199 {
3200 require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php';
3201 $notify=new Notify($db);
3202 $text.='<br>';
3203 $text.=$notify->confirmMessage('BILL_SUPPLIER_VALIDATE',$object->socid, $object);
3204 }*/
3205 $formquestion = array();
3206
3207 $qualified_for_stock_change = 0;
3208 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
3209 $qualified_for_stock_change = $object->hasProductsOrServices(2);
3210 } else {
3211 $qualified_for_stock_change = $object->hasProductsOrServices(1);
3212 }
3213
3214 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') && $qualified_for_stock_change) {
3215 $langs->load("stocks");
3216 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
3217 $formproduct = new FormProduct($db);
3218 $warehouse = new Entrepot($db);
3219 $warehouse_array = $warehouse->list_array();
3220 if (count($warehouse_array) == 1) {
3221 $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("WarehouseForStockDecrease", current($warehouse_array)) : $langs->trans("WarehouseForStockIncrease", current($warehouse_array));
3222 $value = '<input type="hidden" id="idwarehouse" name="idwarehouse" value="'.key($warehouse_array).'">';
3223 } else {
3224 $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("SelectWarehouseForStockDecrease") : $langs->trans("SelectWarehouseForStockIncrease");
3225 $value = $formproduct->selectWarehouses(GETPOST('idwarehouse') ? GETPOST('idwarehouse') : 'ifone', 'idwarehouse', '', 1);
3226 }
3227 $formquestion = array(
3228 array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $value)
3229 );
3230 }
3231
3232 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateBill'), $text, 'confirm_valid', $formquestion, 1, 1);
3233 }
3234 }
3235
3236 // Confirmation edit (back to draft)
3237 if ($action == 'edit') {
3238 $formquestion = array();
3239
3240 $qualified_for_stock_change = 0;
3241 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
3242 $qualified_for_stock_change = $object->hasProductsOrServices(2);
3243 } else {
3244 $qualified_for_stock_change = $object->hasProductsOrServices(1);
3245 }
3246 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') && $qualified_for_stock_change) {
3247 $langs->load("stocks");
3248 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
3249 $formproduct = new FormProduct($db);
3250 $warehouse = new Entrepot($db);
3251 $warehouse_array = $warehouse->list_array();
3252 if (count($warehouse_array) == 1) {
3253 $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("WarehouseForStockIncrease", current($warehouse_array)) : $langs->trans("WarehouseForStockDecrease", current($warehouse_array));
3254 $value = '<input type="hidden" id="idwarehouse" name="idwarehouse" value="'.key($warehouse_array).'">';
3255 } else {
3256 $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("SelectWarehouseForStockIncrease") : $langs->trans("SelectWarehouseForStockDecrease");
3257 $value = $formproduct->selectWarehouses(GETPOST('idwarehouse') ? GETPOST('idwarehouse') : 'ifone', 'idwarehouse', '', 1);
3258 }
3259 $formquestion = array(
3260 array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $value)
3261 );
3262 }
3263 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('UnvalidateBill'), $langs->trans('ConfirmUnvalidateBill', $object->ref), 'confirm_edit', $formquestion, 1, 1);
3264 }
3265
3266 // Confirmation set paid
3267 if ($action == 'paid' && ($resteapayer <= 0 || (getDolGlobalString('SUPPLIER_INVOICE_CAN_SET_PAID_EVEN_IF_PARTIALLY_PAID') && $resteapayer == $object->total_ttc))) {
3268 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidBill', $object->ref), 'confirm_paid', '', 0, 1);
3269 }
3270
3271 if ($action == 'paid' && $resteapayer > 0 && (!getDolGlobalString('SUPPLIER_INVOICE_CAN_SET_PAID_EVEN_IF_PARTIALLY_PAID') || $resteapayer != $object->total_ttc)) {
3272 $close = array();
3273 // Code
3274 $i = 0;
3275 $close[$i]['code'] = 'discount_vat'; // escompte
3276 $i++;
3277 $close[$i]['code'] = 'badsupplier';
3278 $i++;
3279 $close[$i]['code'] = 'other';
3280 $i++;
3281 // Help
3282 $i = 0;
3283 $close[$i]['label'] = $langs->trans("HelpEscompte").'<br><br>'.$langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");
3284 $i++;
3285 $close[$i]['label'] = $langs->trans("ConfirmClassifyPaidPartiallyReasonBadSupplierDesc");
3286 $i++;
3287 $close[$i]['label'] = $langs->trans("Other");
3288 $i++;
3289 // Text
3290 $i = 0;
3291 $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscount", $resteapayer, $langs->trans("Currency".$conf->currency)), $close[$i]['label'], 1);
3292 $i++;
3293 $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer", $resteapayer, $langs->trans("Currency".$conf->currency)), $close[$i]['label'], 1);
3294 $i++;
3295 $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("Other"), $close[$i]['label'], 1);
3296 $i++;
3297 // arrayreasons[code]=reason
3298 $arrayreasons = array();
3299 foreach ($close as $key => $val) {
3300 $arrayreasons[$close[$key]['code']] = $close[$key]['reason'];
3301 }
3302
3303 // Create a form table
3304 $formquestion = array('text' => $langs->trans("ConfirmClassifyPaidPartiallyQuestion"), 0 => array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), 1 => array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'morecss' => 'minwidth300'));
3305 // Incomplete payment. We ask if the reason is discount or other
3306 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidPartially', $object->ref), 'confirm_paid_partially', $formquestion, "yes", 1, 310);
3307 }
3308
3309 // Confirmation of the abandoned classification
3310 if ($action == 'canceled') {
3311 // Code
3312 $close[1]['code'] = 'badsupplier';
3313 $close[2]['code'] = 'abandon';
3314 // Help
3315 $close[1]['label'] = $langs->trans("ConfirmClassifyPaidPartiallyReasonBadSupplierDesc");
3316 $close[2]['label'] = $langs->trans("ConfirmClassifyAbandonReasonOtherDesc");
3317 // Text
3318 $close[1]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadSupplier", $object->ref), $close[1]['label'], 1);
3319 $close[2]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"), $close[2]['label'], 1);
3320 // arrayreasons
3321 $arrayreasons[$close[1]['code']] = $close[1]['reason'];
3322 $arrayreasons[$close[2]['code']] = $close[2]['reason'];
3323
3324 // Create a form table
3325 $formquestion = array('text' => $langs->trans("ConfirmCancelBillQuestion"), 0 => array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), 1 => array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'morecss' => 'minwidth300'));
3326
3327 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('CancelBill'), $langs->trans('ConfirmCancelBill', $object->ref), 'confirm_canceled', $formquestion, "yes", 1, 280);
3328 }
3329
3330 // Confirmation for supplier invoice deletion
3331 if ($action == 'delete') {
3332 $formquestion = array();
3333
3334 $qualified_for_stock_change = 0;
3335 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
3336 $qualified_for_stock_change = $object->hasProductsOrServices(2);
3337 } else {
3338 $qualified_for_stock_change = $object->hasProductsOrServices(1);
3339 }
3340
3341 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') && $qualified_for_stock_change) {
3342 $langs->load("stocks");
3343 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
3344 $formproduct = new FormProduct($db);
3345 $warehouse = new Entrepot($db);
3346 $warehouse_array = $warehouse->list_array();
3347
3348 $selectwarehouse = '<span class="questionrevertstock hidden">';
3349 if (count($warehouse_array) == 1) {
3350 $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("WarehouseForStockIncrease", current($warehouse_array)) : $langs->trans("WarehouseForStockDecrease", current($warehouse_array));
3351 $selectwarehouse .= '<input type="hidden" id="idwarehouse" name="idwarehouse" value="'.key($warehouse_array).'">';
3352 } else {
3353 $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("SelectWarehouseForStockIncrease") : $langs->trans("SelectWarehouseForStockDecrease");
3354 $selectwarehouse .= $formproduct->selectWarehouses(GETPOST('idwarehouse') ? GETPOST('idwarehouse') : 'ifone', 'idwarehouse', '', 1);
3355 }
3356 $selectwarehouse .= '</span>';
3357
3358 $selectyesno = array(0 => $langs->trans('No'), 1 => $langs->trans('Yes'));
3359
3360 print '<script type="text/javascript">
3361 $(document).ready(function() {
3362 $("#revertstock").change(function() {
3363 if(this.value > 0) {
3364 $(".questionrevertstock").removeClass("hidden");
3365 } else {
3366 $(".questionrevertstock").addClass("hidden");
3367 }
3368 });
3369 });
3370 </script>';
3371
3372 $formquestion = array(
3373 array('type' => 'select', 'name' => 'revertstock', 'label' => $langs->trans("RevertProductsToStock"), 'select_show_empty' => 0, 'values' => $selectyesno),
3374 array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $selectwarehouse, 'tdclass' => 'questionrevertstock hidden')
3375 );
3376 }
3377
3378 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteBill'), $langs->trans('ConfirmDeleteBill'), 'confirm_delete', $formquestion, 1, 1);
3379 }
3380 if ($action == 'deletepayment') {
3381 $payment_id = GETPOST('paiement_id');
3382 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&paiement_id='.$payment_id, $langs->trans('DeletePayment'), $langs->trans('ConfirmDeletePayment'), 'confirm_delete_paiement', '', 0, 1);
3383 }
3384
3385 // Confirmation to delete line
3386 if ($action == 'ask_deleteline') {
3387 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1);
3388 }
3389
3390 // Subtotal line form
3391 if ($action == 'add_title_line') {
3392 $langs->load('subtotals');
3393 $type = 'title';
3394 $depth_array = $object->getPossibleLevels($langs);
3395 require DOL_DOCUMENT_ROOT . '/core/tpl/subtotal_create.tpl.php';
3396 } elseif ($action == 'add_subtotal_line') {
3397 $langs->load('subtotals');
3398 $type = 'subtotal';
3399 $titles = $object->getPossibleTitles();
3400 require DOL_DOCUMENT_ROOT . '/core/tpl/subtotal_create.tpl.php';
3401 }
3402
3403 // Call Hook formConfirm
3404 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
3405 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
3406 if (empty($reshook)) {
3407 $formconfirm .= $hookmanager->resPrint;
3408 } elseif ($reshook > 0) {
3409 $formconfirm = $hookmanager->resPrint;
3410 }
3411
3412 // Print form confirm
3413 print $formconfirm;
3414
3415
3416 // Supplier invoice card
3417 $linkback = '<a href="'.DOL_URL_ROOT.'/fourn/facture/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
3418
3419 $morehtmlref = '<div class="refidno">';
3420 // Ref supplier
3421 $morehtmlref .= $form->editfieldkey("RefSupplierBill", 'ref_supplier', $object->ref_supplier, $object, (int) $usercancreate, 'string', '', 0, 1);
3422 $morehtmlref .= $form->editfieldval("RefSupplierBill", 'ref_supplier', $object->ref_supplier, $object, $usercancreate, 'string', '', null, null, '', 1);
3423 // Thirdparty
3424 $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1, 'supplier');
3425 if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
3426 $morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/fourn/facture/list.php?socid='.((int) $object->thirdparty->id).'">'.$langs->trans("OtherBills").'</a>)</div>';
3427 }
3428 // Project
3429 if (isModEnabled('project')) {
3430 $langs->load("projects");
3431 $morehtmlref .= '<br>';
3432 if ($permissiontoadd) {
3433 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
3434 if ($action != 'classify') {
3435 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.((int) $object->id).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
3436 }
3437 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, (!getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') ? $object->socid : -1), (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
3438 } else {
3439 if (!empty($object->fk_project)) {
3440 $proj = new Project($db);
3441 $proj->fetch($object->fk_project);
3442 $morehtmlref .= $proj->getNomUrl(1);
3443 if ($proj->title) {
3444 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
3445 }
3446 }
3447 }
3448 }
3449 $morehtmlref .= '</div>';
3450
3451 $object->totalpaid = $totalpaid; // To give a chance to dol_banner_tab to use already paid amount to show correct status
3452
3453 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
3454
3455 // Call Hook tabContentViewSupplierInvoice
3456 $parameters = array();
3457 // Note that $action and $object may be modified by hook
3458 $reshook = $hookmanager->executeHooks('tabContentViewSupplierInvoice', $parameters, $object, $action);
3459 if (empty($reshook)) {
3460 print '<div class="fichecenter">';
3461 print '<div class="fichehalfleft">';
3462 print '<div class="underbanner clearboth"></div>';
3463
3464 print '<table class="border tableforfield centpercent">';
3465
3466 // Type
3467 print '<tr><td>'.$langs->trans('Type').'</td><td>';
3468 print '<span class="badgeneutral">';
3469 print $object->getLibType();
3470 print '</span>';
3471 if ($object->subtype > 0) {
3472 print ' '.$object->getSubtypeLabel('facture_fourn');
3473 }
3475 $facreplaced = new FactureFournisseur($db);
3476 $facreplaced->fetch($object->fk_facture_source);
3477 print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("ReplaceInvoice", $facreplaced->getNomUrl(1)).'</span>';
3478 }
3480 if ($object->fk_facture_source > 0) {
3481 $facusing = new FactureFournisseur($db);
3482 $facusing->fetch($object->fk_facture_source);
3483 print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("CorrectInvoice", $facusing->getNomUrl(1)).'</span>';
3484 } else {
3485 $langs->load("errors");
3486 print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("WarningCorrectedInvoiceNotFound").'</span>';
3487 }
3488 }
3489
3490 // Retrieve credit note ids
3491 $object->getListIdAvoirFromInvoice();
3492
3493 if (!empty($object->creditnote_ids)) {
3494 $invoicecredits = array();
3495 foreach ($object->creditnote_ids as $invoiceid) {
3496 $creditnote = new FactureFournisseur($db);
3497 $creditnote->fetch($invoiceid);
3498 $invoicecredits[] = $creditnote->getNomUrl(1);
3499 }
3500 print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("InvoiceHasAvoir") . (count($invoicecredits) ? ' ' : '') . implode(',', $invoicecredits);
3501 print '</span>';
3502 }
3503 if (isset($objectidnext) && $objectidnext > 0) {
3504 $facthatreplace = new FactureFournisseur($db);
3505
3506 $facthatreplace->fetch($objectidnext);
3507 print ' <span class="opacitymediumbycolor paddingleft">'.str_replace('{s1}', $facthatreplace->getNomUrl(1), $langs->transnoentities("ReplacedByInvoice", '{s1}')).'</span>';
3508 }
3510 $discount = new DiscountAbsolute($db);
3511 $result = $discount->fetch(0, 0, $object->id);
3512 if ($result > 0) {
3513 print ' <span class="opacitymediumbycolor paddingleft">';
3514 $s = $langs->trans("CreditNoteConvertedIntoDiscount", '{s1}', '{s2}');
3515 $s = str_replace('{s1}', $object->getLibType(1), $s);
3516 $s = str_replace('{s2}', $discount->getNomUrl(1, 'discount'), $s);
3517 print $s;
3518 print '</span><br>';
3519 }
3520 }
3521
3522 if ($object->fk_fac_rec_source > 0) {
3523 $tmptemplate = new FactureFournisseurRec($db);
3524 $result = $tmptemplate->fetch($object->fk_fac_rec_source);
3525 if ($result > 0) {
3526 print ' <span class="opacitymediumbycolor paddingleft">';
3527 $link = '<a href="'.DOL_URL_ROOT.'/fourn/facture/card-rec.php?facid='.$tmptemplate->id.'">'.dol_escape_htmltag($tmptemplate->title).'</a>';
3528 $s = $langs->transnoentities("GeneratedFromSupplierTemplate", $link);
3529
3530 print $s;
3531 print '</span>';
3532 }
3533 }
3534 print '</td></tr>';
3535
3536
3537 // Relative and absolute discounts
3538 print '<!-- Discounts -->'."\n";
3539 print '<tr><td>'.$langs->trans('DiscountStillRemaining');
3540 print '</td><td>';
3541
3542 $thirdparty = $societe;
3543 $discount_type = 1;
3544 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
3545
3546 print '</td></tr>';
3547
3548 // Label
3549 print '<tr>';
3550 print '<td>'.$form->editfieldkey("Label", 'label', $object->label, $object, (int) $usercancreate).'</td>';
3551 print '<td>'.$form->editfieldval("Label", 'label', $object->label, $object, $usercancreate).'</td>';
3552 print '</tr>';
3553
3554 //$form_permission = ($object->status < FactureFournisseur::STATUS_CLOSED) && $usercancreate && ($object->getSommePaiement() <= 0);
3555 $form_permission = ($object->status < FactureFournisseur::STATUS_CLOSED) && $usercancreate;
3556
3557 // Date
3558 print '<tr><td>';
3559 print $form->editfieldkey("DateInvoice", 'datef', (string) $object->date, $object, (int) $form_permission, 'datepicker');
3560 print '</td><td colspan="3">';
3561 print $form->editfieldval("Date", 'datef', $object->date, $object, $form_permission, 'datepicker');
3562 print '</td>';
3563
3564 if (getDolGlobalString('INVOICE_POINTOFTAX_DATE')) {
3565 $pointoftax_form_permission = ($object->status == FactureFournisseur::STATUS_DRAFT) && $usercancreate;
3566 print '<tr><td>';
3567 print $form->editfieldkey("DatePointOfTax", 'date_pointoftax', (string) $object->date_pointoftax, $object, (int) $pointoftax_form_permission, 'datepicker');
3568 print '</td><td colspan="3">';
3569 print $form->editfieldval("DatePointOfTax", 'date_pointoftax', $object->date_pointoftax, $object, $pointoftax_form_permission, 'datepicker');
3570 print '</td></tr>';
3571 }
3572
3573 // Default terms of the settlement
3574 $langs->load('bills');
3575 print '<tr><td class="nowrap">';
3576 print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
3577 print $langs->trans('PaymentConditions');
3578 print '<td>';
3579 if ($action != 'editconditions' && $form_permission) {
3580 print '<td class="right"><a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editconditions&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetConditions'), 1).'</a></td>';
3581 }
3582 print '</tr></table>';
3583 print '</td><td>';
3584 if ($action == 'editconditions') {
3585 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->cond_reglement_id, 'cond_reglement_id');
3586 } else {
3587 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->cond_reglement_id, 'none');
3588 }
3589 print "</td>";
3590 print '</tr>';
3591
3592 // Due date
3593 print '<tr><td>';
3594 print $form->editfieldkey("DateMaxPayment", 'date_lim_reglement', (string) $object->date_echeance, $object, (int) $form_permission, 'datepicker');
3595 print '</td><td>';
3596 print $form->editfieldval("DateMaxPayment", 'date_lim_reglement', $object->date_echeance, $object, $form_permission, 'datepicker');
3597 if ($action != 'editdate_lim_reglement' && $object->hasDelay()) {
3598 print img_warning($langs->trans('Late'));
3599 }
3600 print '</td>';
3601
3602 // Mode of payment
3603 $langs->load('bills');
3604 print '<tr><td class="nowrap">';
3605 print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
3606 print $langs->trans('PaymentMode');
3607 print '</td>';
3608 if ($action != 'editmode' && $form_permission) {
3609 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editmode&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetMode'), 1).'</a></td>';
3610 }
3611 print '</tr></table>';
3612 print '</td><td>';
3613 if ($action == 'editmode') {
3614 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->mode_reglement_id, 'mode_reglement_id', 'DBIT', 1, 1);
3615 } else {
3616 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->mode_reglement_id, 'none');
3617 }
3618 print '</td></tr>';
3619
3620 // Bank Account
3621 if (isModEnabled("bank")) {
3622 print '<tr><td class="nowrap">';
3623 print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
3624 print $langs->trans('BankAccount');
3625 print '<td>';
3626 if ($action != 'editbankaccount' && $usercancreate) {
3627 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>';
3628 }
3629 print '</tr></table>';
3630 print '</td><td>';
3631 if ($action == 'editbankaccount') {
3632 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'fk_account', 1);
3633 } else {
3634 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'none');
3635 }
3636 print "</td>";
3637 print '</tr>';
3638 }
3639
3640 // Vat reverse-charge by default
3641 if (getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
3642 print '<tr><td class="nowrap">';
3643 print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
3644 print $langs->trans('VATReverseCharge');
3645 print '<td>';
3646 if ($action != 'editvatreversecharge' && $usercancreate) {
3647 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editvatreversecharge&amp;token='.newToken().'&amp;id='.$object->id.'">'.img_edit($langs->trans('SetVATReverseCharge'), 1).'</a></td>';
3648 }
3649 print '</tr></table>';
3650 print '</td><td>';
3651 if ($action == 'editvatreversecharge') {
3652 print '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
3653 print '<input type="hidden" name="action" value="setvatreversecharge">';
3654 print '<input type="hidden" name="token" value="'.newToken().'">';
3655
3656 print '<input type="checkbox" name="vat_reverse_charge"' . ($object->vat_reverse_charge == '1' ? ' checked ' : '') . '>';
3657
3658 print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
3659 print '</form>';
3660 } else {
3661 print '<input type="checkbox" name="vat_reverse_charge"'. ($object->vat_reverse_charge == '1' ? ' checked ' : '') . ' disabled>';
3662 }
3663 print '</td></tr>';
3664 }
3665
3666 // Incoterms
3667 if (isModEnabled('incoterm')) {
3668 print '<tr><td>';
3669 print '<table width="100%" class="nobordernopadding"><tr><td>';
3670 print $langs->trans('IncotermLabel');
3671 print '<td><td class="right">';
3672 if ($usercancreate) {
3673 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/fourn/facture/card.php?facid='.$object->id.'&action=editincoterm&token='.newToken().'">'.img_edit().'</a>';
3674 } else {
3675 print '&nbsp;';
3676 }
3677 print '</td></tr></table>';
3678 print '</td>';
3679 print '<td>';
3680 if ($action != 'editincoterm') {
3681 print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1);
3682 } else {
3683 print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id);
3684 }
3685 print '</td></tr>';
3686 }
3687
3688 // Intracomm report
3689 if (isModEnabled('intracommreport')) {
3690 $langs->loadLangs(array("intracommreport"));
3691 print '<!-- If module intracomm on -->'."\n";
3692 print '<tr><td>';
3693 print '<table class="nobordernopadding centpercent"><tr><td>';
3694 print $langs->trans('IntracommReportTransportMode');
3695 print '</td>';
3696 if ($action != 'edittransportmode' && ($user->hasRight("fournisseur", "facture", "creer") || $user->hasRight("supplier_invoice", "creer"))) {
3697 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=edittransportmode&token='.newToken().'&id='.$object->id.'">'.img_edit().'</a></td>';
3698 }
3699 print '</tr></table>';
3700 print '</td>';
3701 print '<td>';
3702 if ($action == 'edittransportmode') {
3703 $form->formSelectTransportMode($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->transport_mode_id, 'transport_mode_id', 1, 1);
3704 } else {
3705 $form->formSelectTransportMode($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->transport_mode_id, 'none');
3706 }
3707 print '</td></tr>';
3708 }
3709
3710 // Categories
3711 if (isModEnabled('category')) {
3712 print '<tr><td>';
3713 print '<table class="nobordernopadding centpercent"><tr><td>';
3714 print $langs->trans("Categories");
3715 print '<td><td class="right">';
3716 if ($usercancreate) {
3717 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/fourn/facture/card.php?facid='.$object->id.'&action=edittags&token='.newToken().'">'.img_edit().'</a>';
3718 } else {
3719 print '&nbsp;';
3720 }
3721 print '</td></tr></table>';
3722 print '</td>';
3723 print '<td>';
3724 if ($action == 'edittags') {
3725 print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'">';
3726 print '<input type="hidden" name="action" value="settags">';
3727 print '<input type="hidden" name="token" value="'.newToken().'">';
3728 print $form->selectCategories(Categorie::TYPE_SUPPLIER_INVOICE, 'categories', $object);
3729 print '<input type="submit" class="button valignmiddle smallpaddingimp" value="'.$langs->trans("Modify").'">';
3730 print '</form>';
3731 } else {
3732 print $form->showCategories($object->id, Categorie::TYPE_SUPPLIER_INVOICE, 1);
3733 }
3734 print "</td></tr>";
3735 }
3736
3737
3738 // Other attributes. Fields from hook formObjectOptions and Extrafields.
3739 $cols = 2;
3740 if ($object->status != $object::STATUS_DRAFT) {
3741 $disableedit = 1;
3742 $disableremove = 1;
3743 }
3744 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
3745
3746 print '</table>';
3747 print '</div>';
3748
3749 print '<div class="fichehalfright">';
3750 print '<div class="underbanner clearboth"></div>';
3751
3752 print '<table class="border tableforfield centpercent">';
3753
3754 include DOL_DOCUMENT_ROOT.'/core/tpl/object_currency_amount.tpl.php';
3755
3756 print '<tr>';
3757 print '<td class="titlefieldmiddle">' . $langs->trans('AmountHT') . '</td>';
3758 print '<td class="nowrap amountcard right">' . price($object->total_ht, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
3759 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
3760 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ht, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
3761 }
3762 print '</tr>';
3763
3764 print '<tr>';
3765 print '<td>' . $langs->trans('AmountVAT') . '</td>';
3766 print '<td class="nowrap amountcard right">';
3767 if (GETPOST('calculationrule')) {
3768 $calculationrule = GETPOST('calculationrule', 'alpha');
3769 } else {
3770 $calculationrule = (!getDolGlobalString('MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND_SUPPLIER') ? 'totalofround' : 'roundoftotal');
3771 }
3772 if ($calculationrule == 'totalofround') {
3773 $calculationrulenum = 1;
3774 } else {
3775 $calculationrulenum = 2;
3776 }
3777 // Show link for "recalculate"
3778 if ($object->getVentilExportCompta() == 0) {
3779 $s = '<span class="hideonsmartphone opacitymedium">' . $langs->trans("ReCalculate") . ' </span>';
3780 $s .= '<a href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=calculate&token='.newToken().'&calculationrule=totalofround">' . $langs->trans("Mode1") . '</a>';
3781 $s .= ' / ';
3782 $s .= '<a href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=calculate&token='.newToken().'&calculationrule=roundoftotal">' . ($conf->dol_optimize_smallscreen ? "2" : $langs->trans("Mode2")) . '</a>';
3783 print '<div class="inline-block">';
3784 print $form->textwithtooltip($s, $langs->trans("CalculationRuleDesc", $calculationrulenum) . '<br>' . $langs->trans("CalculationRuleDescSupplier"), 2, 1, img_picto('', 'help', 'class="paddingleft paddingright"'), '', 3, '', 0, 'recalculate');
3785 print '&nbsp; &nbsp; &nbsp; &nbsp;';
3786 print '</div>';
3787 }
3788 print '<span class="nowraponall">'.price($object->total_tva, 1, $langs, 0, -1, -1, $conf->currency).'</span>';
3789 print '</td>';
3790 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
3791 print '<td class="nowraponall amountcard right">' . price($object->multicurrency_total_tva, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
3792 }
3793 print '</tr>';
3794
3795 if ($societe->localtax1_assuj == "1") { //Localtax1
3796 print '<tr>';
3797 print '<td>' . $langs->transcountry("AmountLT1", $societe->country_code) . '</td>';
3798 print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 1, $langs, 0, -1, -1, $conf->currency) . '</td>';
3799 print '</tr>';
3800 }
3801 if ($societe->localtax2_assuj == "1") { //Localtax2
3802 print '<tr>';
3803 print '<td>' . $langs->transcountry("AmountLT2", $societe->country_code) . '</td>';
3804 print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 1, $langs, 0, -1, -1, $conf->currency) . '</td>';
3805 print '</tr>';
3806 }
3807
3808 print '<tr>';
3809 print '<td>' . $langs->trans('AmountTTC') . '</td>';
3810 print '<td class="nowrap amountcard right">' . price($object->total_ttc, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
3811 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
3812 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ttc, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
3813 }
3814 print '</tr>';
3815
3816 print '</table>';
3817
3818
3819 // List of payments already done
3820
3821 $totalpaid = 0;
3822
3823 $sign = 1;
3825 $sign = - 1;
3826 }
3827
3828 $nbrows = 9;
3829 $nbcols = 3;
3830 if (isModEnabled('project')) {
3831 $nbrows++;
3832 }
3833 if (isModEnabled("bank")) {
3834 $nbrows++;
3835 $nbcols++;
3836 }
3837 if (isModEnabled('incoterm')) {
3838 $nbrows++;
3839 }
3840 if (isModEnabled("multicurrency")) {
3841 $nbrows += 5;
3842 }
3843
3844 // Local taxes
3845 if ($societe->localtax1_assuj == "1") {
3846 $nbrows++;
3847 }
3848 if ($societe->localtax2_assuj == "1") {
3849 $nbrows++;
3850 }
3851
3852 $sql = 'SELECT p.datep as dp, p.ref, p.num_paiement as num_payment, p.rowid, p.fk_bank,';
3853 $sql .= ' c.id as payment_type, c.code as payment_code,';
3854 $sql .= ' pf.amount,';
3855 $sql .= ' ba.rowid as baid, ba.ref as baref, ba.label, ba.number as banumber, ba.account_number, ba.fk_accountancy_journal';
3856 $sql .= ' FROM '.MAIN_DB_PREFIX.'paiementfourn as p';
3857 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid';
3858 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid';
3859 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id';
3860 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf ON pf.fk_paiementfourn = p.rowid';
3861 $sql .= ' WHERE pf.fk_facturefourn = '.((int) $object->id);
3862 $sql .= ' ORDER BY p.datep, p.tms';
3863
3864 $result = $db->query($sql);
3865 if ($result) {
3866 $num = $db->num_rows($result);
3867 $i = 0;
3868
3869 print '<div class="div-table-responsive-no-min">';
3870 print '<table class="noborder paymenttable centpercent">';
3871 print '<tr class="liste_titre">';
3872 print '<td class="liste_titre">'.($object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("PaymentsBack") : $langs->trans('Payments')).'</td>';
3873 print '<td><span class="hideonsmartphone">'.$langs->trans('Date').'</span></td>';
3874 print '<td><span class="hideonsmartphone">'.$langs->trans('Type').'</span></td>';
3875 if (isModEnabled("bank")) {
3876 print '<td class="right">'.$langs->trans('BankAccount').'</td>';
3877 }
3878 // Action
3879 print '<td></td>';
3880 // Amount
3881 print '<td class="right">'.$langs->trans('Amount').'</td>';
3882 print '</tr>';
3883
3884 if ($num > 0) {
3885 while ($i < $num) {
3886 $objp = $db->fetch_object($result);
3887
3888 $paymentstatic->id = $objp->rowid;
3889 $paymentstatic->datepaye = $db->jdate($objp->dp);
3890 $paymentstatic->ref = ($objp->ref ? $objp->ref : $objp->rowid);
3891 $paymentstatic->num_payment = $objp->num_payment;
3892
3893 $paymentstatic->paiementcode = $objp->payment_code;
3894 $paymentstatic->type_code = $objp->payment_code;
3895 $paymentstatic->type_label = $objp->payment_type;
3896
3897 print '<tr class="oddeven">';
3898 print '<td class="nowraponall">';
3899 print $paymentstatic->getNomUrl(1);
3900 print '</td>';
3901 print '<td>'.dol_print_date($db->jdate($objp->dp), 'day').'</td>';
3902 $s = $form->form_modes_reglement('', $objp->payment_type, 'none', '', 1, 0, '', 1).' '.$objp->num_payment;
3903 print '<td class="tdoverflowmax125" title="'.dol_escape_htmltag($s).'">';
3904 print $s;
3905 print '</td>';
3906 if (isModEnabled("bank")) {
3907 $bankaccountstatic->id = $objp->baid;
3908 $bankaccountstatic->ref = $objp->baref;
3909 $bankaccountstatic->label = $objp->baref;
3910 $bankaccountstatic->number = $objp->banumber;
3911
3912 if (isModEnabled('accounting')) {
3913 $bankaccountstatic->account_number = $objp->account_number;
3914
3915 $accountingjournal = new AccountingJournal($db);
3916 $accountingjournal->fetch($objp->fk_accountancy_journal);
3917 $bankaccountstatic->accountancy_journal = $accountingjournal->getNomUrl(0, 1, 1, '', 1);
3918 }
3919
3920 print '<td class="right nowraponall">';
3921 if ($objp->baid > 0) {
3922 print $bankaccountstatic->getNomUrl(1, 'transactions');
3923 }
3924 print '</td>';
3925 }
3926 // Delete
3927 print '<td class="center">';
3928 if ($object->status == FactureFournisseur::STATUS_VALIDATED && $object->paid == 0 && $user->socid == 0) {
3929 print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=deletepayment&token='.newToken().'&paiement_id='.$objp->rowid.'">';
3930 print img_delete();
3931 print '</a>';
3932 }
3933 print '</td>';
3934 // Amount
3935 print '<td class="right">'.price($sign * $objp->amount).'</td>';
3936 print '</tr>';
3937 $totalpaid += $objp->amount;
3938 $i++;
3939 }
3940 } else {
3941 print '<tr class="oddeven"><td colspan="'.$nbcols.'"><span class="opacitymedium">'.$langs->trans("None").'</span></td>';
3942 print '<td></td>';
3943 print '<td></td>';
3944 print '</tr>';
3945 }
3946
3947 /*
3948 if ($object->paid == 0)
3949 {
3950 print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans('AlreadyPaid').' :</td><td class="right">'.price($totalpaid).'</td><td></td></tr>';
3951 print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("Billed").' :</td><td class="right">'.price($object->total_ttc).'</td><td></td></tr>';
3952
3953 $resteapayer = $object->total_ttc - $totalpaid;
3954
3955 print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans('RemainderToPay').' :</td>';
3956 print '<td class="right'.($resteapayer?' amountremaintopay':'').'">'.price($resteapayer).'</td><td></td></tr>';
3957 }
3958 */
3959
3960 $db->free($result);
3961 } else {
3963 }
3964
3966 // Total already paid
3967 print '<tr><td colspan="'.($nbcols + 1).'" class="right">';
3968 print '<span class="opacitymedium">';
3970 print $langs->trans('AlreadyPaidNoCreditNotesNoDeposits');
3971 } else {
3972 print $langs->trans('AlreadyPaid');
3973 }
3974 print '</span>';
3975 print '</td>';
3976 //print '<td></td>';
3977 print '<td class="right"'.(($totalpaid > 0) ? ' class="amountalreadypaid"' : '').'>'.price($totalpaid).'</td>';
3978 print '</tr>';
3979
3980 //$resteapayer = $object->total_ttc - $totalpaid;
3981 $resteapayeraffiche = $resteapayer;
3982
3983 $cssforamountpaymentcomplete = 'amountpaymentcomplete';
3984
3985 // Loop on each credit note or deposit amount applied
3986 $creditnoteamount = 0;
3987 $depositamount = 0;
3988
3989 $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
3990 $sql .= " re.description, re.fk_invoice_supplier_source";
3991 $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re";
3992 $sql .= " WHERE fk_invoice_supplier = ".((int) $object->id);
3993 $resql = $db->query($sql);
3994 if ($resql) {
3995 $num = $db->num_rows($resql);
3996 $i = 0;
3997 $invoice = new FactureFournisseur($db);
3998 while ($i < $num) {
3999 $obj = $db->fetch_object($resql);
4000 $invoice->fetch($obj->fk_invoice_supplier_source);
4001 print '<tr><td colspan="'.$nbcols.'" class="right">';
4002 if ($invoice->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
4003 print $langs->trans("CreditNote").' ';
4004 }
4005 if ($invoice->type == FactureFournisseur::TYPE_DEPOSIT) {
4006 print $langs->trans("Deposit").' ';
4007 }
4008 print $invoice->getNomUrl(0);
4009 print '</td>';
4010 // Delete
4011 print '<td class="right">';
4012 print '<a href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=unlinkdiscount&token='.newToken().'&discountid='.$obj->rowid.'">';
4013 print img_picto($langs->transnoentitiesnoconv("RemoveDiscount"), 'unlink');
4014 print '</a>';
4015 print '</td>';
4016 // Amount
4017 print '<td class="right">'.price($obj->amount_ttc).'</td>';
4018 print '</tr>';
4019 $i++;
4020 if ($invoice->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
4021 $creditnoteamount += $obj->amount_ttc;
4022 }
4023 if ($invoice->type == FactureFournisseur::TYPE_DEPOSIT) {
4024 $depositamount += $obj->amount_ttc;
4025 }
4026 }
4027 } else {
4029 }
4030
4031 // Pay partially 'escompte'
4032 if (($object->status == FactureFournisseur::STATUS_CLOSED || $object->status == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'discount_vat') {
4033 print '<tr><td colspan="'.($nbcols + 1).'" class="right nowrap">';
4034 print '<span class="opacitymedium">';
4035 print $form->textwithpicto($langs->trans("Discount"), $langs->trans("HelpEscompte"), - 1);
4036 print '</span>';
4037 print '</td>';
4038 //print '<td></td>';
4039 print '<td class="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaid).'</td>';
4040 print '</tr>';
4041 $resteapayeraffiche = 0;
4042 $cssforamountpaymentcomplete = 'amountpaymentneutral';
4043 }
4044 // Paye partiellement ou Abandon 'badsupplier'
4045 if (($object->status == FactureFournisseur::STATUS_CLOSED || $object->status == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'badsupplier') {
4046 print '<tr><td colspan="'.($nbcols + 1).'" class="right nowrap">';
4047 print '<span class="opacitymedium">';
4048 print $form->textwithpicto($langs->trans("Abandoned"), $langs->trans("HelpAbandonBadCustomer"), - 1);
4049 print '</span>';
4050 print '</td>';
4051 //print '<td></td>';
4052 print '<td class="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaid).'</td>';
4053 print '</tr>';
4054 // $resteapayeraffiche=0;
4055 $cssforamountpaymentcomplete = 'amountpaymentneutral';
4056 }
4057 // Paye partiellement ou Abandon 'product_returned'
4058 if (($object->status == FactureFournisseur::STATUS_CLOSED || $object->status == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'product_returned') {
4059 print '<tr><td colspan="'.($nbcols + 1).'" class="right nowrap">';
4060 print '<span class="opacitymedium">';
4061 print $form->textwithpicto($langs->trans("ProductReturned"), $langs->trans("HelpAbandonProductReturned"), - 1);
4062 print '</span>';
4063 print '</td>';
4064 //print '<td></td>';
4065 print '<td class="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaid).'</td>';
4066 print '</tr>';
4067 $resteapayeraffiche = 0;
4068 $cssforamountpaymentcomplete = 'amountpaymentneutral';
4069 }
4070 // Paye partiellement ou Abandon 'abandon'
4071 if (($object->status == FactureFournisseur::STATUS_CLOSED || $object->status == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'abandon') {
4072 print '<tr><td colspan="'.($nbcols + 1).'" class="right nowrap">';
4073 $text = $langs->trans("HelpAbandonOther");
4074 if ($object->close_note) {
4075 $text .= '<br><br><b>'.$langs->trans("Reason").'</b>:'.$object->close_note;
4076 }
4077 print '<span class="opacitymedium">';
4078 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
4079 print $form->textwithpicto($langs->trans("Abandoned"), $text, - 1);
4080 print '</span>';
4081 print '</td>';
4082 //print '<td></td>';
4083 print '<td class="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaid).'</td>';
4084 print '</tr>';
4085 $resteapayeraffiche = 0;
4086 $cssforamountpaymentcomplete = 'amountpaymentneutral';
4087 }
4088
4089 // Billed
4090 print '<tr><td colspan="'.($nbcols + 1).'" class="right">';
4091 print '<span class="opacitymedium">';
4092 print $langs->trans("Billed");
4093 print '</span>';
4094 print '</td>';
4095 //print '<td></td>';
4096 print '<td class="right">'.price($object->total_ttc).'</td>';
4097 print '</tr>';
4098
4099 // Remainder to pay
4100 print '<tr><td colspan="'.($nbcols + 1).'" class="right">';
4101 print '<span class="opacitymedium">';
4102 print $langs->trans('RemainderToPay');
4103 if ($resteapayeraffiche < 0) {
4104 print ' ('.$langs->trans('NegativeIfExcessPaid').')';
4105 }
4106 print '</span>';
4107 print '</td>';
4108 //print '<td></td>';
4109 print '<td class="right'.($resteapayeraffiche ? ' amountremaintopay' : (' '.$cssforamountpaymentcomplete)).'">'.price($resteapayeraffiche).'</td>';
4110 print '</tr>';
4111
4112 // Remainder to pay Multicurrency
4113 if (isModEnabled('multicurrency') && (($object->multicurrency_code && $object->multicurrency_code != $conf->currency) || $object->multicurrency_tx != 1)) {
4114 print '<tr><td colspan="'.($nbcols + 1).'" class="right">';
4115 print '<span class="opacitymedium">';
4116 print $langs->trans('RemainderToPayMulticurrency');
4117 if ($resteapayeraffiche < 0) {
4118 print ' ('.$langs->trans('NegativeIfExcessPaid').')';
4119 }
4120 print '</span>';
4121 print '</td>';
4122 //print '<td></td>';
4123 print '<td class="right'.($resteapayeraffiche ? ' amountremaintopaynoresize' : (' '.$cssforamountpaymentcomplete)).'">'.price(price2num($multicurrency_resteapayer, 'MT'), 0, $langs, 1, -1, -1, $object->multicurrency_code).'</td>';
4124 print '</tr>';
4125 }
4126 } else { // Credit note
4127 $cssforamountpaymentcomplete = 'amountpaymentneutral';
4128
4129 // Total already paid back
4130 print '<tr><td colspan="'.($nbcols + 1).'" class="right">';
4131 print $langs->trans('AlreadyPaidBack');
4132 print '</td>';
4133 //print '<td></td>';
4134 print '<td class="right">'.price($sign * $totalpaid).'</td>';
4135 print '</tr>';
4136
4137 // Billed
4138 print '<tr><td colspan="'.($nbcols + 1).'" class="right">'.$langs->trans("Billed").'</td>';
4139 //print '<td></td>';
4140 print '<td class="right">'.price($sign * $object->total_ttc).'</td>';
4141 print '</tr>';
4142
4143 // Remainder to pay back
4144 print '<tr><td colspan="'.($nbcols + 1).'" class="right">';
4145 print '<span class="opacitymedium">';
4146 print $langs->trans('RemainderToPayBack');
4147 if ($resteapayeraffiche > 0) {
4148 print ' ('.$langs->trans('NegativeIfExcessRefunded').')';
4149 }
4150 print '</td>';
4151 print '</span>';
4152 //print '<td></td>';
4153 print '<td class="right'.($resteapayeraffiche ? ' amountremaintopay' : (' '.$cssforamountpaymentcomplete)).'">'.price($sign * $resteapayeraffiche).'</td>';
4154 print '</tr>';
4155
4156 // Remainder to pay back Multicurrency
4157 if (isModEnabled('multicurrency') && (($object->multicurrency_code && $object->multicurrency_code != $conf->currency) || $object->multicurrency_tx != 1)) {
4158 print '<tr><td colspan="'.($nbcols + 1).'" class="right">';
4159 print '<span class="opacitymedium">';
4160 print $langs->trans('RemainderToPayBackMulticurrency');
4161 if ($resteapayeraffiche > 0) {
4162 print ' ('.$langs->trans('NegativeIfExcessRefunded').')';
4163 }
4164 print '</span>';
4165 print '</td>';
4166 //print '<td></td>';
4167 print '<td class="right'.($resteapayeraffiche ? ' amountremaintopaynoresize' : (' '.$cssforamountpaymentcomplete)).'">'.(!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency).' '.price(price2num($sign * $object->multicurrency_tx * $resteapayeraffiche, 'MT')).'</td>';
4168 print '</tr>';
4169 }
4170
4171 // Sold credit note
4172 // print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans('TotalTTC').' :</td>';
4173 // print '<td class="right" style="border: 1px solid;" bgcolor="#f0f0f0"><b>'.price($sign *
4174 // $object->total_ttc).'</b></td><td>&nbsp;</td></tr>';
4175 }
4176
4177 print '</table>';
4178 print '</div>';
4179
4180 print '</div>';
4181 print '</div>';
4182
4183 print '<div class="clearboth"></div><br>';
4184
4185 if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
4186 $blocname = 'contacts';
4187 $title = $langs->trans('ContactsAddresses');
4188 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
4189 }
4190
4191 if (getDolGlobalString('MAIN_DISABLE_NOTES_TAB')) {
4192 $colwidth = 20;
4193 $blocname = 'notes';
4194 $title = $langs->trans('Notes');
4195 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
4196 }
4197
4198
4199 /*
4200 * Lines
4201 */
4202 print '<form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="POST">';
4203 print '<input type="hidden" name="token" value="'.newToken().'">';
4204 print '<input type="hidden" name="action" value="'.(($action != 'editline') ? 'addline' : 'updateline').'">';
4205 print '<input type="hidden" name="mode" value="">';
4206 print '<input type="hidden" name="page_y" value="">';
4207 print '<input type="hidden" name="id" value="'.$object->id.'">';
4208 print '<input type="hidden" name="socid" value="'.$societe->id.'">';
4209 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
4210
4211 if (!empty($conf->use_javascript_ajax) && $object->status == FactureFournisseur::STATUS_DRAFT) {
4212 if (isModEnabled('subtotals')) {
4213 include DOL_DOCUMENT_ROOT . '/core/tpl/subtotal_ajaxrow.tpl.php';
4214 } else {
4215 include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
4216 }
4217 }
4218
4219 print '<div class="div-table-responsive-no-min">';
4220 print '<table id="tablelines" class="noborder noshadow centpercent">';
4221
4222 global $forceall, $senderissupplier, $dateSelector, $inputalsopricewithtax;
4223 $forceall = 1;
4224 $dateSelector = 0;
4225 $inputalsopricewithtax = 1;
4226 $senderissupplier = 2; // $senderissupplier=2 is same than 1 but disable test on minimum qty and disable autofill qty with minimum.
4227 if (getDolGlobalInt('SUPPLIER_INVOICE_WITH_PREDEFINED_PRICES_ONLY')) {
4228 $senderissupplier = getDolGlobalInt('SUPPLIER_INVOICE_WITH_PREDEFINED_PRICES_ONLY');
4229 }
4230
4231 // Show object lines (result may vary according to hidden option MAIN_NO_INPUT_PRICE_WITH_TAX)
4232 if (!empty($object->lines)) {
4233 $object->printObjectLines($action, $societe, $mysoc, $lineid, 1);
4234 }
4235
4236 $num = count($object->lines);
4237
4238 // Form to add new line
4239 if ($object->status == FactureFournisseur::STATUS_DRAFT && $usercancreate) {
4240 if ($action != 'editline') {
4241 // Add free products/services
4242
4243 $parameters = array();
4244 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
4245 if ($reshook < 0) {
4246 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
4247 }
4248 if (empty($reshook)) {
4249 $object->formAddObjectLine(1, $societe, $mysoc);
4250 }
4251 }
4252 }
4253
4254 print '</table>';
4255 print '</div>';
4256 print '</form>';
4257 }
4258
4259 print dol_get_fiche_end();
4260
4261
4262 if ($action != 'presend') {
4263 // Buttons actions
4264
4265 print '<div class="tabsAction">';
4266
4267 $parameters = array();
4268 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
4269 // modified by hook
4270 if (empty($reshook)) {
4271 // Subtotal
4272 if ($object->status === FactureFournisseur::STATUS_DRAFT && isModEnabled('subtotals') && getDolGlobalString('SUBTOTAL_TITLE_'.strtoupper($object->element))) {
4273 $langs->load('subtotals');
4274
4275 $url_button = array();
4276
4277 $url_button[] = array(
4278 'lang' => 'subtotals',
4279 'enabled' => true,
4280 'perm' => (bool) $usercancreate,
4281 'label' => $langs->trans('AddTitleLine'),
4282 'url' => dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'add_title_line'], true)
4283 );
4284
4285 $url_button[] = array(
4286 'lang' => 'subtotals',
4287 'enabled' => true,
4288 'perm' => (bool) $usercancreate,
4289 'label' => $langs->trans('AddSubtotalLine'),
4290 'url' => dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'add_subtotal_line'], true)
4291 );
4292
4293 print dolGetButtonAction('', $langs->trans('SubTotal'), 'default', $url_button, '', true);
4294 }
4295 // Modify a validated invoice with no payments
4296 if ($object->status == FactureFournisseur::STATUS_VALIDATED && $action != 'confirm_edit' && $object->getSommePaiement() == 0 && $usercancreate) {
4297 // We check if lines of invoice are not already transferred into accountancy
4298 $ventilExportCompta = $object->getVentilExportCompta(); // Should be 0 since the sum of payments are zero. But we keep the protection.
4299
4300 if ($ventilExportCompta == 0) {
4301 print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=edit&token='.newToken().'">'.$langs->trans('Modify').'</a>';
4302 } else {
4303 print '<span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseDispatchedInBookkeeping").'">'.$langs->trans('Modify').'</span>';
4304 }
4305 }
4306
4307 $discount = new DiscountAbsolute($db);
4308 $result = $discount->fetch(0, 0, $object->id);
4309
4310 // Reopen a standard paid invoice
4312 || ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && empty($discount->id))
4313 || ($object->type == FactureFournisseur::TYPE_DEPOSIT && empty($discount->id)))
4314 && ($object->status == FactureFournisseur::STATUS_CLOSED || $object->status == FactureFournisseur::STATUS_ABANDONED)) { // A paid invoice (partially or completely)
4315 if (!$objectidnext && $object->close_code != 'replaced' && $usercancreate) { // Not replaced by another invoice
4316 print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans('ReOpen').'</a>';
4317 } else {
4318 if ($usercancreate) {
4319 print '<span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('ReOpen').'</span>';
4320 } elseif (!getDolGlobalString('MAIN_BUTTON_HIDE_UNAUTHORIZED')) {
4321 print '<span class="butActionRefused classfortooltip">'.$langs->trans('ReOpen').'</span>';
4322 }
4323 }
4324 }
4325
4326 // Validate
4327 if ($action != 'confirm_edit' && $object->status == FactureFournisseur::STATUS_DRAFT && count($object->lines) > 0
4328 && ((($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_REPLACEMENT || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_PROFORMA || $object->type == FactureFournisseur::TYPE_SITUATION) && (getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE') || $object->total_ttc >= 0)) // @phan-suppress-current-line PhanDeprecatedClassConstant
4329 || ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) {
4330 // if (count($object->lines)) { // already tested in condition
4331 if ($usercanvalidate) {
4332 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=valid&token='.newToken().'"';
4333 print '>'.$langs->trans('Validate').'</a>';
4334 } else {
4335 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'"';
4336 print '>'.$langs->trans('Validate').'</a>';
4337 }
4338 //}
4339 }
4340
4341 // Send by mail
4342 if (empty($user->socid)) {
4344 if ($usercansend) {
4345 print dolGetButtonAction('', $langs->trans('SendMail'), 'email', dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'presend', 'mode' => 'init'], true).'#formmailbeforetitle', '');
4346 } else {
4347 print dolGetButtonAction('', $langs->trans('SendMail'), 'email', '#', '', false);
4348 }
4349 }
4350 }
4351
4352 // Request a direct debit order
4353 if ($object->status > FactureFournisseur::STATUS_DRAFT && $object->paid == 0) {
4354 $langs->load("withdrawals");
4355 if ($resteapayer > 0) {
4356 if ($usercancreatecreditransfer) {
4357 if (!$objectidnext && $object->close_code != 'replaced') { // Not replaced by another invoice
4358 print '<a class="butAction" href="'.DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$object->id.'&type=bank-transfer" title="'.dol_escape_htmltag($langs->trans("MakeBankTransferOrder")).'">'.$langs->trans("MakeBankTransferOrder").'</a>';
4359 } else {
4360 print '<span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('MakeBankTransferOrder').'</span>';
4361 }
4362 } else {
4363 //print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$langs->trans("MakeWithdrawRequest").'</a>';
4364 }
4365 } else {
4366 //print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("AmountMustBePositive")).'">'.$langs->trans("MakeWithdrawRequest").'</a>';
4367 }
4368 }
4369
4370 // Create payment
4371 if ($object->type != FactureFournisseur::TYPE_CREDIT_NOTE && $object->status == FactureFournisseur::STATUS_VALIDATED && $object->paid == 0 && $usercancreate) {
4372 print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/paiement.php?facid='.$object->id.'&action=create'.($object->fk_account > 0 ? '&accountid='.$object->fk_account : '').'">'.$langs->trans('DoPayment').'</a>'; // must use facid because id is for payment id not invoice
4373 }
4374
4375 // Reverse back money or convert to reduction
4377 // For credit note only
4378 if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->status == 1 && $object->paid == 0) {
4379 if ($resteapayer == 0) {
4380 print '<span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseRemainderToPayIsZero").'">'.$langs->trans('DoPaymentBack').'</span>';
4381 } elseif ($usercancreate) {
4382 print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/paiement.php?facid='.$object->id.'&action=create&accountid='.$object->fk_account.'">'.$langs->trans('DoPaymentBack').'</a>';
4383 }
4384 }
4385
4386 // For standard invoice with excess paid
4387 if ($object->type == FactureFournisseur::TYPE_STANDARD && empty($object->paid) && ($object->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits) < 0 && $usercancreate && empty($discount->id)) {
4388 print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=converttoreduc&token='.newToken().'">'.$langs->trans('ConvertExcessPaidToReduc').'</a>';
4389 }
4390 // For credit note
4391 if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->status == 1 && $object->paid == 0 && $usercancreate
4392 && (getDolGlobalString('SUPPLIER_INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED') || $object->getSommePaiement() == 0)
4393 ) {
4394 print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=converttoreduc&token='.newToken().'" title="'.dol_escape_htmltag($langs->trans("ConfirmConvertToReducSupplier2")).'">'.$langs->trans('ConvertToReduc').'</a>';
4395 }
4396 // For deposit invoice
4397 if ($object->type == FactureFournisseur::TYPE_DEPOSIT && $usercancreate && $object->status > 0 && empty($discount->id)) {
4398 print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=converttoreduc&token='.newToken().'">'.$langs->trans('ConvertToReduc').'</a>';
4399 }
4400 }
4401
4402 // Classify paid
4403 if ($object->status == FactureFournisseur::STATUS_VALIDATED && $object->paid == 0 && (
4404 ($object->type != FactureFournisseur::TYPE_CREDIT_NOTE && $object->type != FactureFournisseur::TYPE_DEPOSIT && ($resteapayer <= 0 || (getDolGlobalString('SUPPLIER_INVOICE_CAN_SET_PAID_EVEN_IF_PARTIALLY_PAID') && $object->total_ttc == $resteapayer))) ||
4405 ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $resteapayer >= 0) ||
4406 ($object->type == FactureFournisseur::TYPE_DEPOSIT && $object->total_ttc > 0 && ($resteapayer == 0 || (getDolGlobalString('SUPPLIER_INVOICE_CAN_SET_PAID_EVEN_IF_PARTIALLY_PAID') && $object->total_ttc == $resteapayer)))
4407 )
4408 ) {
4409 print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=paid&token='.newToken().'">'.$langs->trans('ClassifyPaid').'</a>';
4410 }
4411
4412 // Classify 'closed not completely paid' (possible if validated and not yet filed paid)
4413 if ($object->status == FactureFournisseur::STATUS_VALIDATED && $object->paid == 0 && $resteapayer > 0 && (!getDolGlobalString('SUPPLIER_INVOICE_CAN_SET_PAID_EVEN_IF_PARTIALLY_PAID') || $object->total_ttc != $resteapayer)) {
4414 if ($totalpaid > 0 || $totalcreditnotes > 0) {
4415 // If one payment or one credit note was linked to this invoice
4416 print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=paid&token='.newToken().'">'.$langs->trans('ClassifyPaidPartially').'</a>';
4417 } else {
4418 if (!getDolGlobalString('INVOICE_CAN_NEVER_BE_CANCELED')) {
4419 print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=canceled">'.$langs->trans('ClassifyCanceled').'</a>';
4420 }
4421 }
4422 }
4423
4424 // Create event
4425 /*if (isModEnabled('agenda') && getDolGlobalString('MAIN_ADD_EVENT_ON_ELEMENT_CARD')) { // Add hidden condition because this is not a "workflow" action so should appears somewhere else on page.
4426 print '<div class="inline-block divButAction"><a class="butAction" href="' . DOL_URL_ROOT . '/comm/action/card.php?action=create&amp;origin=' . $object->element . '&amp;originid=' . $object->id . '&amp;socid=' . $object->socid . '">' . $langs->trans("AddAction") . '</a></div>';
4427 }*/
4428
4429 // Create a credit note
4430 if (($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_DEPOSIT) && $object->status > 0 && $usercancreate) {
4431 if (!$objectidnext) {
4432 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?socid='.$object->socid.'&amp;fac_avoir='.$object->id.'&action=create&type=2'.($object->fk_project > 0 ? '&amp;projectid='.$object->fk_project : '').'">'.$langs->trans("CreateCreditNote").'</a>';
4433 }
4434 }
4435
4436 // Clone
4437 if ($action != 'edit' && $usercancreate) {
4438 print '<a class="butAction butActionClone" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=clone&socid='.$object->socid.'&token='.newToken().'">'.$langs->trans('ToClone').'</a>';
4439 }
4440
4441 // Clone as predefined / Create template
4442 if (($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_DEPOSIT) && $object->status == 0 && $usercancreate) {
4443 if (!$objectidnext && count($object->lines) > 0) {
4444 print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/card-rec.php?facid='.$object->id.'&action=create">'.$langs->trans("ChangeIntoRepeatableInvoice").'</a>';
4445 }
4446 }
4447
4448 // Delete
4449 if ($action != 'confirm_edit' && $usercandelete) {
4450 $isErasable = $object->is_erasable();
4451
4452 $enableDelete = false;
4453 $htmltooltip = '';
4454 $params = (empty($conf->use_javascript_ajax) ? array() : array('attr' => array('class' => 'reposition')));
4455 //var_dump($isErasable); var_dump($params);
4456 if ($isErasable == -4) {
4457 $htmltooltip = $langs->trans("DisabledBecausePayments");
4458 } elseif ($isErasable == -3) { // Should never happen with supplier invoice
4459 $htmltooltip = $langs->trans("DisabledBecauseNotLastSituationInvoice");
4460 } elseif ($isErasable == -2) { // Should never happen with supplier invoice
4461 $htmltooltip = $langs->trans("DisabledBecauseNotLastInvoice");
4462 } elseif ($isErasable == -1) {
4463 $htmltooltip = $langs->trans("DisabledBecauseDispatchedInBookkeeping");
4464 } elseif ($isErasable <= 0) { // Any other cases
4465 $htmltooltip = $langs->trans("DisabledBecauseNotErasable");
4466 } else {
4467 $enableDelete = true;
4468 $htmltooltip = '';
4469 }
4470 print dolGetButtonAction($htmltooltip, $langs->trans("Delete"), 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), (string) $object->id, $enableDelete, $params);
4471 }
4472 print '</div>';
4473
4474 if ($action != 'confirm_edit') {
4475 print '<div class="fichecenter"><div class="fichehalfleft">';
4476
4477 /*
4478 * Generated documents
4479 */
4480 $ref = dol_sanitizeFileName($object->ref);
4481 $subdir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier').$ref;
4482 $filedir = getMultidirOutput($object).'/'.$subdir;
4483 $urlsource = $_SERVER['PHP_SELF'].'?id='.$object->id;
4484 $genallowed = $usercanread;
4485 $delallowed = $usercancreate;
4486 $modelpdf = (empty($object->model_pdf) ? getDolGlobalString('INVOICE_SUPPLIER_ADDON_PDF') : $object->model_pdf);
4487 $genifempty = 0;
4488
4489 print $formfile->showdocuments('facture_fournisseur', $subdir, $filedir, $urlsource, (int) $genallowed, (int) $delallowed, $modelpdf, $genifempty, 0, 0, 40, 0, '', '', '', $societe->default_lang);
4490 $somethingshown = $formfile->numoffiles;
4491
4492 // Show links to link elements
4493 $tmparray = $form->showLinkToObjectBlock($object, array(), array('invoice_supplier'), 1);
4494 $linktoelem = $tmparray['linktoelem'];
4495 $htmltoenteralink = $tmparray['htmltoenteralink'];
4496 print $htmltoenteralink;
4497
4498 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
4499
4500 print '</div><div class="fichehalfright">';
4501
4502 // List of actions on element
4503 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
4504 $formactions = new FormActions($db);
4505 $somethingshown = $formactions->showactions($object, 'invoice_supplier', $socid, 1, 'listaction'.($genallowed ? 'largetitle' : ''));
4506
4507 print '</div></div>';
4508 }
4509 }
4510 }
4511
4512 // Select mail models is same action as presend
4513 if (GETPOST('modelselected')) {
4514 $action = 'presend';
4515 }
4516
4517 // Presend form
4518 $modelmail = 'invoice_supplier_send';
4519 $defaulttopic = 'SendBillRef';
4520 $diroutput = getMultidirOutput($object);
4521 $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO';
4522 $trackid = 'sinv'.$object->id;
4523
4524 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
4525 }
4526}
4527
4528
4529// End of page
4530llxFooter();
4531$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
Class to manage bank accounts.
Class to manage accounting journals.
const TYPE_PROFORMA
Proforma invoice.
const TYPE_SITUATION
Situation invoice.
Class to manage absolute discounts.
Class to manage a WYSIWYG editor.
Class to manage warehouses.
Class to manage standard extra fields.
Class to manage suppliers invoices.
const TYPE_DEPOSIT
Deposit invoice.
const TYPE_CREDIT_NOTE
Credit note invoice.
const TYPE_REPLACEMENT
Replacement invoice.
const STATUS_VALIDATED
Validated (need to be paid)
const TYPE_STANDARD
Standard invoice.
const STATUS_ABANDONED
Classified abandoned and no payment done.
const STATUS_CLOSED
Classified paid.
Class to manage invoice templates.
Class to manage building of HTML components.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class with static methods for building HTML components related to products Only components common to ...
Class to manage building of HTML components.
Class to manage payments for supplier invoices.
Class ProductCombination Used to represent the relation between a product and one of its variants.
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.
isInEEC($object)
Return if a country of an object is inside the EEC (European Economic Community)
global $mysoc
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:651
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition date.lib.php:126
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.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
$date_start
Variables from include:
facturefourn_prepare_head(FactureFournisseur $object)
Prepare array with list of tabs.
Definition fourn.lib.php:38
dol_now($mode='gmt')
Return date for now.
recordNotFound($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Displays an error page when a record is not found.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
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.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
getMultidirOutput($object, $module='', $forobject=0, $mode='output')
Return the full path of the directory where a module (or an object of a module) stores its files.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTFLOAT($paramname, $rounding='', $option=2)
Return the value of a $_GET or $_POST supervariable, converted into float.
dolGetButtonAction($label, $text='', $actionType='default', $url='', $id='', $userRight=1, $params=array())
Function dolGetButtonAction.
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...
dol_htmloutput_events($disabledoutputofmessages=0)
Print formatted messages to output (Used to show messages on html output).
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
getDictionaryValue($tablename, $field, $id, $checkentity=false, $rowidfield='rowid')
Return the value of a filed into a dictionary for the record $id.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='', $textonpictotooltip='', $cssfordropdown='info_admin')
Show information in HTML for admin users or standard users.
get_localtax($vatrate, $local, $thirdparty_buyer=null, $thirdparty_seller=null, $vatnpr=0)
Return localtax rate for a particular VAT rate, when selling a product with vat $vatrate,...
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
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...
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
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.