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