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