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