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