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