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