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