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