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