dolibarr 21.0.3
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-2025 Frédéric France <frederic.france@free.fr>
13 * Copyright (C) 2019 Ferran Marcet <fmarcet@2byte.es>
14 * Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
15 * Copyright (C) 2023 Nick Fragoulis
16 * Copyright (C) 2024 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")) || ($usercancreate && $object->is_erasable() == 1));
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) {
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 dol_include_once('/'.$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 dol_include_once('/'.$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 // @phan-suppress-next-line PhanTypeMismatchArgumentInternal
1351 if (!empty($lines[$i]->vat_src_code) && !preg_match('/\‍(/', (string) $tva_tx)) {
1352 $tva_tx .= ' ('.$lines[$i]->vat_src_code.')';
1353 }
1354
1355 // FIXME Missing special_code into addline and updateline methods
1356 $object->special_code = $lines[$i]->special_code;
1357
1358 // FIXME If currency different from main currency, take multicurrency price
1359 if ($object->multicurrency_code != $conf->currency || $object->multicurrency_tx != 1) {
1360 $pu = 0;
1361 $pu_currency = $lines[$i]->multicurrency_subprice;
1362 } else {
1363 $pu = $lines[$i]->subprice;
1364 $pu_currency = 0;
1365 }
1366
1367 // FIXME Missing $lines[$i]->ref_supplier and $lines[$i]->label into addline and updateline methods. They are filled when coming from order for example.
1368 $result = $object->addline(
1369 $desc,
1370 $pu,
1371 $tva_tx,
1372 $lines[$i]->localtax1_tx,
1373 $lines[$i]->localtax2_tx,
1374 $lines[$i]->qty,
1375 $lines[$i]->fk_product,
1376 $lines[$i]->remise_percent,
1377 $date_start,
1378 $date_end,
1379 0,
1380 $lines[$i]->info_bits,
1381 'HT',
1382 $product_type,
1383 $lines[$i]->rang,
1384 0,
1385 $lines[$i]->array_options,
1386 $lines[$i]->fk_unit,
1387 $lines[$i]->id,
1388 $pu_currency,
1389 $lines[$i]->ref_supplier,
1390 $lines[$i]->special_code
1391 );
1392
1393 if ($result < 0) {
1394 $error++;
1395 break;
1396 }
1397 }
1398
1399 // Now reload line
1400 $object->fetch_lines();
1401 } else {
1402 $error++;
1403 }
1404 } else {
1405 $error++;
1406 }
1407 } elseif (!$error) {
1408 $id = $object->create($user);
1409 if ($id < 0) {
1410 $error++;
1411 }
1412 }
1413 }
1414 }
1415
1416 if ($error) {
1417 $langs->load("errors");
1418 $db->rollback();
1419
1420 setEventMessages($object->error, $object->errors, 'errors');
1421 $action = 'create';
1422 //$_GET['socid'] = $_POST['socid'];
1423 } else {
1424 $db->commit();
1425
1426 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1427 $outputlangs = $langs;
1428 $result = $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1429 if ($result < 0) {
1430 dol_print_error($db, $object->error, $object->errors);
1431 exit;
1432 }
1433 }
1434
1435 header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
1436 exit;
1437 }
1438 } elseif ($action == 'updateline' && $usercancreate) {
1439 // Edit line
1440 $db->begin();
1441
1442 if (! $object->fetch($id) > 0) {
1443 dol_print_error($db);
1444 }
1445 $object->fetch_thirdparty();
1446
1447 $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
1448 $tva_tx = str_replace('*', '', $tva_tx);
1449
1450 if (GETPOST('price_ht') != '' || GETPOST('multicurrency_subprice') != '') {
1451 $up = price2num(GETPOST('price_ht'), '', 2);
1452 $price_base_type = 'HT';
1453 } else {
1454 $up = price2num(GETPOST('price_ttc'), '', 2);
1455 $price_base_type = 'TTC';
1456 }
1457
1458 if (GETPOST('productid') > 0) {
1459 $productsupplier = new ProductFournisseur($db);
1460 if (getDolGlobalInt('SUPPLIER_INVOICE_WITH_PREDEFINED_PRICES_ONLY') == 1) { // Not the common case
1461 if (GETPOST('productid') > 0 && $productsupplier->get_buyprice(0, price2num(GETPOST('qty')), GETPOSTINT('productid'), 'restricthtml', GETPOSTINT('socid')) < 0) {
1462 setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'warnings');
1463 }
1464 }
1465
1466 $prod = new Product($db);
1467 $prod->fetch(GETPOST('productid'));
1468 $label = $prod->description;
1469 if (trim(GETPOST('product_desc', 'restricthtml')) != trim($label)) {
1470 $label = GETPOST('product_desc', 'restricthtml');
1471 }
1472
1473 $type = $prod->type;
1474 } else {
1475 $label = GETPOST('product_desc', 'restricthtml');
1476 $type = GETPOST("type") ? GETPOST("type") : 0;
1477 }
1478
1479 $date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear'));
1480 $date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear'));
1481
1482 // Define info_bits
1483 $info_bits = 0;
1484 if (preg_match('/\*/', $tva_tx)) {
1485 $info_bits |= 0x01;
1486 }
1487
1488 // Define vat_rate
1489 $tva_tx = str_replace('*', '', $tva_tx);
1490 $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty);
1491 $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty);
1492
1493 $remise_percent = price2num(GETPOST('remise_percent'), '', 2);
1494 $pu_devise = price2num(GETPOST('multicurrency_subprice'), 'MU', 2);
1495
1496 // Extrafields Lines
1497 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
1498 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line);
1499 // Unset extrafield POST Data
1500 if (is_array($extralabelsline)) {
1501 foreach ($extralabelsline as $key => $value) {
1502 unset($_POST["options_".$key]);
1503 }
1504 }
1505
1506 $result = $object->updateline(
1507 GETPOSTINT('lineid'),
1508 $label,
1509 $up,
1510 $tva_tx,
1511 $localtax1_tx,
1512 $localtax2_tx,
1513 price2num(GETPOST('qty'), 'MS'),
1514 GETPOSTINT('productid'),
1515 $price_base_type,
1516 $info_bits,
1517 $type,
1518 $remise_percent,
1519 0,
1520 $date_start,
1521 $date_end,
1522 $array_options,
1523 GETPOST('units', 'alpha'),
1524 $pu_devise,
1525 GETPOST('fourn_ref', 'alpha')
1526 );
1527 if ($result >= 0) {
1528 unset($_POST['label']);
1529 unset($_POST['fourn_ref']);
1530 unset($_POST['date_starthour']);
1531 unset($_POST['date_startmin']);
1532 unset($_POST['date_startsec']);
1533 unset($_POST['date_startday']);
1534 unset($_POST['date_startmonth']);
1535 unset($_POST['date_startyear']);
1536 unset($_POST['date_endhour']);
1537 unset($_POST['date_endmin']);
1538 unset($_POST['date_endsec']);
1539 unset($_POST['date_endday']);
1540 unset($_POST['date_endmonth']);
1541 unset($_POST['date_endyear']);
1542 unset($_POST['price_ttc']);
1543 unset($_POST['price_ht']);
1544
1545 $db->commit();
1546 } else {
1547 $db->rollback();
1548 setEventMessages($object->error, $object->errors, 'errors');
1549 }
1550 } elseif ($action == 'addline' && GETPOST('submitforalllines', 'aZ09') && (GETPOST('alldate_start', 'alpha') || GETPOST('alldate_end', 'alpha')) && $usercancreate) {
1551 // Define date start and date end for all line
1552 $alldate_start = dol_mktime(GETPOST('alldate_starthour'), GETPOST('alldate_startmin'), 0, GETPOST('alldate_startmonth'), GETPOST('alldate_startday'), GETPOST('alldate_startyear'));
1553 $alldate_end = dol_mktime(GETPOST('alldate_endhour'), GETPOST('alldate_endmin'), 0, GETPOST('alldate_endmonth'), GETPOST('alldate_endday'), GETPOST('alldate_endyear'));
1554 foreach ($object->lines as $line) {
1555 if ($line->product_type == 1) { // only service line
1556 $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);
1557 }
1558 }
1559 } elseif ($action == 'addline' && GETPOST('submitforalllines', 'aZ09') && GETPOST('vatforalllines', 'alpha') != '' && $usercancreate) {
1560 // Define vat_rate
1561 $vat_rate = (GETPOST('vatforalllines') ? GETPOST('vatforalllines') : 0);
1562 $vat_rate = str_replace('*', '', $vat_rate);
1563 $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty, $mysoc);
1564 $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty, $mysoc);
1565 foreach ($object->lines as $line) {
1566 $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);
1567 }
1568 } elseif ($action == 'addline' && $usercancreate) {
1569 // Add a product line
1570 $db->begin();
1571
1572 $ret = $object->fetch($id);
1573 if ($ret < 0) {
1574 dol_print_error($db, $object->error);
1575 exit;
1576 }
1577 $ret = $object->fetch_thirdparty();
1578
1579 $langs->load('errors');
1580 $error = 0;
1581
1582 // Set if we used free entry or predefined product
1583 $predef = '';
1584 $product_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : '');
1585 $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'));
1586 $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'));
1587
1588 $prod_entry_mode = GETPOST('prod_entry_mode');
1589 if ($prod_entry_mode == 'free') {
1590 $idprod = 0;
1591 } else {
1592 $idprod = GETPOSTINT('idprod');
1593 }
1594
1595 $price_ht = '';
1596 $price_ht_devise = '';
1597 $price_ttc = '';
1598 $price_ttc_devise = '';
1599
1600 if (GETPOST('price_ht') !== '') {
1601 $price_ht = price2num(GETPOST('price_ht'), 'MU', 2);
1602 }
1603 if (GETPOST('multicurrency_price_ht') !== '') {
1604 $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2);
1605 }
1606 if (GETPOST('price_ttc') !== '') {
1607 $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2);
1608 }
1609 if (GETPOST('multicurrency_price_ttc') !== '') {
1610 $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2);
1611 }
1612
1613 $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); // Can be '1.2' or '1.2 (CODE)'
1614
1615 $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS');
1616
1617 $remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef, 'alpha'), '', 2) : 0);
1618 if (empty($remise_percent)) {
1619 $remise_percent = 0;
1620 }
1621
1622 // Extrafields
1623 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
1624 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
1625 // Unset extrafield
1626 if (is_array($extralabelsline)) {
1627 // Get extra fields
1628 foreach ($extralabelsline as $key => $value) {
1629 unset($_POST["options_".$key]);
1630 }
1631 }
1632
1633 if ($prod_entry_mode == 'free' && GETPOST('price_ht') < 0 && $qty < 0) {
1634 setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPrice'), $langs->transnoentitiesnoconv('Qty')), null, 'errors');
1635 $error++;
1636 }
1637 if ($prod_entry_mode == 'free' && (!GETPOST('idprodfournprice') || GETPOST('idprodfournprice') == '-1') && GETPOST('type') < 0) {
1638 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors');
1639 $error++;
1640 }
1641
1642 // Do not allow negative lines for free products (invite to enter a discount instead)
1643 if ($prod_entry_mode == 'free' && (!GETPOST('idprodfournprice') || GETPOST('idprodfournprice') == '-1')
1644 && (((float) $price_ht < 0 && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES')) || $price_ht === '')
1645 && (((float) $price_ht_devise < 0 && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES')) || $price_ht_devise === '')
1646 && ((float) $price_ttc < 0 && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES') || $price_ttc === '')
1647 && ((float) $price_ttc_devise < 0 && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES') || $price_ttc_devise === '')
1648 && $object->type != $object::TYPE_CREDIT_NOTE) { // Unit price can be 0 but not ''
1649 if (((float) $price_ht < 0 || (float) $price_ttc < 0) && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES')) {
1650 $langs->load("errors");
1651 if ($object->type == $object::TYPE_DEPOSIT) {
1652 // Using negative lines on deposit lead to headach and blocking problems when you want to consume them.
1653 setEventMessages($langs->trans("ErrorLinesCantBeNegativeOnDeposits"), null, 'errors');
1654 } else {
1655 setEventMessages($langs->trans("ErrorFieldCantBeNegativeOnInvoice", $langs->transnoentitiesnoconv("UnitPrice"), $langs->transnoentitiesnoconv("CustomerAbsoluteDiscountShort")), null, 'errors');
1656 }
1657 $error++;
1658 }
1659 }
1660 if ($prod_entry_mode == 'free' && (!GETPOST('idprodfournprice') || GETPOST('idprodfournprice') == '-1') && GETPOST('price_ht') === '' && GETPOST('price_ttc') === '' && $price_ht_devise === '') { // Unit price can be 0 but not ''
1661 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('UnitPrice')), null, 'errors');
1662 $error++;
1663 }
1664
1665 if ($prod_entry_mode == 'free' && (!GETPOST('idprodfournprice') || GETPOST('idprodfournprice') == '-1') && !GETPOST('dp_desc')) {
1666 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors');
1667 $error++;
1668 }
1669 if (!GETPOST('qty', 'alpha')) { // 0 is NOT allowed for invoices
1670 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
1671 $error++;
1672 }
1673
1674 if (!$error && isModEnabled('variants') && $prod_entry_mode != 'free') {
1675 if ($combinations = GETPOST('combinations', 'array')) {
1676 //Check if there is a product with the given combination
1677 $prodcomb = new ProductCombination($db);
1678
1679 if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) {
1680 $idprod = $res->fk_product_child;
1681 } else {
1682 setEventMessages($langs->trans('ErrorProductCombinationNotFound'), null, 'errors');
1683 $error++;
1684 }
1685 }
1686 }
1687
1688 if ($prod_entry_mode != 'free' && empty($error)) { // With combolist mode idprodfournprice is > 0 or -1. With autocomplete, idprodfournprice is > 0 or ''
1689 $productsupplier = new ProductFournisseur($db);
1690
1691 $idprod = 0;
1692 if (GETPOST('idprodfournprice', 'alpha') == -1 || GETPOST('idprodfournprice', 'alpha') == '') {
1693 $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, ...)
1694 }
1695
1696 $reg = array();
1697 if (preg_match('/^idprod_([0-9]+)$/', GETPOST('idprodfournprice', 'alpha'), $reg)) {
1698 $idprod = $reg[1];
1699 $res = $productsupplier->fetch($idprod); // Load product from its id
1700 // Call to init some price properties of $productsupplier
1701 // So if a supplier price already exists for another thirdparty (first one found), we use it as reference price
1702 if (getDolGlobalString('SUPPLIER_TAKE_FIRST_PRICE_IF_NO_PRICE_FOR_CURRENT_SUPPLIER')) {
1703 $fksoctosearch = 0;
1704 $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist
1705 if ($productsupplier->fourn_socid != $socid) { // The price we found is for another supplier, so we clear supplier price
1706 $productsupplier->ref_supplier = '';
1707 }
1708 } else {
1709 $fksoctosearch = $object->thirdparty->id;
1710 $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist
1711 }
1712 } elseif (GETPOST('idprodfournprice', 'alpha') > 0) {
1713 $qtytosearch = $qty; // Just to see if a price exists for the quantity. Not used to found vat.
1714 //$qtytosearch=-1; // We force qty to -1 to be sure to find if a supplier price exist
1715 $idprod = $productsupplier->get_buyprice(GETPOST('idprodfournprice', 'alpha'), $qtytosearch);
1716 $res = $productsupplier->fetch($idprod);
1717 }
1718
1719 if ($idprod > 0) {
1720 $label = $productsupplier->label;
1721 // Define output language
1722 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
1723 $outputlangs = $langs;
1724 $newlang = '';
1725 if (empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1726 $newlang = GETPOST('lang_id', 'aZ09');
1727 }
1728 if (empty($newlang)) {
1729 $newlang = $object->thirdparty->default_lang;
1730 }
1731 if (!empty($newlang)) {
1732 $outputlangs = new Translate("", $conf);
1733 $outputlangs->setDefaultLang($newlang);
1734 }
1735 $desc = (!empty($productsupplier->multilangs[$outputlangs->defaultlang]["description"])) ? $productsupplier->multilangs[$outputlangs->defaultlang]["description"] : $productsupplier->description;
1736 } else {
1737 $desc = $productsupplier->description;
1738 }
1739 // if we use supplier description of the products
1740 if (!empty($productsupplier->desc_supplier) && getDolGlobalString('PRODUIT_FOURN_TEXTS')) {
1741 $desc = $productsupplier->desc_supplier;
1742 }
1743
1744 //If text set in desc is the same as product descpription (as now it's preloaded) we add it only one time
1745 if (trim($product_desc) == trim($desc) && getDolGlobalString('PRODUIT_AUTOFILL_DESC')) {
1746 $product_desc = '';
1747 }
1748 if (!empty($product_desc) && getDolGlobalString('MAIN_NO_CONCAT_DESCRIPTION')) {
1749 $desc = $product_desc;
1750 }
1751 if (!empty($product_desc) && trim($product_desc) != trim($desc)) {
1752 $desc = dol_concatdesc($desc, $product_desc, false, getDolGlobalString('MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION') ? true : false);
1753 }
1754
1755 $ref_supplier = $productsupplier->ref_supplier;
1756
1757 // Get vat rate
1758 if (!GETPOSTISSET('tva_tx')) { // If vat rate not provided from the form (the form has the priority)
1759 $tmpidprodfournprice = GETPOST('idprodfournprice', 'alpha'); // can be an id of price, or -1, -2, -99 or 'idprod_...'
1760 if (is_numeric($tmpidprodfournprice) && (int) $tmpidprodfournprice > 0) {
1761 $tmpidprodfournprice = (int) $tmpidprodfournprice;
1762 } else {
1763 $tmpidprodfournprice = 0;
1764 }
1765
1766 $tva_tx = get_default_tva($object->thirdparty, $mysoc, $productsupplier->id, $tmpidprodfournprice);
1767 $tva_npr = get_default_npr($object->thirdparty, $mysoc, $productsupplier->id, $tmpidprodfournprice);
1768 }
1769 if (empty($tva_tx) || empty($tva_npr)) {
1770 $tva_npr = 0;
1771 }
1772 $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty, $tva_npr);
1773 $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty, $tva_npr);
1774
1775 $type = $productsupplier->type;
1776 if (GETPOST('price_ht') != '' || GETPOST('multicurrency_price_ht') != '') {
1777 $price_base_type = 'HT';
1778 $pu = price2num($price_ht, 'MU');
1779 $pu_devise = price2num($price_ht_devise, 'CU');
1780 } elseif (GETPOST('price_ttc') != '' || GETPOST('multicurrency_price_ttc') != '') {
1781 $price_base_type = 'TTC';
1782 $pu = price2num($price_ttc, 'MU');
1783 $pu_devise = price2num($price_ttc_devise, 'CU');
1784 } else {
1785 $price_base_type = ($productsupplier->fourn_price_base_type ? $productsupplier->fourn_price_base_type : 'HT');
1786 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
1787 $pu = $productsupplier->fourn_pu;
1788 $pu_devise = 0;
1789 } else {
1790 $pu = $productsupplier->fourn_pu;
1791 $pu_devise = $productsupplier->fourn_multicurrency_unitprice;
1792 }
1793 }
1794
1795 $ref_supplier = $productsupplier->ref_supplier;
1796
1797 if (empty($pu)) {
1798 $pu = 0; // If pu is '' or null, we force to have a numeric value
1799 }
1800
1801 $result = $object->addline(
1802 $desc,
1803 $pu,
1804 $tva_tx,
1805 $localtax1_tx,
1806 $localtax2_tx,
1807 $qty,
1808 $idprod,
1809 $remise_percent,
1810 $date_start,
1811 $date_end,
1812 0,
1813 $tva_npr,
1814 $price_base_type,
1815 $type,
1816 min($rank, count($object->lines) + 1),
1817 0,
1818 $array_options,
1819 $productsupplier->fk_unit,
1820 0,
1821 $pu_devise,
1822 GETPOST('fourn_ref', 'alpha'),
1823 0
1824 );
1825 }
1826 if ($idprod == -99 || $idprod == 0) {
1827 // Product not selected
1828 $error++;
1829 $langs->load("errors");
1830 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductOrService")), null, 'errors');
1831 }
1832 if ($idprod == -1) {
1833 // Quantity too low
1834 $error++;
1835 $langs->load("errors");
1836 setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'errors');
1837 }
1838 } elseif (empty($error)) { // $price_ht is already set
1839 $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
1840 $tva_tx = str_replace('*', '', $tva_tx);
1841 $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
1842 $desc = $product_desc;
1843 $type = GETPOST('type');
1844 $ref_supplier = GETPOST('fourn_ref', 'alpha');
1845
1846 $fk_unit = GETPOST('units', 'alpha');
1847
1848 if (!preg_match('/\‍((.*)\‍)/', $tva_tx)) {
1849 $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'
1850 }
1851
1852 // Local Taxes
1853 $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty);
1854 $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty);
1855
1856 if (GETPOST('price_ht') != '' || GETPOST('multicurrency_price_ht') != '') {
1857 $pu_ht = price2num($price_ht, 'MU'); // $pu_ht must be rounded according to settings
1858 } else {
1859 $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
1860 $pu_ht = price2num((float) $pu_ttc / (1 + ((float) $tva_tx / 100)), 'MU'); // $pu_ht must be rounded according to settings
1861 }
1862 $price_base_type = 'HT';
1863 $pu_devise = price2num($price_ht_devise, 'CU');
1864
1865 $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);
1866 }
1867
1868 //print "xx".$tva_tx; exit;
1869 if (!$error && $result > 0) {
1870 $db->commit();
1871
1872 // Define output language
1873 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1874 $outputlangs = $langs;
1875 $newlang = '';
1876 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1877 $newlang = GETPOST('lang_id', 'aZ09');
1878 }
1879 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1880 $newlang = $object->thirdparty->default_lang;
1881 }
1882 if (!empty($newlang)) {
1883 $outputlangs = new Translate("", $conf);
1884 $outputlangs->setDefaultLang($newlang);
1885 }
1886 $model = $object->model_pdf;
1887 $ret = $object->fetch($id); // Reload to get new records
1888
1889 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1890 if ($result < 0) {
1891 dol_print_error($db, $object->error, $object->errors);
1892 }
1893 }
1894
1895 unset($_POST ['prod_entry_mode']);
1896
1897 unset($_POST['qty']);
1898 unset($_POST['type']);
1899 unset($_POST['remise_percent']);
1900 unset($_POST['pu']);
1901 unset($_POST['price_ht']);
1902 unset($_POST['multicurrency_price_ht']);
1903 unset($_POST['price_ttc']);
1904 unset($_POST['fourn_ref']);
1905 unset($_POST['tva_tx']);
1906 unset($_POST['label']);
1907 unset($localtax1_tx);
1908 unset($localtax2_tx);
1909 unset($_POST['np_marginRate']);
1910 unset($_POST['np_markRate']);
1911 unset($_POST['dp_desc']);
1912 unset($_POST['idprodfournprice']);
1913 unset($_POST['units']);
1914
1915 unset($_POST['date_starthour']);
1916 unset($_POST['date_startmin']);
1917 unset($_POST['date_startsec']);
1918 unset($_POST['date_startday']);
1919 unset($_POST['date_startmonth']);
1920 unset($_POST['date_startyear']);
1921 unset($_POST['date_endhour']);
1922 unset($_POST['date_endmin']);
1923 unset($_POST['date_endsec']);
1924 unset($_POST['date_endday']);
1925 unset($_POST['date_endmonth']);
1926 unset($_POST['date_endyear']);
1927 } else {
1928 $db->rollback();
1929 setEventMessages($object->error, $object->errors, 'errors');
1930 }
1931
1932 $action = '';
1933 } elseif ($action == 'classin' && $usercancreate) {
1934 $object->fetch($id);
1935 $result = $object->setProject($projectid);
1936 } elseif ($action == 'confirm_edit' && $confirm == 'yes' && $usercancreate) {
1937 // Set invoice to draft status
1938 $object->fetch($id);
1939
1940 $totalpaid = $object->getSommePaiement();
1941 $resteapayer = $object->total_ttc - $totalpaid;
1942
1943 // We check that lines of invoices are exported in accountancy
1944 $ventilExportCompta = $object->getVentilExportCompta();
1945
1946 if (!$ventilExportCompta) {
1947 // We verify that no payment was done
1948 if ($resteapayer == price2num($object->total_ttc, 'MT', 1) && $object->status == FactureFournisseur::STATUS_VALIDATED) {
1949 $idwarehouse = GETPOST('idwarehouse');
1950
1951 $object->fetch_thirdparty();
1952
1953 $qualified_for_stock_change = 0;
1954 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
1955 $qualified_for_stock_change = $object->hasProductsOrServices(2);
1956 } else {
1957 $qualified_for_stock_change = $object->hasProductsOrServices(1);
1958 }
1959
1960 // Check parameters
1961 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') && $qualified_for_stock_change) {
1962 $langs->load("stocks");
1963 if (!$idwarehouse || $idwarehouse == -1) {
1964 $error++;
1965 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
1966 $action = '';
1967 }
1968 }
1969
1970 $object->setDraft($user, $idwarehouse);
1971
1972 // Define output language
1973 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1974 $outputlangs = $langs;
1975 $newlang = '';
1976 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1977 $newlang = GETPOST('lang_id', 'aZ09');
1978 }
1979 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1980 $newlang = $object->thirdparty->default_lang;
1981 }
1982 if (!empty($newlang)) {
1983 $outputlangs = new Translate("", $conf);
1984 $outputlangs->setDefaultLang($newlang);
1985 }
1986 $model = $object->model_pdf;
1987 $ret = $object->fetch($id); // Reload to get new records
1988
1989 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1990 if ($result < 0) {
1991 dol_print_error($db, $object->error, $object->errors);
1992 }
1993 }
1994
1995 $action = '';
1996 }
1997 }
1998 } elseif ($action == 'reopen' && $usercancreate) {
1999 // Set invoice to validated/unpaid status
2000 $result = $object->fetch($id);
2002 || ($object->status == FactureFournisseur::STATUS_ABANDONED && $object->close_code != 'replaced')) {
2003 $result = $object->setUnpaid($user);
2004 if ($result > 0) {
2005 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);
2006 exit;
2007 } else {
2008 setEventMessages($object->error, $object->errors, 'errors');
2009 }
2010 }
2011 }
2012
2013 // Actions when printing a doc from card
2014 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
2015
2016 // Actions to send emails
2017 $triggersendname = 'BILL_SUPPLIER_SENTBYMAIL';
2018 $paramname = 'id';
2019 $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO';
2020 $trackid = 'sinv'.$object->id;
2021 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
2022
2023 // Actions to build doc
2024 $upload_dir = $conf->fournisseur->facture->dir_output;
2025 $permissiontoadd = $usercancreate;
2026 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
2027
2028 // Make calculation according to calculationrule
2029 if ($action == 'calculate' && $usercancreate) {
2030 $calculationrule = GETPOST('calculationrule');
2031
2032 $object->fetch($id);
2033 $object->fetch_thirdparty();
2034 $result = $object->update_price(0, (($calculationrule == 'totalofround') ? '0' : '1'), 0, $object->thirdparty);
2035 if ($result <= 0) {
2036 dol_print_error($db, $object->error, $object->errors);
2037 exit;
2038 }
2039 }
2040 if ($action == 'update_extras' && $usercancreate) {
2041 $object->oldcopy = dol_clone($object, 2);
2042
2043 // Fill array 'array_options' with data from add form
2044 $ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'restricthtml'));
2045 if ($ret < 0) {
2046 $error++;
2047 }
2048
2049 // Actions on extra fields
2050 if (!$error) {
2051 $result = $object->insertExtraFields('BILL_SUPPLIER_MODIFY');
2052 if ($result < 0) {
2053 $error++;
2054 setEventMessages($object->error, $object->errors, 'errors');
2055 }
2056 }
2057
2058 if ($error) {
2059 $action = 'edit_extras';
2060 }
2061 }
2062
2063 if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
2064 if ($action == 'addcontact' && $usercancreate) {
2065 $result = $object->fetch($id);
2066
2067 if ($result > 0 && $id > 0) {
2068 $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
2069 $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
2070 $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09'));
2071 }
2072
2073 if ($result >= 0) {
2074 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
2075 exit;
2076 } else {
2077 if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
2078 $langs->load("errors");
2079 setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
2080 } else {
2081 setEventMessages($object->error, $object->errors, 'errors');
2082 }
2083 }
2084 } elseif ($action == 'swapstatut' && $usercancreate) {
2085 // bascule du statut d'un contact
2086 if ($object->fetch($id)) {
2087 $result = $object->swapContactStatus(GETPOSTINT('ligne'));
2088 } else {
2089 dol_print_error($db);
2090 }
2091 } elseif ($action == 'deletecontact' && $usercancreate) {
2092 // Efface un contact
2093 $object->fetch($id);
2094 $result = $object->delete_contact(GETPOSTINT("lineid"));
2095
2096 if ($result >= 0) {
2097 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
2098 exit;
2099 } else {
2100 dol_print_error($db);
2101 }
2102 }
2103 }
2104}
2105
2106
2107/*
2108 * View
2109 */
2110
2111$form = new Form($db);
2112$formfile = new FormFile($db);
2113$bankaccountstatic = new Account($db);
2114$paymentstatic = new PaiementFourn($db);
2115if (isModEnabled('project')) {
2116 $formproject = new FormProjets($db);
2117}
2118
2119$now = dol_now();
2120
2121$title = $object->ref." - ".$langs->trans('Card');
2122if ($action == 'create') {
2123 $title = $langs->trans("NewSupplierInvoice");
2124}
2125$help_url = 'EN:Module_Suppliers_Invoices|FR:Module_Fournisseurs_Factures|ES:Módulo_Facturas_de_proveedores|DE:Modul_Lieferantenrechnungen';
2126llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-fourn-facture page-card');
2127
2128// Mode creation
2129if ($action == 'create') {
2130 $facturestatic = new FactureFournisseur($db);
2131 $selectedLines = array(); // Ensure initialised
2132
2133 print load_fiche_titre($langs->trans('NewSupplierInvoice'), '', 'supplier_invoice');
2134
2136
2137 $currency_code = $conf->currency;
2138
2139 $societe = '';
2140 if (GETPOSTINT('socid') > 0) {
2141 $societe = new Societe($db);
2142 $societe->fetch(GETPOSTINT('socid'));
2143 if (isModEnabled("multicurrency") && !empty($societe->multicurrency_code)) {
2144 $currency_code = $societe->multicurrency_code;
2145 }
2146 }
2147
2148 if (!empty($origin) && !empty($originid)) {
2149 // Parse element/subelement (ex: project_task)
2150 $element = $subelement = $origin;
2151
2152 if ($element == 'project') {
2153 $projectid = $originid;
2154 $element = 'projet';
2155 }
2156
2157 // For compatibility
2158 if ($element == 'order') {
2159 $element = $subelement = 'commande';
2160 }
2161 if ($element == 'propal') {
2162 $element = 'comm/propal';
2163 $subelement = 'propal';
2164 }
2165 if ($element == 'contract') {
2166 $element = $subelement = 'contrat';
2167 }
2168 if ($element == 'order_supplier') {
2169 $element = 'fourn';
2170 $subelement = 'fournisseur.commande';
2171 }
2172
2173 dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
2174 $classname = ucfirst($subelement);
2175 if ($classname == 'Fournisseur.commande') {
2176 $classname = 'CommandeFournisseur';
2177 }
2178 $objectsrc = new $classname($db);
2179 '@phan-var-force Project|Commande|Propal|Facture|Contrat|CommandeFournisseur|CommonObject $objectsrc';
2180 $objectsrc->fetch($originid);
2181 $objectsrc->fetch_thirdparty();
2182
2183 $projectid = (!empty($objectsrc->fk_project) ? $objectsrc->fk_project : '');
2184 //$ref_client = (!empty($objectsrc->ref_client)?$object->ref_client:'');
2185 $soc = $objectsrc->thirdparty;
2186
2187 $cond_reglement_id = 0;
2188 $mode_reglement_id = 0;
2189 $fk_account = 0;
2190 //$remise_percent = 0;
2191 //$remise_absolue = 0;
2192 $transport_mode_id = 0;
2193
2194 // set from object source
2195 if (!empty($objectsrc->cond_reglement_id)) {
2196 $cond_reglement_id = $objectsrc->cond_reglement_id;
2197 }
2198 if (!empty($objectsrc->mode_reglement_id)) {
2199 $mode_reglement_id = $objectsrc->mode_reglement_id;
2200 }
2201 if (!empty($objectsrc->fk_account)) {
2202 $fk_account = $objectsrc->fk_account;
2203 }
2204 if (!empty($objectsrc->transport_mode_id)) {
2205 $transport_mode_id = $objectsrc->transport_mode_id;
2206 }
2207
2208 if (empty($cond_reglement_id)
2209 || empty($mode_reglement_id)
2210 || empty($fk_account)
2211 || empty($transport_mode_id)
2212 ) {
2213 if ($origin == 'reception') {
2214 // try to get from source of reception (supplier order)
2215 if (!isset($objectsrc->supplier_order)) {
2216 $objectsrc->fetch_origin();
2217 }
2218
2219 if (!empty($objectsrc->origin_object)) {
2220 $originObject = $objectsrc->origin_object;
2221 if (empty($cond_reglement_id) && !empty($originObject->cond_reglement_id)) {
2222 $cond_reglement_id = $originObject->cond_reglement_id;
2223 }
2224 if (empty($mode_reglement_id) && !empty($originObject->mode_reglement_id)) {
2225 $mode_reglement_id = $originObject->mode_reglement_id;
2226 }
2227 if (empty($fk_account) && !empty($originObject->fk_account)) {
2228 $fk_account = $originObject->fk_account;
2229 }
2230 if (empty($transport_mode_id) && !empty($originObject->transport_mode_id)) {
2231 $transport_mode_id = $originObject->transport_mode_id;
2232 }
2233 }
2234 }
2235
2236 // try to get from third-party of source object
2237 if (!empty($soc)) {
2238 if (empty($cond_reglement_id) && !empty($soc->cond_reglement_supplier_id)) {
2239 $cond_reglement_id = $soc->cond_reglement_supplier_id;
2240 }
2241 if (empty($mode_reglement_id) && !empty($soc->mode_reglement_supplier_id)) {
2242 $mode_reglement_id = $soc->mode_reglement_supplier_id;
2243 }
2244 if (empty($fk_account) && !empty($soc->fk_account)) {
2245 $fk_account = $soc->fk_account;
2246 }
2247 if (empty($transport_mode_id) && !empty($soc->transport_mode_id)) {
2248 $transport_mode_id = $soc->transport_mode_id;
2249 }
2250 }
2251 }
2252
2253 if (isModEnabled("multicurrency")) {
2254 if (!empty($objectsrc->multicurrency_code)) {
2255 $currency_code = $objectsrc->multicurrency_code;
2256 }
2257 if (getDolGlobalString('MULTICURRENCY_USE_ORIGIN_TX') && !empty($objectsrc->multicurrency_tx)) {
2258 $currency_tx = $objectsrc->multicurrency_tx;
2259 }
2260 }
2261
2262 $datetmp = dol_mktime(12, 0, 0, GETPOSTINT('remonth'), GETPOSTINT('reday'), GETPOSTINT('reyear'));
2263 $dateinvoice = ($datetmp == '' ? (!getDolGlobalString('MAIN_AUTOFILL_DATE') ? -1 : '') : $datetmp);
2264 $datetmp = dol_mktime(12, 0, 0, GETPOSTINT('echmonth'), GETPOSTINT('echday'), GETPOSTINT('echyear'));
2265 $datedue = ($datetmp == '' ? -1 : $datetmp);
2266
2267 // Replicate extrafields
2268 $objectsrc->fetch_optionals();
2269 $object->array_options = $objectsrc->array_options;
2270 } else {
2271 $cond_reglement_id = !empty($societe->cond_reglement_supplier_id) ? $societe->cond_reglement_supplier_id : 0;
2272 $mode_reglement_id = !empty($societe->mode_reglement_supplier_id) ? $societe->mode_reglement_supplier_id : 0;
2273 $vat_reverse_charge = (empty($societe) ? '' : $societe->vat_reverse_charge);
2274 $transport_mode_id = !empty($societe->transport_mode_supplier_id) ? $societe->transport_mode_supplier_id : 0;
2275 $fk_account = !empty($societe->fk_account) ? $societe->fk_account : 0;
2276 $datetmp = dol_mktime(12, 0, 0, GETPOSTINT('remonth'), GETPOSTINT('reday'), GETPOSTINT('reyear'));
2277 $dateinvoice = ($datetmp == '' ? (getDolGlobalInt('MAIN_AUTOFILL_DATE') ? '' : -1) : $datetmp);
2278 $datetmp = dol_mktime(12, 0, 0, GETPOSTINT('echmonth'), GETPOSTINT('echday'), GETPOSTINT('echyear'));
2279 $datedue = ($datetmp == '' ? -1 : $datetmp);
2280
2281 if (isModEnabled("multicurrency") && !empty($societe->multicurrency_code)) {
2282 $currency_code = $societe->multicurrency_code;
2283 }
2284 }
2285
2286 // when payment condition is empty (means not override by payment condition form a other object, like third-party), try to use default value
2287 if (empty($cond_reglement_id)) {
2288 $cond_reglement_id = GETPOST("cond_reglement_id");
2289 }
2290
2291 // when payment mode is empty (means not override by payment condition form a other object, like third-party), try to use default value
2292 if (empty($mode_reglement_id)) {
2293 $mode_reglement_id = GETPOST("mode_reglement_id");
2294 }
2295
2296 // If form was posted (but error returned), we must reuse the value posted in priority (standard Dolibarr behaviour)
2297 if (!GETPOST('changecompany')) {
2298 if (GETPOSTISSET('cond_reglement_id')) {
2299 $cond_reglement_id = GETPOSTINT('cond_reglement_id');
2300 }
2301 if (GETPOSTISSET('mode_reglement_id')) {
2302 $mode_reglement_id = GETPOSTINT('mode_reglement_id');
2303 }
2304 if (GETPOSTISSET('cond_reglement_id')) {
2305 $fk_account = GETPOSTINT('fk_account');
2306 }
2307 }
2308
2309 $note_public = $object->getDefaultCreateValueFor('note_public', ((!empty($origin) && !empty($originid) && is_object($objectsrc) && getDolGlobalString('FACTUREFOURN_REUSE_NOTES_ON_CREATE_FROM')) ? $objectsrc->note_public : null));
2310 $note_private = $object->getDefaultCreateValueFor('note_private', ((!empty($origin) && !empty($originid) && is_object($objectsrc) && getDolGlobalString('FACTUREFOURN_REUSE_NOTES_ON_CREATE_FROM')) ? $objectsrc->note_private : null));
2311
2312 if ($origin == 'contrat') {
2313 $langs->load("admin");
2314 $text = $langs->trans("ToCreateARecurringInvoice");
2315 $text .= ' '.$langs->trans("ToCreateARecurringInvoiceGene", $langs->transnoentitiesnoconv("MenuFinancial"), $langs->transnoentitiesnoconv("SupplierBills"), $langs->transnoentitiesnoconv("ListOfTemplates"));
2316 if (!getDolGlobalString('INVOICE_DISABLE_AUTOMATIC_RECURRING_INVOICE')) {
2317 $text .= ' '.$langs->trans("ToCreateARecurringInvoiceGeneAuto", $langs->transnoentitiesnoconv('Module2300Name'));
2318 }
2319 print info_admin($text, 0, 0, '0', 'opacitymedium').'<br>';
2320 }
2321
2322 print '<form name="add" action="'.$_SERVER["PHP_SELF"].'" method="post">';
2323 print '<input type="hidden" name="token" value="'.newToken().'">';
2324 print '<input type="hidden" name="action" value="add">';
2325 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
2326
2327 if (!empty($societe->id) && $societe->id > 0) {
2328 print '<input type="hidden" name="socid" value="'.$societe->id.'">'."\n";
2329 }
2330 print '<input type="hidden" name="origin" value="'.$origin.'">';
2331 print '<input type="hidden" name="originid" value="'.$originid.'">';
2332 if (!empty($currency_tx)) {
2333 print '<input type="hidden" name="originmulticurrency_tx" value="'.$currency_tx.'">';
2334 }
2335 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
2336
2337 print dol_get_fiche_head();
2338
2339 // Call Hook tabContentCreateSupplierInvoice
2340 $parameters = array();
2341 // Note that $action and $object may be modified by hook
2342 $reshook = $hookmanager->executeHooks('tabContentCreateSupplierInvoice', $parameters, $object, $action);
2343 if (empty($reshook)) {
2344 print '<table class="border centpercent">';
2345
2346 // Ref
2347 print '<tr><td class="titlefieldcreate">'.$langs->trans('Ref').'</td><td>'.$langs->trans('Draft').'</td></tr>';
2348
2349 $exampletemplateinvoice = new FactureFournisseurRec($db);
2350 $invoice_predefined = new FactureFournisseurRec($db);
2351 if (empty($origin) && empty($originid) && $fac_recid > 0) {
2352 $invoice_predefined->fetch($fac_recid);
2353 }
2354
2355 // Third party
2356 print '<tr><td class="fieldrequired">'.$langs->trans('Supplier').'</td>';
2357 print '<td>';
2358
2359 if (!empty($societe->id) && $societe->id > 0 && ($fac_recid <= 0 || !empty($invoice_predefined->frequency))) {
2360 $absolute_discount = $societe->getAvailableDiscounts(null, '', 0, 1);
2361 print $societe->getNomUrl(1, 'supplier');
2362 print '<input type="hidden" name="socid" value="'.$societe->id.'">';
2363 } else {
2364 $filter = '((s.fournisseur:=:1) AND (s.status:=:1))';
2365 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');
2366 // reload page to retrieve supplier information
2367 if (!getDolGlobalString('RELOAD_PAGE_ON_SUPPLIER_CHANGE_DISABLED')) {
2368 print '<script type="text/javascript">
2369 $(document).ready(function() {
2370 $("#socid").change(function() {
2371 console.log("We have changed the company - Reload page");
2372 // reload page
2373 $("input[name=action]").val("create");
2374 $("input[name=changecompany]").val("1");
2375 $("form[name=add]").submit();
2376 });
2377 });
2378 </script>';
2379 }
2380 if ($fac_recid <= 0) {
2381 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>';
2382 }
2383 }
2384 print '</td></tr>';
2385
2386 // Overwrite some values if creation of invoice is from a predefined invoice
2387 if (empty($origin) && empty($originid) && $fac_recid > 0) {
2388 $invoice_predefined->fetch($fac_recid);
2389
2390 $dateinvoice = $invoice_predefined->date_when; // To use next gen date by default later
2391 if (empty($projectid)) {
2392 $projectid = $invoice_predefined->fk_project;
2393 }
2394 $cond_reglement_id = $invoice_predefined->cond_reglement_id;
2395 $mode_reglement_id = $invoice_predefined->mode_reglement_id;
2396 $fk_account = $invoice_predefined->fk_account;
2397 $note_public = $invoice_predefined->note_public;
2398 $note_private = $invoice_predefined->note_private;
2399
2400 if (!empty($invoice_predefined->multicurrency_code)) {
2401 $currency_code = $invoice_predefined->multicurrency_code;
2402 }
2403 if (!empty($invoice_predefined->multicurrency_tx)) {
2404 $currency_tx = $invoice_predefined->multicurrency_tx;
2405 }
2406
2407 $sql = 'SELECT r.rowid, r.titre as title, r.total_ttc';
2408 $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_rec as r';
2409 $sql .= ' WHERE r.fk_soc = '. (int) $invoice_predefined->socid;
2410
2411 $resql = $db->query($sql);
2412 if ($resql) {
2413 $num = $db->num_rows($resql);
2414 $i = 0;
2415
2416 if ($num > 0) {
2417 print '<tr><td>'.$langs->trans('CreateFromRepeatableInvoice').'</td><td>';
2418 //print '<input type="hidden" name="fac_rec" id="fac_rec" value="'.$fac_recid.'">';
2419 print '<select class="flat" id="fac_rec" name="fac_rec">'; // We may want to change the template to use
2420 print '<option value="0" selected></option>';
2421 while ($i < $num) {
2422 $objp = $db->fetch_object($resql);
2423 print '<option value="'.$objp->rowid.'"';
2424 if ($fac_recid == $objp->rowid) {
2425 print ' selected';
2426 $exampletemplateinvoice->fetch($fac_recid);
2427 }
2428 print '>'.$objp->title.' ('.price($objp->total_ttc).' '.$langs->trans("TTC").')</option>';
2429 $i++;
2430 }
2431 print '</select>';
2432 // Option to reload page to retrieve customer information. Note, this clear other input
2433 if (!getDolGlobalString('RELOAD_PAGE_ON_TEMPLATE_CHANGE_DISABLED')) {
2434 print '<script type="text/javascript">
2435 $(document).ready(function() {
2436 $("#fac_rec").change(function() {
2437 console.log("We have changed the template invoice - Reload page");
2438 // reload page
2439 $("input[name=action]").val("create");
2440 $("form[name=add]").submit();
2441 });
2442 });
2443 </script>';
2444 }
2445 print '</td></tr>';
2446 }
2447 $db->free($resql);
2448 } else {
2449 dol_print_error($db);
2450 }
2451 }
2452
2453 // Ref supplier
2454 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"';
2455 if (!empty($societe->id) && $societe->id > 0) {
2456 print ' autofocus';
2457 }
2458 print '></td>';
2459 print '</tr>';
2460
2461 print '<tr><td class="tdtop fieldrequired">'.$langs->trans('Type').'</td><td>';
2462
2463 print '<div class="tagtable">'."\n";
2464
2465 // Standard invoice
2466 print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2467 $tmp = '<input type="radio" id="radio_standard" name="type" value="0"'.(GETPOSTINT('type') ? '' : 'checked').'> ';
2468 $desc = $form->textwithpicto($tmp.'<label for="radio_standard">'.$langs->trans("InvoiceStandardAsk").'</label>', $langs->transnoentities("InvoiceStandardDesc"), 1, 'help', '', 0, 3);
2469 print $desc;
2470 print '</div></div>';
2471
2472 if (empty($origin) || ($origin == 'order_supplier' && !empty($originid))) {
2473 // Deposit - Down payment
2474 if (!getDolGlobalString('INVOICE_DISABLE_DEPOSIT')) {
2475 print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2476 $tmp = '<input type="radio" id="radio_deposit" name="type" value="3"' . (GETPOSTINT('type') == 3 ? ' checked' : '') . '> ';
2477 print '<script type="text/javascript">
2478 jQuery(document).ready(function() {
2479 jQuery("#typestandardinvoice, #valuestandardinvoice").click(function() {
2480 jQuery("#radio_standard").prop("checked", true);
2481 });
2482 jQuery("#typedeposit, #valuedeposit").click(function() {
2483 jQuery("#radio_deposit").prop("checked", true);
2484 });
2485 jQuery("#typedeposit").change(function() {
2486 console.log("We change type of down payment");
2487 jQuery("#radio_deposit").prop("checked", true);
2488 setRadioForTypeOfInvoice();
2489 });
2490 jQuery("#radio_standard, #radio_deposit, #radio_replacement, #radio_template").change(function() {
2491 setRadioForTypeOfInvoice();
2492 });
2493 function setRadioForTypeOfInvoice() {
2494 console.log("Change radio");
2495 if (jQuery("#radio_deposit").prop("checked") && (jQuery("#typedeposit").val() == \'amount\' || jQuery("#typedeposit").val() == \'variable\')) {
2496 jQuery(".checkforselect").prop("disabled", true);
2497 jQuery(".checkforselect").prop("checked", false);
2498 } else {
2499 jQuery(".checkforselect").prop("disabled", false);
2500 jQuery(".checkforselect").prop("checked", true);
2501 }
2502 }
2503 });
2504 </script>';
2505
2506 $tmp = $tmp.'<label for="radio_deposit" >'.$langs->trans("InvoiceDeposit").'</label>';
2507 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
2508 $desc = $form->textwithpicto($tmp, $langs->transnoentities("InvoiceDepositDesc"), 1, 'help', '', 0, 3);
2509 print '<table class="nobordernopadding"><tr>';
2510 print '<td>';
2511 print $desc;
2512 print '</td>';
2513 if ($origin == 'order_supplier') {
2514 print '<td class="nowrap" style="padding-left: 15px">';
2515 $arraylist = array(
2516 'amount' => $langs->transnoentitiesnoconv('FixAmount', $langs->transnoentitiesnoconv('Deposit')),
2517 'variable' => $langs->transnoentitiesnoconv('VarAmountOneLine', $langs->transnoentitiesnoconv('Deposit')),
2518 'variablealllines' => $langs->transnoentitiesnoconv('VarAmountAllLines')
2519 );
2520 print $form->selectarray('typedeposit', $arraylist, GETPOST('typedeposit', 'aZ09'), 0, 0, 0, '', 1);
2521 print '</td>';
2522 print '<td class="nowrap" style="padding-left: 5px">';
2523 print '<span class="opacitymedium paddingleft">'.$langs->trans("AmountOrPercent").'</span><input type="text" id="valuedeposit" name="valuedeposit" class="width75 right" value="' . GETPOSTINT('valuedeposit') . '"/>';
2524 print '</td>';
2525 }
2526 print '</tr></table>';
2527
2528 print '</div></div>';
2529 }
2530 }
2531
2532 /* Not yet supported for supplier
2533 if ($societe->id > 0)
2534 {
2535 // Replacement
2536 if (empty($conf->global->INVOICE_DISABLE_REPLACEMENT))
2537 {
2538 // Type invoice
2539 $facids = $facturestatic->list_replacable_supplier_invoices($societe->id);
2540 if ($facids < 0) {
2541 dol_print_error($db, $facturestatic->error, $facturestatic->errors);
2542 exit();
2543 }
2544 $options = "";
2545 foreach ($facids as $facparam)
2546 {
2547 $options .= '<option value="' . $facparam ['id'] . '"';
2548 if ($facparam ['id'] == GETPOST('fac_replacement') {
2549 $options .= ' selected';
2550 }
2551 $options .= '>' . $facparam ['ref'];
2552 $options .= ' (' . $facturestatic->LibStatut(0, $facparam ['status']) . ')';
2553 $options .= '</option>';
2554 }
2555
2556 print '<!-- replacement line -->';
2557 print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2558 $tmp='<input type="radio" name="type" id="radio_replacement" value="1"' . (GETPOST('type') == 1 ? ' checked' : '');
2559 if (! $options) $tmp.=' disabled';
2560 $tmp.='> ';
2561 print '<script type="text/javascript">
2562 jQuery(document).ready(function() {
2563 jQuery("#fac_replacement").change(function() {
2564 jQuery("#radio_replacement").prop("checked", true);
2565 });
2566 });
2567 </script>';
2568 $text = $tmp.$langs->trans("InvoiceReplacementAsk") . ' ';
2569 $text .= '<select class="flat" name="fac_replacement" id="fac_replacement"';
2570 if (! $options)
2571 $text .= ' disabled';
2572 $text .= '>';
2573 if ($options) {
2574 $text .= '<option value="-1">&nbsp;</option>';
2575 $text .= $options;
2576 } else {
2577 $text .= '<option value="-1">' . $langs->trans("NoReplacableInvoice") . '</option>';
2578 }
2579 $text .= '</select>';
2580 $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceReplacementDesc"), 1, 'help', '', 0, 3);
2581 print $desc;
2582 print '</div></div>';
2583 }
2584 }
2585 else
2586 {
2587 print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2588 $tmp='<input type="radio" name="type" id="radio_replacement" value="0" disabled> ';
2589 $text = $tmp.$langs->trans("InvoiceReplacement") . ' ';
2590 $text.= '('.$langs->trans("YouMustCreateInvoiceFromSupplierThird").') ';
2591 $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceReplacementDesc"), 1, 'help', '', 0, 3);
2592 print $desc;
2593 print '</div></div>';
2594 }
2595 */
2596
2597 if (empty($origin)) {
2598 if (!empty($societe->id) && $societe->id > 0) {
2599 // Credit note
2600 if (!getDolGlobalString('INVOICE_DISABLE_CREDIT_NOTE')) {
2601 // Show link for credit note
2602 $facids = $facturestatic->list_qualified_avoir_supplier_invoices($societe->id);
2603 if ($facids < 0) {
2604 dol_print_error($db, $facturestatic->error, $facturestatic->errors);
2605 exit;
2606 }
2607 $optionsav = "";
2608 $newinvoice_static = new FactureFournisseur($db);
2609 foreach ($facids as $key => $valarray) {
2610 $newinvoice_static->id = $key;
2611 $newinvoice_static->ref = $valarray ['ref'];
2612 $newinvoice_static->status = $valarray ['status'];
2613 $newinvoice_static->statut = $valarray ['status'];
2614 $newinvoice_static->type = $valarray ['type'];
2615 $newinvoice_static->paid = $valarray ['paye'];
2616 $newinvoice_static->paye = $valarray ['paye'];
2617
2618 $optionsav .= '<option value="'.$key.'"';
2619 if ($key == GETPOSTINT('fac_avoir')) {
2620 $optionsav .= ' selected';
2621 }
2622 $optionsav .= '>';
2623 $optionsav .= $newinvoice_static->ref;
2624 $optionsav .= ' ('.$newinvoice_static->getLibStatut(1, $valarray ['paymentornot']).')';
2625 $optionsav .= '</option>';
2626 }
2627
2628 print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2629 $tmp = '<input type="radio" id="radio_creditnote" name="type" value="2"'.(GETPOST('type') == 2 ? ' checked' : '');
2630 if (!$optionsav && !getDolGlobalString('INVOICE_CREDIT_NOTE_STANDALONE')) {
2631 $tmp .= ' disabled';
2632 }
2633 $tmp .= '> ';
2634 // Show credit note options only if we checked credit note
2635 print '<script type="text/javascript">
2636 jQuery(document).ready(function() {
2637 if (! jQuery("#radio_creditnote").is(":checked"))
2638 {
2639 jQuery("#credit_note_options").hide();
2640 }
2641 jQuery("#radio_creditnote").click(function() {
2642 jQuery("#credit_note_options").show();
2643 });
2644 jQuery("#radio_standard, #radio_replacement, #radio_deposit").click(function() {
2645 jQuery("#credit_note_options").hide();
2646 });
2647 });
2648 </script>';
2649 $text = $tmp.'<label for="radio_creditnote">'.$langs->transnoentities("InvoiceAvoirAsk").'</label> ';
2650 // $text.='<input type="text" value="">';
2651 $text .= '<select class="flat valignmiddle" name="fac_avoir" id="fac_avoir"';
2652 if (!$optionsav) {
2653 $text .= ' disabled';
2654 }
2655 $text .= '>';
2656 if ($optionsav) {
2657 $text .= '<option value="-1"></option>';
2658 $text .= $optionsav;
2659 } else {
2660 $text .= '<option value="-1">'.$langs->trans("NoInvoiceToCorrect").'</option>';
2661 }
2662 $text .= '</select>';
2663 $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1, 'help', '', 0, 3);
2664 print $desc;
2665
2666 print '<div id="credit_note_options" class="clearboth">';
2667 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' : '').' /> ';
2668 print '<label for="invoiceAvoirWithLines">'.$langs->trans('invoiceAvoirWithLines')."</label>";
2669 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' : '').' /> ';
2670 print '<label for="invoiceAvoirWithPaymentRestAmount">'.$langs->trans('invoiceAvoirWithPaymentRestAmount')."</label>";
2671 print '</div>';
2672
2673 print '</div></div>';
2674 }
2675 } else {
2676 print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2677 if (!getDolGlobalString('INVOICE_CREDIT_NOTE_STANDALONE')) {
2678 $tmp = '<input type="radio" name="type" id="radio_creditnote" value="0" disabled> ';
2679 } else {
2680 $tmp = '<input type="radio" name="type" id="radio_creditnote" value="2"> ';
2681 }
2682 $text = $tmp.$langs->trans("InvoiceAvoir").' ';
2683 $text .= '<span class="opacitymedium">('.$langs->trans("YouMustCreateInvoiceFromSupplierThird").')</span> ';
2684 $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1, 'help', '', 0, 3);
2685 print $desc;
2686 print '</div></div>'."\n";
2687 }
2688 }
2689
2690 print '</div>';
2691
2692 print '</td></tr>';
2693
2694
2695 // Invoice Subtype
2696 if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED')) {
2697 print '<tr><td class="fieldrequired">'.$langs->trans('InvoiceSubtype').'</td><td colspan="2">';
2698 print $form->getSelectInvoiceSubtype(GETPOST('subtype'), 'subtype', 1, 0, '');
2699 print '</td></tr>';
2700 }
2701
2702 if (!empty($societe->id) && $societe->id > 0) {
2703 // Discounts for third party
2704 print '<tr><td>'.$langs->trans('Discounts').'</td><td>';
2705
2706 $thirdparty = $societe;
2707 $discount_type = 1;
2708 $backtopage = urlencode($_SERVER["PHP_SELF"].'?socid='.$societe->id.'&action='.$action.'&origin='.GETPOST('origin').'&originid='.GETPOST('originid'));
2709 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
2710
2711 print '</td></tr>';
2712 }
2713
2714 // Label
2715 print '<tr><td>'.$langs->trans('Label').'</td><td><input class="minwidth200" name="label" value="'.dol_escape_htmltag(GETPOST('label')).'" type="text"></td></tr>';
2716
2717 // Date invoice
2718 print '<tr><td class="fieldrequired">'.$langs->trans('DateInvoice').'</td><td>';
2719 print img_picto('', 'action', 'class="pictofixedwidth"');
2720 print $form->selectDate($dateinvoice, '', 0, 0, 0, "add", 1, 1);
2721 print '</td></tr>';
2722
2723 // Payment term
2724 print '<tr><td class="nowrap">'.$langs->trans('PaymentConditionsShort').'</td><td>';
2725 print img_picto('', 'payment', 'class="pictofixedwidth"');
2726 print $form->getSelectConditionsPaiements($cond_reglement_id, 'cond_reglement_id', -1, 1);
2727
2728 print '</td></tr>';
2729
2730 // Due date
2731 print '<tr><td>'.$langs->trans('DateMaxPayment').'</td><td>';
2732 print img_picto('', 'action', 'class="pictofixedwidth"');
2733 print $form->selectDate($datedue, 'ech', 0, 0, 0, "add", 1, 1);
2734 print '</td></tr>';
2735
2736 // Payment mode
2737 print '<tr><td>'.$langs->trans('PaymentMode').'</td><td>';
2738 print img_picto('', 'bank', 'class="pictofixedwidth"');
2739 $form->select_types_paiements($mode_reglement_id, 'mode_reglement_id', 'DBIT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx');
2740 print '</td></tr>';
2741
2742 // Bank Account
2743 if (isModEnabled("bank")) {
2744 print '<tr><td>'.$langs->trans('BankAccount').'</td><td>';
2745 // when bank account is empty (means not override by payment mode form a other object, like third-party), try to use default value
2746 print img_picto('', 'bank_account', 'class="pictofixedwidth"').$form->select_comptes($fk_account, 'fk_account', 0, '', 1, '', 0, 'maxwidth200 widthcentpercentminusx', 1);
2747 print '</td></tr>';
2748 }
2749
2750 // Project
2751 if (isModEnabled('project')) {
2752 $formproject = new FormProjets($db);
2753
2754 $langs->load('projects');
2755 print '<tr><td>'.$langs->trans('Project').'</td><td>';
2756 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');
2757 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>';
2758 print '</td></tr>';
2759 }
2760
2761 // Incoterms
2762 if (isModEnabled('incoterm')) {
2763 print '<tr>';
2764 print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), !empty($objectsrc->label_incoterms) ? $objectsrc->label_incoterms : '', 1).'</label></td>';
2765 print '<td colspan="3" class="maxwidthonsmartphone">';
2766 print img_picto('', 'incoterm', 'class="pictofixedwidth"');
2767 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 : ''));
2768 print '</td></tr>';
2769 }
2770
2771 // Vat reverse-charge by default
2772 if (getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
2773 require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
2774 print '<tr><td>' . $langs->trans('VATReverseCharge') . '</td><td>';
2775 // 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
2776 if (GETPOSTISSET('vat_reverse_charge')) { // Check if form was submitted previously
2777 $vat_reverse_charge = (GETPOST('vat_reverse_charge', 'alpha') == 'on' || GETPOST('vat_reverse_charge', 'alpha') == '1') ? 1 : 0;
2778 } elseif ($vat_reverse_charge == 1 || $societe->vat_reverse_charge == 1 || ($societe->country_code != 'FR' && isInEEC($societe) && !empty($societe->tva_intra))) {
2779 $vat_reverse_charge = 1;
2780 } else {
2781 $vat_reverse_charge = 0;
2782 }
2783
2784 print '<input type="checkbox" name="vat_reverse_charge"'. (!empty($vat_reverse_charge) ? ' checked ' : '') . '>';
2785 print '</td></tr>';
2786 }
2787
2788 // Multicurrency
2789 if (isModEnabled("multicurrency")) {
2790 print '<tr>';
2791 print '<td>'.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).'</td>';
2792 print '<td class="maxwidthonsmartphone">';
2793 print img_picto('', 'currency', 'class="pictofixedwidth"');
2794 $used_currency_code = $currency_code;
2795 if (!GETPOST('changecompany')) {
2796 $used_currency_code = GETPOSTISSET('multicurrency_code') ? GETPOST('multicurrency_code', 'alpha') : $currency_code;
2797 }
2798 print $form->selectMultiCurrency($used_currency_code, 'multicurrency_code');
2799 print '</td></tr>';
2800 }
2801
2802 // Help of substitution key
2803 $htmltext = '';
2804 if ($fac_recid > 0) {
2805 $dateexample = $dateinvoice;
2806 if (empty($dateexample)) {
2807 $dateexample = dol_now();
2808 }
2809 $substitutionarray = array(
2810 '__TOTAL_HT__' => $langs->trans("AmountHT").' ('.$langs->trans("Example").': '.price($exampletemplateinvoice->total_ht).')',
2811 '__TOTAL_TTC__' => $langs->trans("AmountTTC").' ('.$langs->trans("Example").': '.price($exampletemplateinvoice->total_ttc).')',
2812 '__INVOICE_PREVIOUS_MONTH__' => $langs->trans("PreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%m').')',
2813 '__INVOICE_MONTH__' => $langs->trans("MonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%m').')',
2814 '__INVOICE_NEXT_MONTH__' => $langs->trans("NextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%m').')',
2815 '__INVOICE_PREVIOUS_MONTH_TEXT__' => $langs->trans("TextPreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%B').')',
2816 '__INVOICE_MONTH_TEXT__' => $langs->trans("TextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%B').')',
2817 '__INVOICE_NEXT_MONTH_TEXT__' => $langs->trans("TextNextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%B').')',
2818 '__INVOICE_PREVIOUS_YEAR__' => $langs->trans("PreviousYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'y'), '%Y').')',
2819 '__INVOICE_YEAR__' => $langs->trans("YearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%Y').')',
2820 '__INVOICE_NEXT_YEAR__' => $langs->trans("NextYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'y'), '%Y').')'
2821 );
2822
2823 $htmltext = '<i>'.$langs->trans("FollowingConstantsWillBeSubstituted").':<br>';
2824 foreach ($substitutionarray as $key => $val) {
2825 $htmltext .= $key.' = '.$langs->trans($val).'<br>';
2826 }
2827 $htmltext .= '</i>';
2828 }
2829
2830 // Intracomm report
2831 if (isModEnabled('intracommreport')) {
2832 $langs->loadLangs(array("intracommreport"));
2833 print '<!-- If module intracomm on -->'."\n";
2834 print '<tr><td>'.$langs->trans('IntracommReportTransportMode').'</td><td>';
2835 $form->selectTransportMode(GETPOSTISSET('transport_mode_id') ? GETPOST('transport_mode_id') : $transport_mode_id, 'transport_mode_id');
2836 print '</td></tr>';
2837 }
2838
2839 if (empty($reshook)) {
2840 print $object->showOptionals($extrafields, 'create');
2841 }
2842
2843 // Public note
2844 print '<tr><td>'.$langs->trans('NotePublic').'</td>';
2845 print '<td>';
2846 $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%');
2847 print $doleditor->Create(1);
2848 print '</td>';
2849 // print '<td><textarea name="note" wrap="soft" cols="60" rows="'.ROWS_5.'"></textarea></td>';
2850 print '</tr>';
2851
2852 // Private note
2853 print '<tr><td>'.$langs->trans('NotePrivate').'</td>';
2854 print '<td>';
2855 $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%');
2856 print $doleditor->Create(1);
2857 print '</td>';
2858 // print '<td><textarea name="note" wrap="soft" cols="60" rows="'.ROWS_5.'"></textarea></td>';
2859 print '</tr>';
2860
2861
2862 if (!empty($objectsrc) && is_object($objectsrc)) {
2863 print "\n<!-- ".$classname." info -->";
2864 print "\n";
2865 print '<input type="hidden" name="amount" value="'.$objectsrc->total_ht.'">'."\n";
2866 print '<input type="hidden" name="total" value="'.$objectsrc->total_ttc.'">'."\n";
2867 print '<input type="hidden" name="tva" value="'.$objectsrc->total_tva.'">'."\n";
2868 print '<input type="hidden" name="origin" value="'.$objectsrc->element.'">';
2869 print '<input type="hidden" name="originid" value="'.$objectsrc->id.'">';
2870
2871 $txt = $langs->trans($classname);
2872 if ($classname == 'CommandeFournisseur') {
2873 $langs->load('orders');
2874 $txt = $langs->trans("SupplierOrder");
2875 }
2876 print '<tr><td>'.$txt.'</td><td>'.$objectsrc->getNomUrl(1);
2877 // We check if Origin document (id and type is known) has already at least one invoice attached to it
2878 $objectsrc->fetchObjectLinked($originid, $origin, null, 'invoice_supplier');
2879
2880 $invoice_supplier = $objectsrc->linkedObjects['invoice_supplier'];
2881 '@phan-var-force null|FactureFournisseur[] $invoice_supplier';
2882
2883 // count function need a array as argument (Note: the array must implement Countable too)
2884 if (is_array($invoice_supplier)) {
2885 $cntinvoice = count($invoice_supplier);
2886
2887 if ($cntinvoice >= 1) {
2888 setEventMessages('WarningBillExist', null, 'warnings');
2889 echo ' ('.$langs->trans('LatestRelatedBill').end($invoice_supplier)->getNomUrl(1).')';
2890 }
2891 }
2892
2893 print '</td></tr>';
2894 print '<tr><td>'.$langs->trans('AmountHT').'</td><td>'.price($objectsrc->total_ht).'</td></tr>';
2895 print '<tr><td>'.$langs->trans('AmountVAT').'</td><td>'.price($objectsrc->total_tva)."</td></tr>";
2896 if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) { //Localtax1
2897 print '<tr><td>'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax1)."</td></tr>";
2898 }
2899
2900 if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) { //Localtax2
2901 print '<tr><td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax2)."</td></tr>";
2902 }
2903 print '<tr><td>'.$langs->trans('AmountTTC').'</td><td>'.price($objectsrc->total_ttc)."</td></tr>";
2904
2905 if (isModEnabled("multicurrency")) {
2906 print '<tr><td>'.$langs->trans('MulticurrencyAmountHT').'</td><td>'.price($objectsrc->multicurrency_total_ht).'</td></tr>';
2907 print '<tr><td>'.$langs->trans('MulticurrencyAmountVAT').'</td><td>'.price($objectsrc->multicurrency_total_tva)."</td></tr>";
2908 print '<tr><td>'.$langs->trans('MulticurrencyAmountTTC').'</td><td>'.price($objectsrc->multicurrency_total_ttc)."</td></tr>";
2909 }
2910 }
2911
2912 // Other options
2913 $parameters = array();
2914 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2915 print $hookmanager->resPrint;
2916
2917
2918 print "</table>\n";
2919 }
2920
2921 print dol_get_fiche_end();
2922
2923 print $form->buttonsSaveCancel("CreateDraft");
2924
2925 // Show origin lines
2926 if (!empty($objectsrc) && is_object($objectsrc)) {
2927 print '<br>';
2928
2929 $title = $langs->trans('ProductsAndServices');
2930 print load_fiche_titre($title);
2931
2932 print '<div class="div-table-responsive-no-min">';
2933 print '<table class="noborder centpercent">';
2934
2935 $objectsrc->printOriginLinesList('', $selectedLines);
2936
2937 print '</table>';
2938 print '</div>';
2939 }
2940
2941 print "</form>\n";
2942} else {
2943 if ($id > 0 || !empty($ref)) {
2944 //
2945 // View or edit mode
2946 //
2947 $now = dol_now();
2948
2949 $productstatic = new Product($db);
2950
2951 $result = $object->fetch($id, $ref);
2952 if ($result <= 0) {
2953 $langs->load("errors");
2954 print $langs->trans("ErrorRecordNotFound");
2955 llxFooter();
2956 $db->close();
2957 exit;
2958 }
2959
2960 $result = $object->fetch_thirdparty();
2961 if ($result < 0) {
2962 dol_print_error($db, $object->error, $object->errors);
2963 exit;
2964 }
2965
2966 $societe = $object->thirdparty;
2967
2968 $totalpaid = $object->getSommePaiement();
2969 $totalcreditnotes = $object->getSumCreditNotesUsed();
2970 $totaldeposits = $object->getSumDepositsUsed();
2971 // print "totalpaid=".$totalpaid." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits."
2972 // selleruserrevenuestamp=".$selleruserevenustamp;
2973
2974 // We can also use bcadd to avoid pb with floating points
2975 // For example print 239.2 - 229.3 - 9.9; does not return 0.
2976 // $resteapayer=bcadd($object->total_ttc,$totalpaid,$conf->global->MAIN_MAX_DECIMALS_TOT);
2977 // $resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT);
2978 $resteapayer = price2num($object->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits, 'MT');
2979
2980 // Multicurrency
2981 $multicurrency_resteapayer = 0;
2982 if (isModEnabled("multicurrency")) {
2983 $multicurrency_totalpaid = $object->getSommePaiement(1);
2984 $multicurrency_totalcreditnotes = $object->getSumCreditNotesUsed(1);
2985 $multicurrency_totaldeposits = $object->getSumDepositsUsed(1);
2986 $multicurrency_resteapayer = price2num($object->multicurrency_total_ttc - $multicurrency_totalpaid - $multicurrency_totalcreditnotes - $multicurrency_totaldeposits, 'MT');
2987 // Code to fix case of corrupted data
2988 // 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
2989 // 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)
2990 if ($resteapayer == 0 && $multicurrency_resteapayer != 0 && $object->multicurrency_code != $conf->currency) {
2991 $resteapayer = price2num((float) $multicurrency_resteapayer / $object->multicurrency_tx, 'MT');
2992 }
2993 }
2994
2995 if ($object->paid) {
2996 $resteapayer = 0;
2997 }
2998 $resteapayeraffiche = $resteapayer;
2999
3000 if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) { // Never use this
3001 $filterabsolutediscount = "fk_invoice_supplier_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
3002 $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
3003 } else {
3004 $filterabsolutediscount = "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')";
3005 $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')";
3006 }
3007
3008 $absolute_discount = $societe->getAvailableDiscounts(null, $filterabsolutediscount, 0, 1);
3009 $absolute_creditnote = $societe->getAvailableDiscounts(null, $filtercreditnote, 0, 1);
3010 $absolute_discount = price2num($absolute_discount, 'MT');
3011 $absolute_creditnote = price2num($absolute_creditnote, 'MT');
3012
3013 // View card
3014
3015 $objectidnext = $object->getIdReplacingInvoice();
3016
3018 $titre = $langs->trans('SupplierInvoice');
3019
3020 print dol_get_fiche_head($head, 'card', $titre, -1, 'supplier_invoice', 0, '', '', 0, '', 1);
3021
3022 $formconfirm = '';
3023
3024 // Confirmation de la conversion de l'avoir en reduc
3025 if ($action == 'converttoreduc') {
3026 $type_fac = '';
3028 $type_fac = 'ExcessPaid';
3029 } elseif ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
3030 $type_fac = 'CreditNote';
3031 } elseif ($object->type == FactureFournisseur::TYPE_DEPOSIT) {
3032 $type_fac = 'Deposit';
3033 }
3034 $text = $langs->trans('ConfirmConvertToReducSupplier', strtolower($langs->transnoentities($type_fac)));
3035 $text .= '<br>'.$langs->trans('ConfirmConvertToReducSupplier2');
3036 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id, $langs->trans('ConvertToReduc'), $text, 'confirm_converttoreduc', '', "yes", 2);
3037 }
3038
3039 // Clone confirmation
3040 if ($action == 'clone') {
3041 // Create an array for form
3042 $formquestion = array(
3043 array('type' => 'text', 'name' => 'newsupplierref', 'label' => $langs->trans("RefSupplierBill"), 'value' => $langs->trans("CopyOf").' '.$object->ref_supplier),
3044 array('type' => 'date', 'name' => 'newdate', 'label' => $langs->trans("Date"), 'value' => dol_now())
3045 );
3046 // Ask confirmation to clone
3047 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneInvoice', $object->ref), 'confirm_clone', $formquestion, 'yes', 1, 250);
3048 }
3049
3050 // Confirmation of validation
3051 if ($action == 'valid') {
3052 // We check if number is temporary number
3053 if (preg_match('/^[\‍(]?PROV/i', $object->ref) || empty($object->ref)) {
3054 // empty should not happened, but when it occurs, the test save life
3055 $numref = $object->getNextNumRef($societe);
3056 } else {
3057 $numref = $object->ref;
3058 }
3059
3060 if ($numref < 0) {
3061 setEventMessages($object->error, $object->errors, 'errors');
3062 $action = '';
3063 } else {
3064 $text = $langs->trans('ConfirmValidateBill', $numref);
3065 /*if (isModEnabled('notification'))
3066 {
3067 require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php';
3068 $notify=new Notify($db);
3069 $text.='<br>';
3070 $text.=$notify->confirmMessage('BILL_SUPPLIER_VALIDATE',$object->socid, $object);
3071 }*/
3072 $formquestion = array();
3073
3074 $qualified_for_stock_change = 0;
3075 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
3076 $qualified_for_stock_change = $object->hasProductsOrServices(2);
3077 } else {
3078 $qualified_for_stock_change = $object->hasProductsOrServices(1);
3079 }
3080
3081 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') && $qualified_for_stock_change) {
3082 $langs->load("stocks");
3083 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
3084 $formproduct = new FormProduct($db);
3085 $warehouse = new Entrepot($db);
3086 $warehouse_array = $warehouse->list_array();
3087 if (count($warehouse_array) == 1) {
3088 $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("WarehouseForStockDecrease", current($warehouse_array)) : $langs->trans("WarehouseForStockIncrease", current($warehouse_array));
3089 $value = '<input type="hidden" id="idwarehouse" name="idwarehouse" value="'.key($warehouse_array).'">';
3090 } else {
3091 $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("SelectWarehouseForStockDecrease") : $langs->trans("SelectWarehouseForStockIncrease");
3092 $value = $formproduct->selectWarehouses(GETPOST('idwarehouse') ? GETPOST('idwarehouse') : 'ifone', 'idwarehouse', '', 1);
3093 }
3094 $formquestion = array(
3095 array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $value)
3096 );
3097 }
3098
3099 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateBill'), $text, 'confirm_valid', $formquestion, 1, 1);
3100 }
3101 }
3102
3103 // Confirmation edit (back to draft)
3104 if ($action == 'edit') {
3105 $formquestion = array();
3106
3107 $qualified_for_stock_change = 0;
3108 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
3109 $qualified_for_stock_change = $object->hasProductsOrServices(2);
3110 } else {
3111 $qualified_for_stock_change = $object->hasProductsOrServices(1);
3112 }
3113 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') && $qualified_for_stock_change) {
3114 $langs->load("stocks");
3115 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
3116 $formproduct = new FormProduct($db);
3117 $warehouse = new Entrepot($db);
3118 $warehouse_array = $warehouse->list_array();
3119 if (count($warehouse_array) == 1) {
3120 $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("WarehouseForStockIncrease", current($warehouse_array)) : $langs->trans("WarehouseForStockDecrease", current($warehouse_array));
3121 $value = '<input type="hidden" id="idwarehouse" name="idwarehouse" value="'.key($warehouse_array).'">';
3122 } else {
3123 $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("SelectWarehouseForStockIncrease") : $langs->trans("SelectWarehouseForStockDecrease");
3124 $value = $formproduct->selectWarehouses(GETPOST('idwarehouse') ? GETPOST('idwarehouse') : 'ifone', 'idwarehouse', '', 1);
3125 }
3126 $formquestion = array(
3127 array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $value)
3128 );
3129 }
3130 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('UnvalidateBill'), $langs->trans('ConfirmUnvalidateBill', $object->ref), 'confirm_edit', $formquestion, 1, 1);
3131 }
3132
3133 // Confirmation set paid
3134 if ($action == 'paid' && ($resteapayer <= 0 || (getDolGlobalString('SUPPLIER_INVOICE_CAN_SET_PAID_EVEN_IF_PARTIALLY_PAID') && $resteapayer == $object->total_ttc))) {
3135 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidBill', $object->ref), 'confirm_paid', '', 0, 1);
3136 }
3137
3138 if ($action == 'paid' && $resteapayer > 0 && (!getDolGlobalString('SUPPLIER_INVOICE_CAN_SET_PAID_EVEN_IF_PARTIALLY_PAID') || $resteapayer != $object->total_ttc)) {
3139 $close = array();
3140 // Code
3141 $i = 0;
3142 $close[$i]['code'] = 'discount_vat'; // escompte
3143 $i++;
3144 $close[$i]['code'] = 'badsupplier';
3145 $i++;
3146 $close[$i]['code'] = 'other';
3147 $i++;
3148 // Help
3149 $i = 0;
3150 $close[$i]['label'] = $langs->trans("HelpEscompte").'<br><br>'.$langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");
3151 $i++;
3152 $close[$i]['label'] = $langs->trans("ConfirmClassifyPaidPartiallyReasonBadSupplierDesc");
3153 $i++;
3154 $close[$i]['label'] = $langs->trans("Other");
3155 $i++;
3156 // Text
3157 $i = 0;
3158 $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscount", $resteapayer, $langs->trans("Currency".$conf->currency)), $close[$i]['label'], 1);
3159 $i++;
3160 $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer", $resteapayer, $langs->trans("Currency".$conf->currency)), $close[$i]['label'], 1);
3161 $i++;
3162 $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("Other"), $close[$i]['label'], 1);
3163 $i++;
3164 // arrayreasons[code]=reason
3165 $arrayreasons = array();
3166 foreach ($close as $key => $val) {
3167 $arrayreasons[$close[$key]['code']] = $close[$key]['reason'];
3168 }
3169
3170 // Create a form table
3171 $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'));
3172 // Incomplete payment. We ask if the reason is discount or other
3173 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidPartially', $object->ref), 'confirm_paid_partially', $formquestion, "yes", 1, 310);
3174 }
3175
3176 // Confirmation of the abandoned classification
3177 if ($action == 'canceled') {
3178 // Code
3179 $close[1]['code'] = 'badsupplier';
3180 $close[2]['code'] = 'abandon';
3181 // Help
3182 $close[1]['label'] = $langs->trans("ConfirmClassifyPaidPartiallyReasonBadSupplierDesc");
3183 $close[2]['label'] = $langs->trans("ConfirmClassifyAbandonReasonOtherDesc");
3184 // Text
3185 $close[1]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadSupplier", $object->ref), $close[1]['label'], 1);
3186 $close[2]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"), $close[2]['label'], 1);
3187 // arrayreasons
3188 $arrayreasons[$close[1]['code']] = $close[1]['reason'];
3189 $arrayreasons[$close[2]['code']] = $close[2]['reason'];
3190
3191 // Create a form table
3192 $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'));
3193
3194 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('CancelBill'), $langs->trans('ConfirmCancelBill', $object->ref), 'confirm_canceled', $formquestion, "yes", 1, 280);
3195 }
3196
3197 // Confirmation de la suppression de la facture fournisseur
3198 if ($action == 'delete') {
3199 $formquestion = array();
3200
3201 $qualified_for_stock_change = 0;
3202 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
3203 $qualified_for_stock_change = $object->hasProductsOrServices(2);
3204 } else {
3205 $qualified_for_stock_change = $object->hasProductsOrServices(1);
3206 }
3207
3208 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') && $qualified_for_stock_change) {
3209 $langs->load("stocks");
3210 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
3211 $formproduct = new FormProduct($db);
3212 $warehouse = new Entrepot($db);
3213 $warehouse_array = $warehouse->list_array();
3214
3215 $selectwarehouse = '<span class="questionrevertstock hidden">';
3216 if (count($warehouse_array) == 1) {
3217 $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("WarehouseForStockIncrease", current($warehouse_array)) : $langs->trans("WarehouseForStockDecrease", current($warehouse_array));
3218 $selectwarehouse .= '<input type="hidden" id="idwarehouse" name="idwarehouse" value="'.key($warehouse_array).'">';
3219 } else {
3220 $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("SelectWarehouseForStockIncrease") : $langs->trans("SelectWarehouseForStockDecrease");
3221 $selectwarehouse .= $formproduct->selectWarehouses(GETPOST('idwarehouse') ? GETPOST('idwarehouse') : 'ifone', 'idwarehouse', '', 1);
3222 }
3223 $selectwarehouse .= '</span>';
3224
3225 $selectyesno = array(0 => $langs->trans('No'), 1 => $langs->trans('Yes'));
3226
3227 print '<script type="text/javascript">
3228 $(document).ready(function() {
3229 $("#revertstock").change(function() {
3230 if(this.value > 0) {
3231 $(".questionrevertstock").removeClass("hidden");
3232 } else {
3233 $(".questionrevertstock").addClass("hidden");
3234 }
3235 });
3236 });
3237 </script>';
3238
3239 $formquestion = array(
3240 array('type' => 'select', 'name' => 'revertstock', 'label' => $langs->trans("RevertProductsToStock"), 'select_show_empty' => 0, 'values' => $selectyesno),
3241 array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $selectwarehouse, 'tdclass' => 'questionrevertstock hidden')
3242 );
3243 }
3244
3245 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteBill'), $langs->trans('ConfirmDeleteBill'), 'confirm_delete', $formquestion, 1, 1);
3246 }
3247 if ($action == 'deletepayment') {
3248 $payment_id = GETPOST('paiement_id');
3249 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&paiement_id='.$payment_id, $langs->trans('DeletePayment'), $langs->trans('ConfirmDeletePayment'), 'confirm_delete_paiement', '', 0, 1);
3250 }
3251
3252 // Confirmation to delete line
3253 if ($action == 'ask_deleteline') {
3254 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1);
3255 }
3256
3257 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
3258 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
3259 if (empty($reshook)) {
3260 $formconfirm .= $hookmanager->resPrint;
3261 } elseif ($reshook > 0) {
3262 $formconfirm = $hookmanager->resPrint;
3263 }
3264
3265 // Print form confirm
3266 print $formconfirm;
3267
3268
3269 // Supplier invoice card
3270 $linkback = '<a href="'.DOL_URL_ROOT.'/fourn/facture/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
3271
3272 $morehtmlref = '<div class="refidno">';
3273 // Ref supplier
3274 $morehtmlref .= $form->editfieldkey("RefSupplierBill", 'ref_supplier', $object->ref_supplier, $object, $usercancreate, 'string', '', 0, 1);
3275 $morehtmlref .= $form->editfieldval("RefSupplierBill", 'ref_supplier', $object->ref_supplier, $object, $usercancreate, 'string', '', null, null, '', 1);
3276 // Thirdparty
3277 $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1, 'supplier');
3278 if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
3279 $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>';
3280 }
3281 // Project
3282 if (isModEnabled('project')) {
3283 $langs->load("projects");
3284 $morehtmlref .= '<br>';
3285 if ($permissiontoadd) {
3286 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
3287 if ($action != 'classify') {
3288 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.((int) $object->id).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
3289 }
3290 $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');
3291 } else {
3292 if (!empty($object->fk_project)) {
3293 $proj = new Project($db);
3294 $proj->fetch($object->fk_project);
3295 $morehtmlref .= $proj->getNomUrl(1);
3296 if ($proj->title) {
3297 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
3298 }
3299 }
3300 }
3301 }
3302 $morehtmlref .= '</div>';
3303
3304 $object->totalpaid = $totalpaid; // To give a chance to dol_banner_tab to use already paid amount to show correct status
3305
3306 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
3307
3308 // Call Hook tabContentViewSupplierInvoice
3309 $parameters = array();
3310 // Note that $action and $object may be modified by hook
3311 $reshook = $hookmanager->executeHooks('tabContentViewSupplierInvoice', $parameters, $object, $action);
3312 if (empty($reshook)) {
3313 print '<div class="fichecenter">';
3314 print '<div class="fichehalfleft">';
3315 print '<div class="underbanner clearboth"></div>';
3316
3317 print '<table class="border tableforfield centpercent">';
3318
3319 // Type
3320 print '<tr><td class="titlefield">'.$langs->trans('Type').'</td><td>';
3321 print '<span class="badgeneutral">';
3322 print $object->getLibType();
3323 print '</span>';
3324 if ($object->subtype > 0) {
3325 print ' '.$object->getSubtypeLabel('facture_fourn');
3326 }
3328 $facreplaced = new FactureFournisseur($db);
3329 $facreplaced->fetch($object->fk_facture_source);
3330 print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("ReplaceInvoice", $facreplaced->getNomUrl(1)).'</span>';
3331 }
3333 if ($object->fk_facture_source > 0) {
3334 $facusing = new FactureFournisseur($db);
3335 $facusing->fetch($object->fk_facture_source);
3336 print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("CorrectInvoice", $facusing->getNomUrl(1)).'</span>';
3337 } else {
3338 $langs->load("errors");
3339 print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("WarningCorrectedInvoiceNotFound").'</span>';
3340 }
3341 }
3342
3343 $facidavoir = $object->getListIdAvoirFromInvoice();
3344 if (count($facidavoir) > 0) {
3345 $invoicecredits = array();
3346 foreach ($facidavoir as $id) {
3347 $facavoir = new FactureFournisseur($db);
3348 $facavoir->fetch($id);
3349 $invoicecredits[] = $facavoir->getNomUrl(1);
3350 }
3351 print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("InvoiceHasAvoir") . (count($invoicecredits) ? ' ' : '') . implode(',', $invoicecredits);
3352 print '</span>';
3353 }
3354 if (isset($objectidnext) && $objectidnext > 0) {
3355 $facthatreplace = new FactureFournisseur($db);
3356
3357 $facthatreplace->fetch($objectidnext);
3358 print ' <span class="opacitymediumbycolor paddingleft">'.str_replace('{s1}', $facthatreplace->getNomUrl(1), $langs->transnoentities("ReplacedByInvoice", '{s1}')).'</span>';
3359 }
3361 $discount = new DiscountAbsolute($db);
3362 $result = $discount->fetch(0, 0, $object->id);
3363 if ($result > 0) {
3364 print ' <span class="opacitymediumbycolor paddingleft">';
3365 $s = $langs->trans("CreditNoteConvertedIntoDiscount", '{s1}', '{s2}');
3366 $s = str_replace('{s1}', $object->getLibType(1), $s);
3367 $s = str_replace('{s2}', $discount->getNomUrl(1, 'discount'), $s);
3368 print $s;
3369 print '</span><br>';
3370 }
3371 }
3372
3373 if ($object->fk_fac_rec_source > 0) {
3374 $tmptemplate = new FactureFournisseurRec($db);
3375 $result = $tmptemplate->fetch($object->fk_fac_rec_source);
3376 if ($result > 0) {
3377 print ' <span class="opacitymediumbycolor paddingleft">';
3378 $link = '<a href="'.DOL_URL_ROOT.'/fourn/facture/card-rec.php?facid='.$tmptemplate->id.'">'.dol_escape_htmltag($tmptemplate->title).'</a>';
3379 $s = $langs->transnoentities("GeneratedFromSupplierTemplate", $link);
3380
3381 print $s;
3382 print '</span>';
3383 }
3384 }
3385 print '</td></tr>';
3386
3387
3388 // Relative and absolute discounts
3389 print '<!-- Discounts -->'."\n";
3390 print '<tr><td>'.$langs->trans('DiscountStillRemaining');
3391 print '</td><td>';
3392
3393 $thirdparty = $societe;
3394 $discount_type = 1;
3395 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
3396
3397 print '</td></tr>';
3398
3399 // Label
3400 print '<tr>';
3401 print '<td>'.$form->editfieldkey("Label", 'label', $object->label, $object, $usercancreate).'</td>';
3402 print '<td>'.$form->editfieldval("Label", 'label', $object->label, $object, $usercancreate).'</td>';
3403 print '</tr>';
3404
3405 //$form_permission = ($object->status < FactureFournisseur::STATUS_CLOSED) && $usercancreate && ($object->getSommePaiement() <= 0);
3406 $form_permission = ($object->status < FactureFournisseur::STATUS_CLOSED) && $usercancreate;
3407
3408 // Date
3409 print '<tr><td>';
3410 print $form->editfieldkey("DateInvoice", 'datef', $object->date, $object, $form_permission, 'datepicker');
3411 print '</td><td colspan="3">';
3412 print $form->editfieldval("Date", 'datef', $object->date, $object, $form_permission, 'datepicker');
3413 print '</td>';
3414
3415 // Default terms of the settlement
3416 $langs->load('bills');
3417 print '<tr><td class="nowrap">';
3418 print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
3419 print $langs->trans('PaymentConditions');
3420 print '<td>';
3421 if ($action != 'editconditions' && $form_permission) {
3422 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>';
3423 }
3424 print '</tr></table>';
3425 print '</td><td>';
3426 if ($action == 'editconditions') {
3427 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'cond_reglement_id');
3428 } else {
3429 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'none');
3430 }
3431 print "</td>";
3432 print '</tr>';
3433
3434 // Due date
3435 print '<tr><td>';
3436 print $form->editfieldkey("DateMaxPayment", 'date_lim_reglement', $object->date_echeance, $object, $form_permission, 'datepicker');
3437 print '</td><td>';
3438 print $form->editfieldval("DateMaxPayment", 'date_lim_reglement', $object->date_echeance, $object, $form_permission, 'datepicker');
3439 if ($action != 'editdate_lim_reglement' && $object->hasDelay()) {
3440 print img_warning($langs->trans('Late'));
3441 }
3442 print '</td>';
3443
3444 // Mode of payment
3445 $langs->load('bills');
3446 print '<tr><td class="nowrap">';
3447 print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
3448 print $langs->trans('PaymentMode');
3449 print '</td>';
3450 if ($action != 'editmode' && $form_permission) {
3451 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>';
3452 }
3453 print '</tr></table>';
3454 print '</td><td>';
3455 if ($action == 'editmode') {
3456 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->mode_reglement_id, 'mode_reglement_id', 'DBIT', 1, 1);
3457 } else {
3458 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->mode_reglement_id, 'none');
3459 }
3460 print '</td></tr>';
3461
3462 // Bank Account
3463 if (isModEnabled("bank")) {
3464 print '<tr><td class="nowrap">';
3465 print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
3466 print $langs->trans('BankAccount');
3467 print '<td>';
3468 if ($action != 'editbankaccount' && $usercancreate) {
3469 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>';
3470 }
3471 print '</tr></table>';
3472 print '</td><td>';
3473 if ($action == 'editbankaccount') {
3474 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'fk_account', 1);
3475 } else {
3476 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none');
3477 }
3478 print "</td>";
3479 print '</tr>';
3480 }
3481
3482 // Vat reverse-charge by default
3483 if (getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
3484 print '<tr><td class="nowrap">';
3485 print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
3486 print $langs->trans('VATReverseCharge');
3487 print '<td>';
3488 if ($action != 'editvatreversecharge' && $usercancreate) {
3489 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>';
3490 }
3491 print '</tr></table>';
3492 print '</td><td>';
3493 if ($action == 'editvatreversecharge') {
3494 print '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
3495 print '<input type="hidden" name="action" value="setvatreversecharge">';
3496 print '<input type="hidden" name="token" value="'.newToken().'">';
3497
3498 print '<input type="checkbox" name="vat_reverse_charge"' . ($object->vat_reverse_charge == '1' ? ' checked ' : '') . '>';
3499
3500 print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
3501 print '</form>';
3502 } else {
3503 print '<input type="checkbox" name="vat_reverse_charge"'. ($object->vat_reverse_charge == '1' ? ' checked ' : '') . ' disabled>';
3504 }
3505 print '</td></tr>';
3506 }
3507
3508 // Incoterms
3509 if (isModEnabled('incoterm')) {
3510 print '<tr><td>';
3511 print '<table width="100%" class="nobordernopadding"><tr><td>';
3512 print $langs->trans('IncotermLabel');
3513 print '<td><td class="right">';
3514 if ($usercancreate) {
3515 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/fourn/facture/card.php?facid='.$object->id.'&action=editincoterm&token='.newToken().'">'.img_edit().'</a>';
3516 } else {
3517 print '&nbsp;';
3518 }
3519 print '</td></tr></table>';
3520 print '</td>';
3521 print '<td>';
3522 if ($action != 'editincoterm') {
3523 print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1);
3524 } else {
3525 print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id);
3526 }
3527 print '</td></tr>';
3528 }
3529
3530 // Intracomm report
3531 if (isModEnabled('intracommreport')) {
3532 $langs->loadLangs(array("intracommreport"));
3533 print '<!-- If module intracomm on -->'."\n";
3534 print '<tr><td>';
3535 print '<table class="nobordernopadding centpercent"><tr><td>';
3536 print $langs->trans('IntracommReportTransportMode');
3537 print '</td>';
3538 if ($action != 'edittransportmode' && ($user->hasRight("fournisseur", "facture", "creer") || $user->hasRight("supplier_invoice", "creer"))) {
3539 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=edittransportmode&token='.newToken().'&id='.$object->id.'">'.img_edit().'</a></td>';
3540 }
3541 print '</tr></table>';
3542 print '</td>';
3543 print '<td>';
3544 if ($action == 'edittransportmode') {
3545 $form->formSelectTransportMode($_SERVER['PHP_SELF'].'?id='.$object->id, $object->transport_mode_id, 'transport_mode_id', 1, 1);
3546 } else {
3547 $form->formSelectTransportMode($_SERVER['PHP_SELF'].'?id='.$object->id, $object->transport_mode_id, 'none');
3548 }
3549 print '</td></tr>';
3550 }
3551
3552 // Other attributes
3553 $cols = 2;
3554 if ($object->status != $object::STATUS_DRAFT) {
3555 $disableedit = 1;
3556 $disableremove = 1;
3557 }
3558 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
3559
3560 print '</table>';
3561 print '</div>';
3562
3563 print '<div class="fichehalfright">';
3564 print '<div class="underbanner clearboth"></div>';
3565
3566 print '<table class="border tableforfield centpercent">';
3567
3568 include DOL_DOCUMENT_ROOT.'/core/tpl/object_currency_amount.tpl.php';
3569
3570 print '<tr>';
3571 print '<td class="titlefieldmiddle">' . $langs->trans('AmountHT') . '</td>';
3572 print '<td class="nowrap amountcard right">' . price($object->total_ht, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
3573 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
3574 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ht, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
3575 }
3576 print '</tr>';
3577
3578 print '<tr>';
3579 print '<td>' . $langs->trans('AmountVAT') . '</td>';
3580 print '<td class="nowrap amountcard right">';
3581 if (GETPOST('calculationrule')) {
3582 $calculationrule = GETPOST('calculationrule', 'alpha');
3583 } else {
3584 $calculationrule = (!getDolGlobalString('MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND') ? 'totalofround' : 'roundoftotal');
3585 }
3586 if ($calculationrule == 'totalofround') {
3587 $calculationrulenum = 1;
3588 } else {
3589 $calculationrulenum = 2;
3590 }
3591 // Show link for "recalculate"
3592 if ($object->getVentilExportCompta() == 0) {
3593 $s = '<span class="hideonsmartphone opacitymedium">' . $langs->trans("ReCalculate") . ' </span>';
3594 $s .= '<a href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=calculate&token='.newToken().'&calculationrule=totalofround">' . $langs->trans("Mode1") . '</a>';
3595 $s .= ' / ';
3596 $s .= '<a href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=calculate&token='.newToken().'&calculationrule=roundoftotal">' . $langs->trans("Mode2") . '</a>';
3597 print '<div class="inline-block">';
3598 print $form->textwithtooltip($s, $langs->trans("CalculationRuleDesc", $calculationrulenum) . '<br>' . $langs->trans("CalculationRuleDescSupplier"), 2, 1, img_picto('', 'help'), '', 3, '', 0, 'recalculate');
3599 print '&nbsp; &nbsp; &nbsp; &nbsp;';
3600 print '</div>';
3601 }
3602 print '<span class="nowraponall">'.price($object->total_tva, 1, $langs, 0, -1, -1, $conf->currency).'</span>';
3603 print '</td>';
3604 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
3605 print '<td class="nowraponall amountcard right">' . price($object->multicurrency_total_tva, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
3606 }
3607 print '</tr>';
3608
3609 if ($societe->localtax1_assuj == "1") { //Localtax1
3610 print '<tr>';
3611 print '<td>' . $langs->transcountry("AmountLT1", $societe->country_code) . '</td>';
3612 print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 1, $langs, 0, -1, -1, $conf->currency) . '</td>';
3613 print '</tr>';
3614 }
3615 if ($societe->localtax2_assuj == "1") { //Localtax2
3616 print '<tr>';
3617 print '<td>' . $langs->transcountry("AmountLT2", $societe->country_code) . '</td>';
3618 print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 1, $langs, 0, -1, -1, $conf->currency) . '</td>';
3619 print '</tr>';
3620 }
3621
3622 print '<tr>';
3623 print '<td>' . $langs->trans('AmountTTC') . '</td>';
3624 print '<td class="nowrap amountcard right">' . price($object->total_ttc, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
3625 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
3626 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ttc, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
3627 }
3628 print '</tr>';
3629
3630 print '</table>';
3631
3632
3633 // List of payments already done
3634
3635 $totalpaid = 0;
3636
3637 $sign = 1;
3639 $sign = - 1;
3640 }
3641
3642 $nbrows = 9;
3643 $nbcols = 3;
3644 if (isModEnabled('project')) {
3645 $nbrows++;
3646 }
3647 if (isModEnabled("bank")) {
3648 $nbrows++;
3649 $nbcols++;
3650 }
3651 if (isModEnabled('incoterm')) {
3652 $nbrows++;
3653 }
3654 if (isModEnabled("multicurrency")) {
3655 $nbrows += 5;
3656 }
3657
3658 // Local taxes
3659 if ($societe->localtax1_assuj == "1") {
3660 $nbrows++;
3661 }
3662 if ($societe->localtax2_assuj == "1") {
3663 $nbrows++;
3664 }
3665
3666 $sql = 'SELECT p.datep as dp, p.ref, p.num_paiement as num_payment, p.rowid, p.fk_bank,';
3667 $sql .= ' c.id as payment_type, c.code as payment_code,';
3668 $sql .= ' pf.amount,';
3669 $sql .= ' ba.rowid as baid, ba.ref as baref, ba.label, ba.number as banumber, ba.account_number, ba.fk_accountancy_journal';
3670 $sql .= ' FROM '.MAIN_DB_PREFIX.'paiementfourn as p';
3671 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid';
3672 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid';
3673 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id';
3674 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf ON pf.fk_paiementfourn = p.rowid';
3675 $sql .= ' WHERE pf.fk_facturefourn = '.((int) $object->id);
3676 $sql .= ' ORDER BY p.datep, p.tms';
3677
3678 $result = $db->query($sql);
3679 if ($result) {
3680 $num = $db->num_rows($result);
3681 $i = 0;
3682
3683 print '<div class="div-table-responsive-no-min">';
3684 print '<table class="noborder paymenttable centpercent">';
3685 print '<tr class="liste_titre">';
3686 print '<td class="liste_titre">'.($object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("PaymentsBack") : $langs->trans('Payments')).'</td>';
3687 print '<td><span class="hideonsmartphone">'.$langs->trans('Date').'</span></td>';
3688 print '<td><span class="hideonsmartphone">'.$langs->trans('Type').'</span></td>';
3689 if (isModEnabled("bank")) {
3690 print '<td class="right">'.$langs->trans('BankAccount').'</td>';
3691 }
3692 print '<td class="right">'.$langs->trans('Amount').'</td>';
3693 print '<td width="18">&nbsp;</td>';
3694 print '</tr>';
3695
3696 if ($num > 0) {
3697 while ($i < $num) {
3698 $objp = $db->fetch_object($result);
3699
3700 $paymentstatic->id = $objp->rowid;
3701 $paymentstatic->datepaye = $db->jdate($objp->dp);
3702 $paymentstatic->ref = ($objp->ref ? $objp->ref : $objp->rowid);
3703 $paymentstatic->num_payment = $objp->num_payment;
3704
3705 $paymentstatic->paiementcode = $objp->payment_code;
3706 $paymentstatic->type_code = $objp->payment_code;
3707 $paymentstatic->type_label = $objp->payment_type;
3708
3709 print '<tr class="oddeven">';
3710 print '<td class="nowraponall">';
3711 print $paymentstatic->getNomUrl(1);
3712 print '</td>';
3713 print '<td>'.dol_print_date($db->jdate($objp->dp), 'day').'</td>';
3714 $s = $form->form_modes_reglement('', $objp->payment_type, 'none', '', 1, 0, '', 1).' '.$objp->num_payment;
3715 print '<td class="tdoverflowmax125" title="'.dol_escape_htmltag($s).'">';
3716 print $s;
3717 print '</td>';
3718 if (isModEnabled("bank")) {
3719 $bankaccountstatic->id = $objp->baid;
3720 $bankaccountstatic->ref = $objp->baref;
3721 $bankaccountstatic->label = $objp->baref;
3722 $bankaccountstatic->number = $objp->banumber;
3723
3724 if (isModEnabled('accounting')) {
3725 $bankaccountstatic->account_number = $objp->account_number;
3726
3727 $accountingjournal = new AccountingJournal($db);
3728 $accountingjournal->fetch($objp->fk_accountancy_journal);
3729 $bankaccountstatic->accountancy_journal = $accountingjournal->getNomUrl(0, 1, 1, '', 1);
3730 }
3731
3732 print '<td class="right">';
3733 if ($objp->baid > 0) {
3734 print $bankaccountstatic->getNomUrl(1, 'transactions');
3735 }
3736 print '</td>';
3737 }
3738 print '<td class="right">'.price($sign * $objp->amount).'</td>';
3739 print '<td class="center">';
3740 if ($object->status == FactureFournisseur::STATUS_VALIDATED && $object->paid == 0 && $user->socid == 0) {
3741 print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=deletepayment&token='.newToken().'&paiement_id='.$objp->rowid.'">';
3742 print img_delete();
3743 print '</a>';
3744 }
3745 print '</td>';
3746 print '</tr>';
3747 $totalpaid += $objp->amount;
3748 $i++;
3749 }
3750 } else {
3751 print '<tr class="oddeven"><td colspan="'.$nbcols.'"><span class="opacitymedium">'.$langs->trans("None").'</span></td><td></td><td></td></tr>';
3752 }
3753
3754 /*
3755 if ($object->paid == 0)
3756 {
3757 print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans('AlreadyPaid').' :</td><td class="right">'.price($totalpaid).'</td><td></td></tr>';
3758 print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("Billed").' :</td><td class="right">'.price($object->total_ttc).'</td><td></td></tr>';
3759
3760 $resteapayer = $object->total_ttc - $totalpaid;
3761
3762 print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans('RemainderToPay').' :</td>';
3763 print '<td class="right'.($resteapayer?' amountremaintopay':'').'">'.price($resteapayer).'</td><td></td></tr>';
3764 }
3765 */
3766
3767 $db->free($result);
3768 } else {
3769 dol_print_error($db);
3770 }
3771
3773 // Total already paid
3774 print '<tr><td colspan="'.$nbcols.'" class="right">';
3775 print '<span class="opacitymedium">';
3777 print $langs->trans('AlreadyPaidNoCreditNotesNoDeposits');
3778 } else {
3779 print $langs->trans('AlreadyPaid');
3780 }
3781 print '</span>';
3782 print '</td><td class="right"'.(($totalpaid > 0) ? ' class="amountalreadypaid"' : '').'>'.price($totalpaid).'</td><td>&nbsp;</td></tr>';
3783
3784 //$resteapayer = $object->total_ttc - $totalpaid;
3785 $resteapayeraffiche = $resteapayer;
3786
3787 $cssforamountpaymentcomplete = 'amountpaymentcomplete';
3788
3789 // Loop on each credit note or deposit amount applied
3790 $creditnoteamount = 0;
3791 $depositamount = 0;
3792
3793 $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
3794 $sql .= " re.description, re.fk_invoice_supplier_source";
3795 $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re";
3796 $sql .= " WHERE fk_invoice_supplier = ".((int) $object->id);
3797 $resql = $db->query($sql);
3798 if ($resql) {
3799 $num = $db->num_rows($resql);
3800 $i = 0;
3801 $invoice = new FactureFournisseur($db);
3802 while ($i < $num) {
3803 $obj = $db->fetch_object($resql);
3804 $invoice->fetch($obj->fk_invoice_supplier_source);
3805 print '<tr><td colspan="'.$nbcols.'" class="right">';
3806 if ($invoice->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
3807 print $langs->trans("CreditNote").' ';
3808 }
3809 if ($invoice->type == FactureFournisseur::TYPE_DEPOSIT) {
3810 print $langs->trans("Deposit").' ';
3811 }
3812 print $invoice->getNomUrl(0);
3813 print ' :</td>';
3814 print '<td class="right">'.price($obj->amount_ttc).'</td>';
3815 print '<td class="right">';
3816 print '<a href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=unlinkdiscount&discountid='.$obj->rowid.'">';
3817 print img_picto($langs->transnoentitiesnoconv("RemoveDiscount"), 'unlink');
3818 print '</a>';
3819 print '</td></tr>';
3820 $i++;
3821 if ($invoice->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
3822 $creditnoteamount += $obj->amount_ttc;
3823 }
3824 if ($invoice->type == FactureFournisseur::TYPE_DEPOSIT) {
3825 $depositamount += $obj->amount_ttc;
3826 }
3827 }
3828 } else {
3829 dol_print_error($db);
3830 }
3831
3832 // Paye partiellement 'escompte'
3833 if (($object->status == FactureFournisseur::STATUS_CLOSED || $object->status == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'discount_vat') {
3834 print '<tr><td colspan="'.$nbcols.'" class="right nowrap">';
3835 print '<span class="opacitymedium">';
3836 print $form->textwithpicto($langs->trans("Discount"), $langs->trans("HelpEscompte"), - 1);
3837 print '</span>';
3838 print '</td><td class="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaid).'</td><td>&nbsp;</td></tr>';
3839 $resteapayeraffiche = 0;
3840 $cssforamountpaymentcomplete = 'amountpaymentneutral';
3841 }
3842 // Paye partiellement ou Abandon 'badsupplier'
3843 if (($object->status == FactureFournisseur::STATUS_CLOSED || $object->status == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'badsupplier') {
3844 print '<tr><td colspan="'.$nbcols.'" class="right nowrap">';
3845 print '<span class="opacitymedium">';
3846 print $form->textwithpicto($langs->trans("Abandoned"), $langs->trans("HelpAbandonBadCustomer"), - 1);
3847 print '</span>';
3848 print '</td><td class="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaid).'</td><td>&nbsp;</td></tr>';
3849 // $resteapayeraffiche=0;
3850 $cssforamountpaymentcomplete = 'amountpaymentneutral';
3851 }
3852 // Paye partiellement ou Abandon 'product_returned'
3853 if (($object->status == FactureFournisseur::STATUS_CLOSED || $object->status == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'product_returned') {
3854 print '<tr><td colspan="'.$nbcols.'" class="right nowrap">';
3855 print '<span class="opacitymedium">';
3856 print $form->textwithpicto($langs->trans("ProductReturned"), $langs->trans("HelpAbandonProductReturned"), - 1);
3857 print '</span>';
3858 print '</td><td class="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaid).'</td><td>&nbsp;</td></tr>';
3859 $resteapayeraffiche = 0;
3860 $cssforamountpaymentcomplete = 'amountpaymentneutral';
3861 }
3862 // Paye partiellement ou Abandon 'abandon'
3863 if (($object->status == FactureFournisseur::STATUS_CLOSED || $object->status == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'abandon') {
3864 print '<tr><td colspan="'.$nbcols.'" class="right nowrap">';
3865 $text = $langs->trans("HelpAbandonOther");
3866 if ($object->close_note) {
3867 $text .= '<br><br><b>'.$langs->trans("Reason").'</b>:'.$object->close_note;
3868 }
3869 print '<span class="opacitymedium">';
3870 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
3871 print $form->textwithpicto($langs->trans("Abandoned"), $text, - 1);
3872 print '</span>';
3873 print '</td><td class="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaid).'</td><td>&nbsp;</td></tr>';
3874 $resteapayeraffiche = 0;
3875 $cssforamountpaymentcomplete = 'amountpaymentneutral';
3876 }
3877
3878 // Billed
3879 print '<tr><td colspan="'.$nbcols.'" class="right">';
3880 print '<span class="opacitymedium">';
3881 print $langs->trans("Billed");
3882 print '</span>';
3883 print '</td><td class="right">'.price($object->total_ttc).'</td><td>&nbsp;</td></tr>';
3884
3885 // Remainder to pay
3886 print '<tr><td colspan="'.$nbcols.'" class="right">';
3887 print '<span class="opacitymedium">';
3888 print $langs->trans('RemainderToPay');
3889 if ($resteapayeraffiche < 0) {
3890 print ' ('.$langs->trans('NegativeIfExcessPaid').')';
3891 }
3892 print '</span>';
3893 print '</td>';
3894 print '<td class="right'.($resteapayeraffiche ? ' amountremaintopay' : (' '.$cssforamountpaymentcomplete)).'">'.price($resteapayeraffiche).'</td><td>&nbsp;</td></tr>';
3895
3896 // Remainder to pay Multicurrency
3897 if (isModEnabled('multicurrency') && $object->multicurrency_code != $conf->currency || $object->multicurrency_tx != 1) {
3898 print '<tr><td colspan="'.$nbcols.'" class="right">';
3899 print '<span class="opacitymedium">';
3900 print $langs->trans('RemainderToPayMulticurrency');
3901 if ($resteapayeraffiche < 0) {
3902 print ' ('.$langs->trans('NegativeIfExcessPaid').')';
3903 }
3904 print '</span>';
3905 print '</td>';
3906 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>';
3907 }
3908 } else { // Credit note
3909 $cssforamountpaymentcomplete = 'amountpaymentneutral';
3910
3911 // Total already paid back
3912 print '<tr><td colspan="'.$nbcols.'" class="right">';
3913 print $langs->trans('AlreadyPaidBack');
3914 print ' :</td><td class="right">'.price($sign * $totalpaid).'</td><td>&nbsp;</td></tr>';
3915
3916 // Billed
3917 print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("Billed").' :</td><td class="right">'.price($sign * $object->total_ttc).'</td><td>&nbsp;</td></tr>';
3918
3919 // Remainder to pay back
3920 print '<tr><td colspan="'.$nbcols.'" class="right">';
3921 print '<span class="opacitymedium">';
3922 print $langs->trans('RemainderToPayBack');
3923 if ($resteapayeraffiche > 0) {
3924 print ' ('.$langs->trans('NegativeIfExcessRefunded').')';
3925 }
3926 print '</td>';
3927 print '</span>';
3928 print '<td class="right'.($resteapayeraffiche ? ' amountremaintopay' : (' '.$cssforamountpaymentcomplete)).'">'.price($sign * $resteapayeraffiche).'</td><td>&nbsp;</td></tr>';
3929
3930 // Remainder to pay back Multicurrency
3931 if (isModEnabled('multicurrency') && $object->multicurrency_code != $conf->currency || $object->multicurrency_tx != 1) {
3932 print '<tr><td colspan="'.$nbcols.'" class="right">';
3933 print '<span class="opacitymedium">';
3934 print $langs->trans('RemainderToPayBackMulticurrency');
3935 if ($resteapayeraffiche > 0) {
3936 print ' ('.$langs->trans('NegativeIfExcessRefunded').')';
3937 }
3938 print '</span>';
3939 print '</td>';
3940 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>';
3941 }
3942
3943 // Sold credit note
3944 // print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans('TotalTTC').' :</td>';
3945 // print '<td class="right" style="border: 1px solid;" bgcolor="#f0f0f0"><b>'.price($sign *
3946 // $object->total_ttc).'</b></td><td>&nbsp;</td></tr>';
3947 }
3948
3949 print '</table>';
3950 print '</div>';
3951
3952 print '</div>';
3953 print '</div>';
3954
3955 print '<div class="clearboth"></div><br>';
3956
3957 if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
3958 $blocname = 'contacts';
3959 $title = $langs->trans('ContactsAddresses');
3960 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
3961 }
3962
3963 if (getDolGlobalString('MAIN_DISABLE_NOTES_TAB')) {
3964 $colwidth = 20;
3965 $blocname = 'notes';
3966 $title = $langs->trans('Notes');
3967 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
3968 }
3969
3970
3971 /*
3972 * Lines
3973 */
3974 print '<form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="POST">';
3975 print '<input type="hidden" name="token" value="'.newToken().'">';
3976 print '<input type="hidden" name="action" value="'.(($action != 'editline') ? 'addline' : 'updateline').'">';
3977 print '<input type="hidden" name="mode" value="">';
3978 print '<input type="hidden" name="page_y" value="">';
3979 print '<input type="hidden" name="id" value="'.$object->id.'">';
3980 print '<input type="hidden" name="socid" value="'.$societe->id.'">';
3981 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
3982
3983 if (!empty($conf->use_javascript_ajax) && $object->status == FactureFournisseur::STATUS_DRAFT) {
3984 include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
3985 }
3986
3987 print '<div class="div-table-responsive-no-min">';
3988 print '<table id="tablelines" class="noborder noshadow centpercent">';
3989
3990 global $forceall, $senderissupplier, $dateSelector, $inputalsopricewithtax;
3991 $forceall = 1;
3992 $dateSelector = 0;
3993 $inputalsopricewithtax = 1;
3994 $senderissupplier = 2; // $senderissupplier=2 is same than 1 but disable test on minimum qty and disable autofill qty with minimum.
3995 if (getDolGlobalInt('SUPPLIER_INVOICE_WITH_PREDEFINED_PRICES_ONLY')) {
3996 $senderissupplier = getDolGlobalInt('SUPPLIER_INVOICE_WITH_PREDEFINED_PRICES_ONLY');
3997 }
3998
3999 // Show object lines (result may vary according to hidden option MAIN_NO_INPUT_PRICE_WITH_TAX)
4000 if (!empty($object->lines)) {
4001 $object->printObjectLines($action, $societe, $mysoc, $lineid, 1);
4002 }
4003
4004 $num = count($object->lines);
4005
4006 // Form to add new line
4007 if ($object->status == FactureFournisseur::STATUS_DRAFT && $usercancreate) {
4008 if ($action != 'editline') {
4009 // Add free products/services
4010
4011 $parameters = array();
4012 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
4013 if ($reshook < 0) {
4014 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
4015 }
4016 if (empty($reshook)) {
4017 $object->formAddObjectLine(1, $societe, $mysoc);
4018 }
4019 }
4020 }
4021
4022 print '</table>';
4023 print '</div>';
4024 print '</form>';
4025 }
4026
4027 print dol_get_fiche_end();
4028
4029
4030 if ($action != 'presend') {
4031 // Buttons actions
4032
4033 print '<div class="tabsAction">';
4034
4035 $parameters = array();
4036 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
4037 // modified by hook
4038 if (empty($reshook)) {
4039 // Modify a validated invoice with no payments
4040 if ($object->status == FactureFournisseur::STATUS_VALIDATED && $action != 'confirm_edit' && $object->getSommePaiement() == 0 && $usercancreate) {
4041 // We check if lines of invoice are not already transferred into accountancy
4042 $ventilExportCompta = $object->getVentilExportCompta(); // Should be 0 since the sum of payments are zero. But we keep the protection.
4043
4044 if ($ventilExportCompta == 0) {
4045 print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=edit&token='.newToken().'">'.$langs->trans('Modify').'</a>';
4046 } else {
4047 print '<span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseDispatchedInBookkeeping").'">'.$langs->trans('Modify').'</span>';
4048 }
4049 }
4050
4051 $discount = new DiscountAbsolute($db);
4052 $result = $discount->fetch(0, 0, $object->id);
4053
4054 // Reopen a standard paid invoice
4056 || ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && empty($discount->id))
4057 || ($object->type == FactureFournisseur::TYPE_DEPOSIT && empty($discount->id)))
4058 && ($object->status == FactureFournisseur::STATUS_CLOSED || $object->status == FactureFournisseur::STATUS_ABANDONED)) { // A paid invoice (partially or completely)
4059 if (!$objectidnext && $object->close_code != 'replaced' && $usercancreate) { // Not replaced by another invoice
4060 print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans('ReOpen').'</a>';
4061 } else {
4062 if ($usercancreate) {
4063 print '<span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('ReOpen').'</span>';
4064 } elseif (!getDolGlobalString('MAIN_BUTTON_HIDE_UNAUTHORIZED')) {
4065 print '<span class="butActionRefused classfortooltip">'.$langs->trans('ReOpen').'</span>';
4066 }
4067 }
4068 }
4069
4070 // Validate
4071 if ($action != 'confirm_edit' && $object->status == FactureFournisseur::STATUS_DRAFT && count($object->lines) > 0
4072 && ((($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_REPLACEMENT || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_PROFORMA || $object->type == FactureFournisseur::TYPE_SITUATION) && (getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE') || $object->total_ttc >= 0)) // @phan-suppress-current-line PhanDeprecatedClassConstant
4073 || ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) {
4074 // if (count($object->lines)) { // already tested in condition
4075 if ($usercanvalidate) {
4076 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=valid&token='.newToken().'"';
4077 print '>'.$langs->trans('Validate').'</a>';
4078 } else {
4079 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'"';
4080 print '>'.$langs->trans('Validate').'</a>';
4081 }
4082 //}
4083 }
4084
4085 // Send by mail
4086 if (empty($user->socid)) {
4088 if ($usercansend) {
4089 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=presend&mode=init#formmailbeforetitle">'.$langs->trans('SendMail').'</a>';
4090 } else {
4091 print '<span class="butActionRefused classfortooltip">'.$langs->trans('SendMail').'</span>';
4092 }
4093 }
4094 }
4095
4096 // Create payment
4098 print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.DOL_URL_ROOT.'/fourn/facture/paiement.php?facid='.$object->id.'&action=create'.($object->fk_account > 0 ? '&amp;accountid='.$object->fk_account : '').'">'.$langs->trans('DoPayment').'</a>'; // must use facid because id is for payment id not invoice
4099 }
4100
4101 // Reverse back money or convert to reduction
4103 // For credit note only
4104 if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->status == 1 && $object->paid == 0) {
4105 if ($resteapayer == 0) {
4106 print '<span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseRemainderToPayIsZero").'">'.$langs->trans('DoPaymentBack').'</span>';
4107 } else {
4108 print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/paiement.php?facid='.$object->id.'&action=create&accountid='.$object->fk_account.'">'.$langs->trans('DoPaymentBack').'</a>';
4109 }
4110 }
4111
4112 // For standard invoice with excess paid
4113 if ($object->type == FactureFournisseur::TYPE_STANDARD && empty($object->paid) && ($object->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits) < 0 && $usercancreate && empty($discount->id)) {
4114 print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=converttoreduc&token='.newToken().'">'.$langs->trans('ConvertExcessPaidToReduc').'</a>';
4115 }
4116 // For credit note
4117 if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->status == 1 && $object->paid == 0 && $usercancreate
4118 && (getDolGlobalString('SUPPLIER_INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED') || $object->getSommePaiement() == 0)
4119 ) {
4120 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>';
4121 }
4122 // For deposit invoice
4123 if ($object->type == FactureFournisseur::TYPE_DEPOSIT && $usercancreate && $object->status > 0 && empty($discount->id)) {
4124 print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=converttoreduc&token='.newToken().'">'.$langs->trans('ConvertToReduc').'</a>';
4125 }
4126 }
4127
4128 // Classify paid
4129 if ($object->status == FactureFournisseur::STATUS_VALIDATED && $object->paid == 0 && (
4130 ($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))) ||
4131 ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $resteapayer >= 0) ||
4132 ($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)))
4133 )
4134 ) {
4135 print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=paid&token='.newToken().'">'.$langs->trans('ClassifyPaid').'</a>';
4136 }
4137
4138 // Classify 'closed not completely paid' (possible if validated and not yet filed paid)
4139 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)) {
4140 if ($totalpaid > 0 || $totalcreditnotes > 0) {
4141 // If one payment or one credit note was linked to this invoice
4142 print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=paid&token='.newToken().'">'.$langs->trans('ClassifyPaidPartially').'</a>';
4143 } else {
4144 if (!getDolGlobalString('INVOICE_CAN_NEVER_BE_CANCELED')) {
4145 print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=canceled">'.$langs->trans('ClassifyCanceled').'</a>';
4146 }
4147 }
4148 }
4149
4150 // Create event
4151 /*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.
4152 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>';
4153 }*/
4154
4155 // Create a credit note
4156 if (($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_DEPOSIT) && $object->status > 0 && $usercancreate) {
4157 if (!$objectidnext) {
4158 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?socid='.$object->socid.'&amp;fac_avoir='.$object->id.'&action=create&type=2'.($object->fk_project > 0 ? '&amp;projectid='.$object->fk_project : '').'">'.$langs->trans("CreateCreditNote").'</a>';
4159 }
4160 }
4161
4162 // Clone
4163 if ($action != 'edit' && $usercancreate) {
4164 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=clone&socid='.$object->socid.'&token='.newToken().'">'.$langs->trans('ToClone').'</a>';
4165 }
4166
4167 // Clone as predefined / Create template
4168 if (($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_DEPOSIT) && $object->status == 0 && $usercancreate) {
4169 if (!$objectidnext && count($object->lines) > 0) {
4170 print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/card-rec.php?facid='.$object->id.'&action=create">'.$langs->trans("ChangeIntoRepeatableInvoice").'</a>';
4171 }
4172 }
4173
4174 // Delete
4175 if ($action != 'confirm_edit' && $usercandelete) {
4176 $isErasable = $object->is_erasable();
4177
4178 $enableDelete = false;
4179 $htmltooltip = '';
4180 $params = (empty($conf->use_javascript_ajax) ? array() : array('attr' => array('class' => 'reposition')));
4181 //var_dump($isErasable); var_dump($params);
4182 if ($isErasable == -4) {
4183 $htmltooltip = $langs->trans("DisabledBecausePayments");
4184 } elseif ($isErasable == -3) { // Should never happen with supplier invoice
4185 $htmltooltip = $langs->trans("DisabledBecauseNotLastSituationInvoice");
4186 } elseif ($isErasable == -2) { // Should never happen with supplier invoice
4187 $htmltooltip = $langs->trans("DisabledBecauseNotLastInvoice");
4188 } elseif ($isErasable == -1) {
4189 $htmltooltip = $langs->trans("DisabledBecauseDispatchedInBookkeeping");
4190 } elseif ($isErasable <= 0) { // Any other cases
4191 $htmltooltip = $langs->trans("DisabledBecauseNotErasable");
4192 } else {
4193 $enableDelete = true;
4194 $htmltooltip = '';
4195 }
4196 print dolGetButtonAction($htmltooltip, $langs->trans("Delete"), 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), $object->id, $enableDelete, $params);
4197 }
4198 print '</div>';
4199
4200 if ($action != 'confirm_edit') {
4201 print '<div class="fichecenter"><div class="fichehalfleft">';
4202
4203 /*
4204 * Generated documents
4205 */
4206 $ref = dol_sanitizeFileName($object->ref);
4207 $subdir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier').$ref;
4208 $filedir = $conf->fournisseur->facture->dir_output.'/'.$subdir;
4209 $urlsource = $_SERVER['PHP_SELF'].'?id='.$object->id;
4210 $genallowed = $usercanread;
4211 $delallowed = $usercancreate;
4212 $modelpdf = (empty($object->model_pdf) ? getDolGlobalString('INVOICE_SUPPLIER_ADDON_PDF') : $object->model_pdf);
4213 $genifempty = 0;
4214
4215 print $formfile->showdocuments('facture_fournisseur', $subdir, $filedir, $urlsource, $genallowed, $delallowed, $modelpdf, $genifempty, 0, 0, 40, 0, '', '', '', $societe->default_lang);
4216 $somethingshown = $formfile->numoffiles;
4217
4218 // Show links to link elements
4219 $tmparray = $form->showLinkToObjectBlock($object, array(), array('invoice_supplier'), 1);
4220 $linktoelem = $tmparray['linktoelem'];
4221 $htmltoenteralink = $tmparray['htmltoenteralink'];
4222 print $htmltoenteralink;
4223
4224 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
4225
4226 print '</div><div class="fichehalfright">';
4227
4228 // List of actions on element
4229 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
4230 $formactions = new FormActions($db);
4231 $somethingshown = $formactions->showactions($object, 'invoice_supplier', $socid, 1, 'listaction'.($genallowed ? 'largetitle' : ''));
4232
4233 print '</div></div>';
4234 }
4235 }
4236 }
4237
4238 // Select mail models is same action as presend
4239 if (GETPOST('modelselected')) {
4240 $action = 'presend';
4241 }
4242
4243 // Presend form
4244 $modelmail = 'invoice_supplier_send';
4245 $defaulttopic = 'SendBillRef';
4246 $diroutput = $conf->fournisseur->facture->dir_output;
4247 $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO';
4248 $trackid = 'sinv'.$object->id;
4249
4250 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
4251 }
4252}
4253
4254
4255// End of page
4256llxFooter();
4257$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_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
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).
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
dolGetButtonAction($label, $text='', $actionType='default', $url='', $id='', $userRight=1, $params=array())
Function dolGetButtonAction.
get_default_npr(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that returns whether VAT must be recoverable collected VAT (e.g.: VAT NPR in France)
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
dol_htmloutput_events($disabledoutputofmessages=0)
Print formatted messages to output (Used to show messages on html output).
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
GETPOSTFLOAT($paramname, $rounding='')
Return the value of a $_GET or $_POST supervariable, converted into float.
dol_clone($object, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='')
Show information in HTML for admin users or standard users.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
get_localtax($vatrate, $local, $thirdparty_buyer=null, $thirdparty_seller=null, $vatnpr=0)
Return localtax rate for a particular vat, when selling a product with vat $vatrate,...
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.