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