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