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