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