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