dolibarr  x.y.z
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 
889  $object->addline($langs->trans('invoiceAvoirLineWithPaymentRestAmount'), $remain_to_pay, 0, 0, 0, 1, 0, 0, '', '', 'TTC');
890  }
891  }
892  }
893  } elseif ($fac_recid > 0 && (GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT)) {
894  // Standard invoice or Deposit invoice, created from a Predefined template invoice
895  if (empty($dateinvoice)) {
896  $error++;
897  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
898  $action = 'create';
899  } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
900  $error++;
901  setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
902  $action = 'create';
903  }
904 
905  if (!$error) {
906  $object->socid = GETPOST('socid', 'int');
907  $object->type = GETPOST('type', 'alphanohtml');
908  $object->ref = GETPOST('ref', 'alphanohtml');
909  $object->date = $dateinvoice;
910  $object->note_public = trim(GETPOST('note_public', 'restricthtml'));
911  $object->note_private = trim(GETPOST('note_private', 'restricthtml'));
912  $object->ref_supplier = GETPOST('ref_supplier', 'alphanohtml');
913  $object->model_pdf = GETPOST('model', 'alphanohtml');
914  $object->fk_project = GETPOST('projectid', 'int');
915  $object->cond_reglement_id = (GETPOST('type') == 3 ? 1 : GETPOST('cond_reglement_id'));
916  $object->mode_reglement_id = GETPOST('mode_reglement_id', 'int');
917  $object->fk_account = GETPOST('fk_account', 'int');
918  $object->amount = price2num(GETPOST('amount'));
919  $object->remise_absolue = price2num(GETPOST('remise_absolue'), 'MU');
920  $object->remise_percent = price2num(GETPOST('remise_percent'), '', 2);
921  $object->fk_incoterms = GETPOST('incoterm_id', 'int');
922  $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
923  $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
924  $object->multicurrency_tx = GETPOST('originmulticurrency_tx', 'int');
925 
926  // Source facture
927  $object->fac_rec = $fac_recid;
928  $fac_rec = new FactureFournisseurRec($db);
929  $fac_rec->fetch($object->fac_rec);
930  $fac_rec->fetch_lines();
931  $object->lines = $fac_rec->lines;
932 
933  $id = $object->create($user); // This include recopy of links from recurring invoice and recurring invoice lines
934  }
935  } elseif ($fac_recid <= 0 && (GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT)) {
936  // Standard invoice or Deposit invoice, not from a Predefined template invoice
937  if (GETPOST('socid', 'int') < 1) {
938  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('Supplier')), null, 'errors');
939  $action = 'create';
940  $error++;
941  }
942 
943  if (empty($dateinvoice)) {
944  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('DateInvoice')), null, 'errors');
945  $action = 'create';
946  $_GET['socid'] = $_POST['socid'];
947  $error++;
948  } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
949  $error++;
950  setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
951  $action = 'create';
952  }
953 
954  if (!GETPOST('ref_supplier')) {
955  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('RefSupplier')), null, 'errors');
956  $action = 'create';
957  $_GET['socid'] = $_POST['socid'];
958  $error++;
959  }
960 
961  if (!$error) {
962  $tmpproject = GETPOST('projectid', 'int');
963 
964  // Creation invoice
965  $object->socid = GETPOST('socid', 'int');
966  $object->type = GETPOST('type', 'alphanohtml');
967  $object->ref = GETPOST('ref', 'alphanohtml');
968  $object->ref_supplier = GETPOST('ref_supplier', 'alphanohtml');
969  $object->socid = GETPOST('socid', 'int');
970  $object->libelle = GETPOST('label', 'alphanohtml'); // deprecated
971  $object->label = GETPOST('label', 'alphanohtml');
972  $object->date = $dateinvoice;
973  $object->date_echeance = $datedue;
974  $object->note_public = GETPOST('note_public', 'restricthtml');
975  $object->note_private = GETPOST('note_private', 'restricthtml');
976  $object->cond_reglement_id = GETPOST('cond_reglement_id');
977  $object->mode_reglement_id = GETPOST('mode_reglement_id');
978  $object->fk_account = GETPOST('fk_account', 'int');
979  $object->fk_project = ($tmpproject > 0) ? $tmpproject : null;
980  $object->fk_incoterms = GETPOST('incoterm_id', 'int');
981  $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
982  $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
983  $object->multicurrency_tx = GETPOST('originmulticurrency_tx', 'int');
984  $object->transport_mode_id = GETPOST('transport_mode_id');
985 
986  // Auto calculation of date due if not filled by user
987  if (empty($object->date_echeance)) {
988  $object->date_echeance = $object->calculate_date_lim_reglement();
989  }
990 
991  $object->fetch_thirdparty();
992 
993  // If creation from another object of another module
994  if (!$error && GETPOST('origin', 'alpha') && GETPOST('originid')) {
995  // Parse element/subelement (ex: project_task)
996  $element = $subelement = GETPOST('origin', 'alpha');
997  /*if (preg_match('/^([^_]+)_([^_]+)/i', GETPOST('origin'),$regs))
998  {
999  $element = $regs[1];
1000  $subelement = $regs[2];
1001  }*/
1002 
1003  // For compatibility
1004  if ($element == 'order') {
1005  $element = $subelement = 'commande';
1006  }
1007  if ($element == 'propal') {
1008  $element = 'comm/propal'; $subelement = 'propal';
1009  }
1010  if ($element == 'contract') {
1011  $element = $subelement = 'contrat';
1012  }
1013  if ($element == 'order_supplier') {
1014  $element = 'fourn'; $subelement = 'fournisseur.commande';
1015  }
1016  if ($element == 'project') {
1017  $element = 'projet';
1018  }
1019  $object->origin = GETPOST('origin', 'alpha');
1020  $object->origin_id = GETPOST('originid', 'int');
1021 
1022 
1023  require_once DOL_DOCUMENT_ROOT.'/'.$element.'/class/'.$subelement.'.class.php';
1024  $classname = ucfirst($subelement);
1025  if ($classname == 'Fournisseur.commande') {
1026  $classname = 'CommandeFournisseur';
1027  }
1028  $objectsrc = new $classname($db);
1029  $objectsrc->fetch($originid);
1030  $objectsrc->fetch_thirdparty();
1031 
1032  if (!empty($object->origin) && !empty($object->origin_id)) {
1033  $object->linkedObjectsIds[$object->origin] = $object->origin_id;
1034  }
1035 
1036  // Add also link with order if object is reception
1037  if ($object->origin == 'reception') {
1038  $objectsrc->fetchObjectLinked();
1039 
1040  if (count($objectsrc->linkedObjectsIds['order_supplier']) > 0) {
1041  foreach ($objectsrc->linkedObjectsIds['order_supplier'] as $key => $value) {
1042  $object->linkedObjectsIds['order_supplier'] = $value;
1043  }
1044  }
1045  }
1046 
1047  $id = $object->create($user);
1048 
1049  // Add lines
1050  if ($id > 0) {
1051  require_once DOL_DOCUMENT_ROOT.'/'.$element.'/class/'.$subelement.'.class.php';
1052  $classname = ucfirst($subelement);
1053  if ($classname == 'Fournisseur.commande') {
1054  $classname = 'CommandeFournisseur';
1055  }
1056  $srcobject = new $classname($db);
1057 
1058  $result = $srcobject->fetch(GETPOST('originid', 'int'));
1059 
1060  // If deposit invoice - down payment with 1 line (fixed amount or percent)
1061  $typeamount = GETPOST('typedeposit', 'alpha');
1062  if (GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT && in_array($typeamount, array('amount', 'variable'))) {
1063  $valuedeposit = price2num(GETPOST('valuedeposit', 'alpha'), 'MU');
1064 
1065  // Define the array $amountdeposit
1066  $amountdeposit = array();
1067  if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA)) {
1068  if ($typeamount == 'amount') {
1069  $amount = $valuedeposit;
1070  } else {
1071  $amount = $srcobject->total_ttc * ($valuedeposit / 100);
1072  }
1073 
1074  $TTotalByTva = array();
1075  foreach ($srcobject->lines as &$line) {
1076  if (!empty($line->special_code)) {
1077  continue;
1078  }
1079  $TTotalByTva[$line->tva_tx] += $line->total_ttc;
1080  }
1081 
1082  foreach ($TTotalByTva as $tva => &$total) {
1083  $coef = $total / $srcobject->total_ttc; // Calc coef
1084  $am = $amount * $coef;
1085  $amount_ttc_diff += $am;
1086  $amountdeposit[$tva] += $am / (1 + $tva / 100); // Convert into HT for the addline
1087  }
1088  } else {
1089  if ($typeamount == 'amount') {
1090  $amountdeposit[0] = $valuedeposit;
1091  } elseif ($typeamount == 'variable') {
1092  if ($result > 0) {
1093  $totalamount = 0;
1094  $lines = $srcobject->lines;
1095  $numlines = count($lines);
1096  for ($i = 0; $i < $numlines; $i++) {
1097  $qualified = 1;
1098  if (empty($lines[$i]->qty)) {
1099  $qualified = 0; // We discard qty=0, it is an option
1100  }
1101  if (!empty($lines[$i]->special_code)) {
1102  $qualified = 0; // We discard special_code (frais port, ecotaxe, option, ...)
1103  }
1104  if ($qualified) {
1105  $totalamount += $lines[$i]->total_ht; // Fixme : is it not for the customer ? Shouldn't we take total_ttc ?
1106  $tva_tx = $lines[$i]->tva_tx;
1107  $amountdeposit[$tva_tx] += ($lines[$i]->total_ht * $valuedeposit) / 100;
1108  }
1109  }
1110 
1111  if ($totalamount == 0) {
1112  $amountdeposit[0] = 0;
1113  }
1114  } else {
1115  setEventMessages($srcobject->error, $srcobject->errors, 'errors');
1116  $error++;
1117  }
1118  }
1119 
1120  $amount_ttc_diff = $amountdeposit[0];
1121  }
1122 
1123  foreach ($amountdeposit as $tva => $amount) {
1124  if (empty($amount)) {
1125  continue;
1126  }
1127 
1128  $arraylist = array(
1129  'amount' => 'FixAmount',
1130  'variable' => 'VarAmount'
1131  );
1132  $descline = '(DEPOSIT)';
1133  //$descline.= ' - '.$langs->trans($arraylist[$typeamount]);
1134  if ($typeamount == 'amount') {
1135  $descline .= ' ('.price($valuedeposit, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)).')';
1136  } elseif ($typeamount == 'variable') {
1137  $descline .= ' ('.$valuedeposit.'%)';
1138  }
1139 
1140  $descline .= ' - '.$srcobject->ref;
1141  $result = $object->addline(
1142  $descline,
1143  $amount, // subprice
1144  $tva, // vat rate
1145  0, // localtax1_tx
1146  0, // localtax2_tx
1147  1, // quantity
1148  (empty($conf->global->INVOICE_PRODUCTID_DEPOSIT) ? 0 : $conf->global->INVOICE_PRODUCTID_DEPOSIT), // fk_product
1149  0, // remise_percent
1150  0, // date_start
1151  0, // date_end
1152  0,
1153  $lines[$i]->info_bits, // info_bits
1154  'HT',
1155  0, // product_type
1156  1,
1157  0,
1158  0,
1159  null,
1160  $object->origin,
1161  0,
1162  '',
1163  $lines[$i]->special_code,
1164  0,
1165  0
1166  //,$langs->trans('Deposit') //Deprecated
1167  );
1168  }
1169 
1170  $diff = $object->total_ttc - $amount_ttc_diff;
1171 
1172  if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA) && $diff != 0) {
1173  $object->fetch_lines();
1174  $subprice_diff = $object->lines[0]->subprice - $diff / (1 + $object->lines[0]->tva_tx / 100);
1175  $object->updateline(
1176  $object->lines[0]->id,
1177  $object->lines[0]->desc,
1178  $subprice_diff,
1179  $object->lines[0]->tva_tx,
1180  $object->lines[0]->localtax1_tx,
1181  $object->lines[0]->localtax2_tx,
1182  $object->lines[0]->qty,
1183  $object->lines[0]->fk_product,
1184  'HT',
1185  $object->lines[0]->info_bits,
1186  $object->lines[0]->product_type,
1187  $object->lines[0]->remise_percent,
1188  0,
1189  $object->lines[0]->date_start,
1190  $object->lines[0]->date_end,
1191  0,
1192  0,
1193  0,
1194  '',
1195  100
1196  );
1197  }
1198  } elseif ($result > 0) {
1199  $lines = $srcobject->lines;
1200  if (empty($lines) && method_exists($srcobject, 'fetch_lines')) {
1201  $srcobject->fetch_lines();
1202  $lines = $srcobject->lines;
1203  }
1204 
1205  $num = count($lines);
1206  for ($i = 0; $i < $num; $i++) { // TODO handle subprice < 0
1207  if (!in_array($lines[$i]->id, $selectedLines)) {
1208  continue; // Skip unselected lines
1209  }
1210 
1211  $desc = ($lines[$i]->desc ? $lines[$i]->desc : $lines[$i]->libelle);
1212  $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0);
1213 
1214  // Extrafields
1215  if (method_exists($lines[$i], 'fetch_optionals')) {
1216  $lines[$i]->fetch_optionals();
1217  }
1218 
1219  // Dates
1220  // TODO mutualiser
1221  $date_start = $lines[$i]->date_debut_prevue;
1222  if ($lines[$i]->date_debut_reel) {
1223  $date_start = $lines[$i]->date_debut_reel;
1224  }
1225  if ($lines[$i]->date_start) {
1226  $date_start = $lines[$i]->date_start;
1227  }
1228  $date_end = $lines[$i]->date_fin_prevue;
1229  if ($lines[$i]->date_fin_reel) {
1230  $date_end = $lines[$i]->date_fin_reel;
1231  }
1232  if ($lines[$i]->date_end) {
1233  $date_end = $lines[$i]->date_end;
1234  }
1235 
1236  // FIXME Missing special_code into addline and updateline methods
1237  $object->special_code = $lines[$i]->special_code;
1238 
1239  // FIXME If currency different from main currency, take multicurrency price
1240  if ($object->multicurrency_code != $conf->currency || $object->multicurrency_tx != 1) {
1241  $pu = 0;
1242  $pu_currency = $lines[$i]->multicurrency_subprice;
1243  } else {
1244  $pu = $lines[$i]->subprice;
1245  $pu_currency = 0;
1246  }
1247 
1248  // FIXME Missing $lines[$i]->ref_supplier and $lines[$i]->label into addline and updateline methods. They are filled when coming from order for example.
1249  $result = $object->addline(
1250  $desc,
1251  $pu,
1252  $lines[$i]->tva_tx,
1253  $lines[$i]->localtax1_tx,
1254  $lines[$i]->localtax2_tx,
1255  $lines[$i]->qty,
1256  $lines[$i]->fk_product,
1257  $lines[$i]->remise_percent,
1258  $date_start,
1259  $date_end,
1260  0,
1261  $lines[$i]->info_bits,
1262  'HT',
1263  $product_type,
1264  $lines[$i]->rang,
1265  0,
1266  $lines[$i]->array_options,
1267  $lines[$i]->fk_unit,
1268  $lines[$i]->id,
1269  $pu_currency,
1270  $lines[$i]->ref_supplier,
1271  $lines[$i]->special_code
1272  );
1273 
1274  if ($result < 0) {
1275  $error++;
1276  break;
1277  }
1278  }
1279 
1280  // Now reload line
1281  $object->fetch_lines();
1282  } else {
1283  $error++;
1284  }
1285  } else {
1286  $error++;
1287  }
1288  } elseif (!$error) {
1289  $id = $object->create($user);
1290  if ($id < 0) {
1291  $error++;
1292  }
1293  }
1294  }
1295  }
1296 
1297  if ($error) {
1298  $langs->load("errors");
1299  $db->rollback();
1300 
1301  setEventMessages($object->error, $object->errors, 'errors');
1302  $action = 'create';
1303  $_GET['socid'] = $_POST['socid'];
1304  } else {
1305  $db->commit();
1306 
1307  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
1308  $outputlangs = $langs;
1309  $result = $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1310  if ($result < 0) {
1311  dol_print_error($db, $object->error, $object->errors);
1312  exit;
1313  }
1314  }
1315 
1316  header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
1317  exit;
1318  }
1319  } elseif ($action == 'updateline' && $usercancreate) {
1320  // Edit line
1321  $db->begin();
1322 
1323  if (! $object->fetch($id) > 0) {
1324  dol_print_error($db);
1325  }
1326  $object->fetch_thirdparty();
1327 
1328  $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
1329  $tva_tx = str_replace('*', '', $tva_tx);
1330 
1331  if (GETPOST('price_ht') != '' || GETPOST('multicurrency_subprice') != '') {
1332  $up = price2num(GETPOST('price_ht'), '', 2);
1333  $price_base_type = 'HT';
1334  } else {
1335  $up = price2num(GETPOST('price_ttc'), '', 2);
1336  $price_base_type = 'TTC';
1337  }
1338 
1339  if (GETPOST('productid') > 0) {
1340  $productsupplier = new ProductFournisseur($db);
1341  if (!empty($conf->global->SUPPLIER_INVOICE_WITH_PREDEFINED_PRICES_ONLY)) {
1342  if (GETPOST('productid') > 0 && $productsupplier->get_buyprice(0, price2num(GETPOST('qty')), GETPOST('productid', 'int'), 'restricthtml', GETPOST('socid', 'int')) < 0) {
1343  setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'warnings');
1344  }
1345  }
1346 
1347  $prod = new Product($db);
1348  $prod->fetch(GETPOST('productid'));
1349  $label = $prod->description;
1350  if (trim(GETPOST('product_desc', 'restricthtml')) != trim($label)) {
1351  $label = GETPOST('product_desc', 'restricthtml');
1352  }
1353 
1354  $type = $prod->type;
1355  } else {
1356  $label = GETPOST('product_desc', 'restricthtml');
1357  $type = GETPOST("type") ? GETPOST("type") : 0;
1358  }
1359 
1360  $date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear'));
1361  $date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear'));
1362 
1363  // Define info_bits
1364  $info_bits = 0;
1365  if (preg_match('/\*/', $tva_tx)) {
1366  $info_bits |= 0x01;
1367  }
1368 
1369  // Define vat_rate
1370  $tva_tx = str_replace('*', '', $tva_tx);
1371  $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty);
1372  $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty);
1373 
1374  $remise_percent = price2num(GETPOST('remise_percent'), '', 2);
1375  $pu_devise = price2num(GETPOST('multicurrency_subprice'), 'MU', 2);
1376 
1377  // Extrafields Lines
1378  $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
1379  $array_options = $extrafields->getOptionalsFromPost($object->table_element_line);
1380  // Unset extrafield POST Data
1381  if (is_array($extralabelsline)) {
1382  foreach ($extralabelsline as $key => $value) {
1383  unset($_POST["options_".$key]);
1384  }
1385  }
1386 
1387  $result = $object->updateline(
1388  GETPOST('lineid', 'int'),
1389  $label,
1390  $up,
1391  $tva_tx,
1392  $localtax1_tx,
1393  $localtax2_tx,
1394  price2num(GETPOST('qty'), 'MS'),
1395  GETPOST('productid', 'int'),
1396  $price_base_type,
1397  $info_bits,
1398  $type,
1399  $remise_percent,
1400  0,
1401  $date_start,
1402  $date_end,
1403  $array_options,
1404  GETPOST('units', 'alpha'),
1405  $pu_devise,
1406  GETPOST('fourn_ref', 'alpha')
1407  );
1408  if ($result >= 0) {
1409  unset($_POST['label']);
1410  unset($_POST['fourn_ref']);
1411  unset($_POST['date_starthour']);
1412  unset($_POST['date_startmin']);
1413  unset($_POST['date_startsec']);
1414  unset($_POST['date_startday']);
1415  unset($_POST['date_startmonth']);
1416  unset($_POST['date_startyear']);
1417  unset($_POST['date_endhour']);
1418  unset($_POST['date_endmin']);
1419  unset($_POST['date_endsec']);
1420  unset($_POST['date_endday']);
1421  unset($_POST['date_endmonth']);
1422  unset($_POST['date_endyear']);
1423  unset($_POST['price_ttc']);
1424  unset($_POST['price_ht']);
1425 
1426  $db->commit();
1427  } else {
1428  $db->rollback();
1429  setEventMessages($object->error, $object->errors, 'errors');
1430  }
1431  } elseif ($action == 'addline' && GETPOST('submitforalllines', 'aZ09') && GETPOST('vatforalllines', 'alpha') && $usercancreate) {
1432  // Define vat_rate
1433  $vat_rate = (GETPOST('vatforalllines') ? GETPOST('vatforalllines') : 0);
1434  $vat_rate = str_replace('*', '', $vat_rate);
1435  $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty, $mysoc);
1436  $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty, $mysoc);
1437  foreach ($object->lines as $line) {
1438  $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);
1439  }
1440  } elseif ($action == 'addline' && $usercancreate) {
1441  // Add a product line
1442  $db->begin();
1443 
1444  $ret = $object->fetch($id);
1445  if ($ret < 0) {
1446  dol_print_error($db, $object->error);
1447  exit;
1448  }
1449  $ret = $object->fetch_thirdparty();
1450 
1451  $langs->load('errors');
1452  $error = 0;
1453 
1454  // Set if we used free entry or predefined product
1455  $predef = '';
1456  $product_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : '');
1457  $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'));
1458  $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'));
1459 
1460  $prod_entry_mode = GETPOST('prod_entry_mode');
1461  if ($prod_entry_mode == 'free') {
1462  $idprod = 0;
1463  } else {
1464  $idprod = GETPOST('idprod', 'int');
1465  }
1466 
1467  $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); // Can be '1.2' or '1.2 (CODE)'
1468 
1469  $price_ht = price2num(GETPOST('price_ht'), 'MU', 2);
1470  $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2);
1471  $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2);
1472  $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2);
1473  $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS');
1474 
1475  $remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef, 'alpha'), '', 2) : 0);
1476  if (empty($remise_percent)) {
1477  $remise_percent = 0;
1478  }
1479 
1480  // Extrafields
1481  $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
1482  $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
1483  // Unset extrafield
1484  if (is_array($extralabelsline)) {
1485  // Get extra fields
1486  foreach ($extralabelsline as $key => $value) {
1487  unset($_POST["options_".$key]);
1488  }
1489  }
1490 
1491  if ($prod_entry_mode == 'free' && GETPOST('price_ht') < 0 && $qty < 0) {
1492  setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPrice'), $langs->transnoentitiesnoconv('Qty')), null, 'errors');
1493  $error++;
1494  }
1495  if ($prod_entry_mode == 'free' && !GETPOST('idprodfournprice') && GETPOST('type') < 0) {
1496  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors');
1497  $error++;
1498  }
1499  if ($prod_entry_mode == 'free' && GETPOST('price_ht') === '' && GETPOST('price_ttc') === '' && $price_ht_devise === '') { // Unit price can be 0 but not ''
1500  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('UnitPrice')), null, 'errors');
1501  $error++;
1502  }
1503  if ($prod_entry_mode == 'free' && !GETPOST('dp_desc')) {
1504  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors');
1505  $error++;
1506  }
1507  if (!GETPOST('qty', 'alpha')) { // 0 is NOT allowed for invoices
1508  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
1509  $error++;
1510  }
1511 
1512  if (!$error && isModEnabled('variants') && $prod_entry_mode != 'free') {
1513  if ($combinations = GETPOST('combinations', 'array')) {
1514  //Check if there is a product with the given combination
1515  $prodcomb = new ProductCombination($db);
1516 
1517  if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) {
1518  $idprod = $res->fk_product_child;
1519  } else {
1520  setEventMessages($langs->trans('ErrorProductCombinationNotFound'), null, 'errors');
1521  $error++;
1522  }
1523  }
1524  }
1525 
1526  if ($prod_entry_mode != 'free' && empty($error)) { // With combolist mode idprodfournprice is > 0 or -1. With autocomplete, idprodfournprice is > 0 or ''
1527  $productsupplier = new ProductFournisseur($db);
1528 
1529  $idprod = 0;
1530  if (GETPOST('idprodfournprice', 'alpha') == -1 || GETPOST('idprodfournprice', 'alpha') == '') {
1531  $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, ...)
1532  }
1533 
1534  $reg = array();
1535  if (preg_match('/^idprod_([0-9]+)$/', GETPOST('idprodfournprice', 'alpha'), $reg)) {
1536  $idprod = $reg[1];
1537  $res = $productsupplier->fetch($idprod); // Load product from its id
1538  // Call to init some price properties of $productsupplier
1539  // So if a supplier price already exists for another thirdparty (first one found), we use it as reference price
1540  if (!empty($conf->global->SUPPLIER_TAKE_FIRST_PRICE_IF_NO_PRICE_FOR_CURRENT_SUPPLIER)) {
1541  $fksoctosearch = 0;
1542  $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist
1543  if ($productsupplier->fourn_socid != $socid) { // The price we found is for another supplier, so we clear supplier price
1544  $productsupplier->ref_supplier = '';
1545  }
1546  } else {
1547  $fksoctosearch = $object->thirdparty->id;
1548  $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist
1549  }
1550  } elseif (GETPOST('idprodfournprice', 'alpha') > 0) {
1551  $qtytosearch = $qty; // Just to see if a price exists for the quantity. Not used to found vat.
1552  //$qtytosearch=-1; // We force qty to -1 to be sure to find if a supplier price exist
1553  $idprod = $productsupplier->get_buyprice(GETPOST('idprodfournprice', 'alpha'), $qtytosearch);
1554  $res = $productsupplier->fetch($idprod);
1555  }
1556 
1557  if ($idprod > 0) {
1558  $label = $productsupplier->label;
1559  // Define output language
1560  if (getDolGlobalInt('MAIN_MULTILANGS') && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) {
1561  $outputlangs = $langs;
1562  $newlang = '';
1563  if (empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1564  $newlang = GETPOST('lang_id', 'aZ09');
1565  }
1566  if (empty($newlang)) {
1567  $newlang = $object->thirdparty->default_lang;
1568  }
1569  if (!empty($newlang)) {
1570  $outputlangs = new Translate("", $conf);
1571  $outputlangs->setDefaultLang($newlang);
1572  }
1573  $desc = (!empty($productsupplier->multilangs[$outputlangs->defaultlang]["description"])) ? $productsupplier->multilangs[$outputlangs->defaultlang]["description"] : $productsupplier->description;
1574  } else {
1575  $desc = $productsupplier->description;
1576  }
1577  // if we use supplier description of the products
1578  if (!empty($productsupplier->desc_supplier) && !empty($conf->global->PRODUIT_FOURN_TEXTS)) {
1579  $desc = $productsupplier->desc_supplier;
1580  }
1581 
1582  //If text set in desc is the same as product descpription (as now it's preloaded) whe add it only one time
1583  if (trim($product_desc) == trim($desc) && !empty($conf->global->PRODUIT_AUTOFILL_DESC)) {
1584  $product_desc = '';
1585  }
1586  if (!empty($product_desc) && !empty($conf->global->MAIN_NO_CONCAT_DESCRIPTION)) {
1587  $desc = $product_desc;
1588  }
1589  if (!empty($product_desc) && trim($product_desc) != trim($desc)) {
1590  $desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION));
1591  }
1592 
1593  $ref_supplier = $productsupplier->ref_supplier;
1594 
1595  // Get vat rate
1596  if (!GETPOSTISSET('tva_tx')) { // If vat rate not provided from the form (the form has the priority)
1597  $tva_tx = get_default_tva($object->thirdparty, $mysoc, $productsupplier->id, GETPOST('idprodfournprice', 'alpha'));
1598  $tva_npr = get_default_npr($object->thirdparty, $mysoc, $productsupplier->id, GETPOST('idprodfournprice', 'alpha'));
1599  }
1600  if (empty($tva_tx)) {
1601  $tva_npr = 0;
1602  }
1603  $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty, $tva_npr);
1604  $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty, $tva_npr);
1605 
1606  $type = $productsupplier->type;
1607  if (GETPOST('price_ht') != '' || GETPOST('price_ht_devise') != '') {
1608  $price_base_type = 'HT';
1609  $pu = price2num($price_ht, 'MU');
1610  $pu_devise = price2num($price_ht_devise, 'CU');
1611  } elseif (GETPOST('price_ttc') != '' || GETPOST('price_ttc_devise') != '') {
1612  $price_base_type = 'TTC';
1613  $pu = price2num($price_ttc, 'MU');
1614  $pu_devise = price2num($price_ttc_devise, 'CU');
1615  } else {
1616  $price_base_type = ($productsupplier->fourn_price_base_type ? $productsupplier->fourn_price_base_type : 'HT');
1617  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
1618  $pu = $productsupplier->fourn_pu;
1619  $pu_devise = 0;
1620  } else {
1621  $pu = $productsupplier->fourn_pu;
1622  $pu_devise = $productsupplier->fourn_multicurrency_unitprice;
1623  }
1624  }
1625 
1626  if (empty($pu)) {
1627  $pu = 0; // If pu is '' or null, we force to have a numeric value
1628  }
1629 
1630  $result = $object->addline(
1631  $desc,
1632  $pu,
1633  $tva_tx,
1634  $localtax1_tx,
1635  $localtax2_tx,
1636  $qty,
1637  $idprod,
1638  $remise_percent,
1639  $date_start,
1640  $date_end,
1641  0,
1642  $tva_npr,
1643  $price_base_type,
1644  $type,
1645  min($rank, count($object->lines) + 1),
1646  0,
1647  $array_options,
1648  $productsupplier->fk_unit,
1649  0,
1650  $pu_devise,
1651  GETPOST('fourn_ref', 'alpha'),
1652  ''
1653  );
1654  }
1655  if ($idprod == -99 || $idprod == 0) {
1656  // Product not selected
1657  $error++;
1658  $langs->load("errors");
1659  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductOrService")), null, 'errors');
1660  }
1661  if ($idprod == -1) {
1662  // Quantity too low
1663  $error++;
1664  $langs->load("errors");
1665  setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'errors');
1666  }
1667  } elseif (empty($error)) { // $price_ht is already set
1668  $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
1669  $tva_tx = str_replace('*', '', $tva_tx);
1670  $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
1671  $desc = $product_desc;
1672  $type = GETPOST('type');
1673  $ref_supplier = GETPOST('fourn_ref', 'alpha');
1674 
1675  $fk_unit = GETPOST('units', 'alpha');
1676 
1677  if (!preg_match('/\‍((.*)\‍)/', $tva_tx)) {
1678  $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'
1679  }
1680 
1681  // Local Taxes
1682  $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty);
1683  $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty);
1684 
1685  if (GETPOST('price_ht') != '' || GETPOST('price_ht_devise') != '') {
1686  $pu_ht = price2num($price_ht, 'MU'); // $pu_ht must be rounded according to settings
1687  } else {
1688  $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
1689  $pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU'); // $pu_ht must be rounded according to settings
1690  }
1691  $price_base_type = 'HT';
1692  $pu_devise = price2num($price_devise, 'CU');
1693 
1694  $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);
1695  }
1696 
1697  //print "xx".$tva_tx; exit;
1698  if (!$error && $result > 0) {
1699  $db->commit();
1700 
1701  // Define output language
1702  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
1703  $outputlangs = $langs;
1704  $newlang = '';
1705  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1706  $newlang = GETPOST('lang_id', 'aZ09');
1707  }
1708  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1709  $newlang = $object->thirdparty->default_lang;
1710  }
1711  if (!empty($newlang)) {
1712  $outputlangs = new Translate("", $conf);
1713  $outputlangs->setDefaultLang($newlang);
1714  }
1715  $model = $object->model_pdf;
1716  $ret = $object->fetch($id); // Reload to get new records
1717 
1718  $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1719  if ($result < 0) {
1720  dol_print_error($db, $result);
1721  }
1722  }
1723 
1724  unset($_POST ['prod_entry_mode']);
1725 
1726  unset($_POST['qty']);
1727  unset($_POST['type']);
1728  unset($_POST['remise_percent']);
1729  unset($_POST['pu']);
1730  unset($_POST['price_ht']);
1731  unset($_POST['multicurrency_price_ht']);
1732  unset($_POST['price_ttc']);
1733  unset($_POST['fourn_ref']);
1734  unset($_POST['tva_tx']);
1735  unset($_POST['label']);
1736  unset($localtax1_tx);
1737  unset($localtax2_tx);
1738  unset($_POST['np_marginRate']);
1739  unset($_POST['np_markRate']);
1740  unset($_POST['dp_desc']);
1741  unset($_POST['idprodfournprice']);
1742  unset($_POST['units']);
1743 
1744  unset($_POST['date_starthour']);
1745  unset($_POST['date_startmin']);
1746  unset($_POST['date_startsec']);
1747  unset($_POST['date_startday']);
1748  unset($_POST['date_startmonth']);
1749  unset($_POST['date_startyear']);
1750  unset($_POST['date_endhour']);
1751  unset($_POST['date_endmin']);
1752  unset($_POST['date_endsec']);
1753  unset($_POST['date_endday']);
1754  unset($_POST['date_endmonth']);
1755  unset($_POST['date_endyear']);
1756  } else {
1757  $db->rollback();
1758  setEventMessages($object->error, $object->errors, 'errors');
1759  }
1760 
1761  $action = '';
1762  } elseif ($action == 'classin' && $usercancreate) {
1763  $object->fetch($id);
1764  $result = $object->setProject($projectid);
1765  } elseif ($action == 'confirm_edit' && $confirm == 'yes' && $usercancreate) {
1766  // Set invoice to draft status
1767  $object->fetch($id);
1768 
1769  $totalpaid = $object->getSommePaiement();
1770  $resteapayer = $object->total_ttc - $totalpaid;
1771 
1772  // We check that lines of invoices are exported in accountancy
1773  $ventilExportCompta = $object->getVentilExportCompta();
1774 
1775  if (!$ventilExportCompta) {
1776  // On verifie si aucun paiement n'a ete effectue
1777  if ($resteapayer == price2num($object->total_ttc, 'MT', 1) && $object->statut == FactureFournisseur::STATUS_VALIDATED) {
1778  $idwarehouse = GETPOST('idwarehouse');
1779 
1780  $object->fetch_thirdparty();
1781 
1782  $qualified_for_stock_change = 0;
1783  if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
1784  $qualified_for_stock_change = $object->hasProductsOrServices(2);
1785  } else {
1786  $qualified_for_stock_change = $object->hasProductsOrServices(1);
1787  }
1788 
1789  // Check parameters
1790  if (isModEnabled('stock') && !empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL) && $qualified_for_stock_change) {
1791  $langs->load("stocks");
1792  if (!$idwarehouse || $idwarehouse == -1) {
1793  $error++;
1794  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
1795  $action = '';
1796  }
1797  }
1798 
1799  $object->setDraft($user, $idwarehouse);
1800 
1801  // Define output language
1802  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
1803  $outputlangs = $langs;
1804  $newlang = '';
1805  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1806  $newlang = GETPOST('lang_id', 'aZ09');
1807  }
1808  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1809  $newlang = $object->thirdparty->default_lang;
1810  }
1811  if (!empty($newlang)) {
1812  $outputlangs = new Translate("", $conf);
1813  $outputlangs->setDefaultLang($newlang);
1814  }
1815  $model = $object->model_pdf;
1816  $ret = $object->fetch($id); // Reload to get new records
1817 
1818  $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1819  if ($result < 0) {
1820  dol_print_error($db, $result);
1821  }
1822  }
1823 
1824  $action = '';
1825  }
1826  }
1827  } elseif ($action == 'reopen' && $usercancreate) {
1828  // Set invoice to validated/unpaid status
1829  $result = $object->fetch($id);
1830  if ($object->statut == FactureFournisseur::STATUS_CLOSED
1831  || ($object->statut == FactureFournisseur::STATUS_ABANDONED && $object->close_code != 'replaced')) {
1832  $result = $object->setUnpaid($user);
1833  if ($result > 0) {
1834  header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);
1835  exit;
1836  } else {
1837  setEventMessages($object->error, $object->errors, 'errors');
1838  }
1839  }
1840  }
1841 
1842  // Actions when printing a doc from card
1843  include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
1844 
1845  // Actions to send emails
1846  $triggersendname = 'BILL_SUPPLIER_SENTBYMAIL';
1847  $paramname = 'id';
1848  $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO';
1849  $trackid = 'sinv'.$object->id;
1850  include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
1851 
1852  // Actions to build doc
1853  $upload_dir = $conf->fournisseur->facture->dir_output;
1854  $permissiontoadd = $usercancreate;
1855  include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
1856 
1857  // Make calculation according to calculationrule
1858  if ($action == 'calculate') {
1859  $calculationrule = GETPOST('calculationrule');
1860 
1861  $object->fetch($id);
1862  $object->fetch_thirdparty();
1863  $result = $object->update_price(0, (($calculationrule == 'totalofround') ? '0' : '1'), 0, $object->thirdparty);
1864  if ($result <= 0) {
1865  dol_print_error($db, $result);
1866  exit;
1867  }
1868  }
1869  if ($action == 'update_extras') {
1870  $object->oldcopy = dol_clone($object);
1871 
1872  // Fill array 'array_options' with data from add form
1873  $ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'restricthtml'));
1874  if ($ret < 0) {
1875  $error++;
1876  }
1877 
1878  if (!$error) {
1879  // Actions on extra fields
1880  if (!$error) {
1881  $result = $object->insertExtraFields('BILL_SUPPLIER_MODIFY');
1882  if ($result < 0) {
1883  $error++;
1884  }
1885  }
1886  }
1887 
1888  if ($error) {
1889  $action = 'edit_extras';
1890  }
1891  }
1892 
1893  if (!empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $usercancreate) {
1894  if ($action == 'addcontact') {
1895  $result = $object->fetch($id);
1896 
1897  if ($result > 0 && $id > 0) {
1898  $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
1899  $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
1900  $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09'));
1901  }
1902 
1903  if ($result >= 0) {
1904  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
1905  exit;
1906  } else {
1907  if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
1908  $langs->load("errors");
1909  setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
1910  } else {
1911  setEventMessages($object->error, $object->errors, 'errors');
1912  }
1913  }
1914  } elseif ($action == 'swapstatut') {
1915  // bascule du statut d'un contact
1916  if ($object->fetch($id)) {
1917  $result = $object->swapContactStatus(GETPOST('ligne', 'int'));
1918  } else {
1919  dol_print_error($db);
1920  }
1921  } elseif ($action == 'deletecontact') {
1922  // Efface un contact
1923  $object->fetch($id);
1924  $result = $object->delete_contact(GETPOST("lineid", 'int'));
1925 
1926  if ($result >= 0) {
1927  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
1928  exit;
1929  } else {
1930  dol_print_error($db);
1931  }
1932  }
1933  }
1934 }
1935 
1936 
1937 /*
1938  * View
1939  */
1940 
1941 $form = new Form($db);
1942 $formfile = new FormFile($db);
1943 $bankaccountstatic = new Account($db);
1944 $paymentstatic = new PaiementFourn($db);
1945 if (isModEnabled('project')) {
1946  $formproject = new FormProjets($db);
1947 }
1948 
1949 $now = dol_now();
1950 
1951 $title = $object->ref." - ".$langs->trans('Card');
1952 if ($action == 'create') {
1953  $title = $langs->trans("NewSupplierInvoice");
1954 }
1955 $help_url = 'EN:Module_Suppliers_Invoices|FR:Module_Fournisseurs_Factures|ES:Módulo_Facturas_de_proveedores|DE:Modul_Lieferantenrechnungen';
1956 llxHeader('', $title, $help_url);
1957 
1958 // Mode creation
1959 if ($action == 'create') {
1960  $facturestatic = new FactureFournisseur($db);
1961 
1962  print load_fiche_titre($langs->trans('NewSupplierInvoice'), '', 'supplier_invoice');
1963 
1965 
1966  $currency_code = $conf->currency;
1967 
1968  $societe = '';
1969  if (GETPOST('socid', 'int') > 0) {
1970  $societe = new Societe($db);
1971  $societe->fetch(GETPOST('socid', 'int'));
1972  if (isModEnabled("multicurrency") && !empty($societe->multicurrency_code)) {
1973  $currency_code = $societe->multicurrency_code;
1974  }
1975  }
1976 
1977  if (!empty($origin) && !empty($originid)) {
1978  // Parse element/subelement (ex: project_task)
1979  $element = $subelement = $origin;
1980 
1981  if ($element == 'project') {
1982  $projectid = $originid;
1983  $element = 'projet';
1984  }
1985 
1986  // For compatibility
1987  if ($element == 'order') {
1988  $element = $subelement = 'commande';
1989  }
1990  if ($element == 'propal') {
1991  $element = 'comm/propal'; $subelement = 'propal';
1992  }
1993  if ($element == 'contract') {
1994  $element = $subelement = 'contrat';
1995  }
1996  if ($element == 'order_supplier') {
1997  $element = 'fourn'; $subelement = 'fournisseur.commande';
1998  }
1999 
2000  require_once DOL_DOCUMENT_ROOT.'/'.$element.'/class/'.$subelement.'.class.php';
2001  $classname = ucfirst($subelement);
2002  if ($classname == 'Fournisseur.commande') {
2003  $classname = 'CommandeFournisseur';
2004  }
2005  $objectsrc = new $classname($db);
2006  $objectsrc->fetch($originid);
2007  $objectsrc->fetch_thirdparty();
2008 
2009  $projectid = (!empty($objectsrc->fk_project) ? $objectsrc->fk_project : '');
2010  //$ref_client = (!empty($objectsrc->ref_client)?$object->ref_client:'');
2011 
2012  $soc = $objectsrc->thirdparty;
2013  $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
2014  $mode_reglement_id = (!empty($objectsrc->mode_reglement_id) ? $objectsrc->mode_reglement_id : (!empty($soc->mode_reglement_supplier_id) ? $soc->mode_reglement_supplier_id : 0));
2015  $fk_account = (!empty($objectsrc->fk_account) ? $objectsrc->fk_account : (!empty($soc->fk_account) ? $soc->fk_account : 0));
2016  $remise_percent = (!empty($objectsrc->remise_percent) ? $objectsrc->remise_percent : (!empty($soc->remise_supplier_percent) ? $soc->remise_supplier_percent : 0));
2017  $remise_absolue = (!empty($objectsrc->remise_absolue) ? $objectsrc->remise_absolue : (!empty($soc->remise_absolue) ? $soc->remise_absolue : 0));
2018  $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE) ?-1 : '';
2019  $transport_mode_id = (!empty($objectsrc->transport_mode_id) ? $objectsrc->transport_mode_id : (!empty($soc->transport_mode_id) ? $soc->transport_mode_id : 0));
2020 
2021  if (isModEnabled("multicurrency")) {
2022  if (!empty($objectsrc->multicurrency_code)) {
2023  $currency_code = $objectsrc->multicurrency_code;
2024  }
2025  if (!empty($conf->global->MULTICURRENCY_USE_ORIGIN_TX) && !empty($objectsrc->multicurrency_tx)) {
2026  $currency_tx = $objectsrc->multicurrency_tx;
2027  }
2028  }
2029 
2030  $datetmp = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
2031  $dateinvoice = ($datetmp == '' ? (empty($conf->global->MAIN_AUTOFILL_DATE) ?-1 : '') : $datetmp);
2032  $datetmp = dol_mktime(12, 0, 0, GETPOST('echmonth', 'int'), GETPOST('echday', 'int'), GETPOST('echyear', 'int'));
2033  $datedue = ($datetmp == '' ?-1 : $datetmp);
2034 
2035  // Replicate extrafields
2036  $objectsrc->fetch_optionals();
2037  $object->array_options = $objectsrc->array_options;
2038  } else {
2039  $cond_reglement_id = !empty($societe->cond_reglement_supplier_id) ? $societe->cond_reglement_supplier_id : 0;
2040  $mode_reglement_id = !empty($societe->mode_reglement_supplier_id) ? $societe->mode_reglement_supplier_id : 0;
2041  $transport_mode_id = !empty($societe->transport_mode_supplier_id) ? $societe->transport_mode_supplier_id : 0;
2042  $fk_account = !empty($societe->fk_account) ? $societe->fk_account : 0;
2043  $datetmp = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
2044  $dateinvoice = ($datetmp == '' ? (empty($conf->global->MAIN_AUTOFILL_DATE) ?-1 : '') : $datetmp);
2045  $datetmp = dol_mktime(12, 0, 0, GETPOST('echmonth', 'int'), GETPOST('echday', 'int'), GETPOST('echyear', 'int'));
2046  $datedue = ($datetmp == '' ?-1 : $datetmp);
2047 
2048  if (isModEnabled("multicurrency") && !empty($soc->multicurrency_code)) {
2049  $currency_code = $soc->multicurrency_code;
2050  }
2051  }
2052 
2053  // when payment condition is empty (means not override by payment condition form a other object, like third-party), try to use default value
2054  if (empty($cond_reglement_id)) {
2055  $cond_reglement_id = GETPOST("cond_reglement_id");
2056  }
2057 
2058  // when payment mode is empty (means not override by payment condition form a other object, like third-party), try to use default value
2059  if (empty($mode_reglement_id)) {
2060  $mode_reglement_id = GETPOST("mode_reglement_id");
2061  }
2062 
2063  $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));
2064  $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));
2065 
2066  print '<form name="add" action="'.$_SERVER["PHP_SELF"].'" method="post">';
2067  print '<input type="hidden" name="token" value="'.newToken().'">';
2068  print '<input type="hidden" name="action" value="add">';
2069  if (!empty($societe->id) && $societe->id > 0) {
2070  print '<input type="hidden" name="socid" value="'.$societe->id.'">'."\n";
2071  }
2072  print '<input type="hidden" name="origin" value="'.$origin.'">';
2073  print '<input type="hidden" name="originid" value="'.$originid.'">';
2074  if (!empty($currency_tx)) {
2075  print '<input type="hidden" name="originmulticurrency_tx" value="'.$currency_tx.'">';
2076  }
2077 
2078  print dol_get_fiche_head();
2079 
2080  print '<table class="border centpercent">';
2081 
2082  // Ref
2083  print '<tr><td class="titlefieldcreate">'.$langs->trans('Ref').'</td><td>'.$langs->trans('Draft').'</td></tr>';
2084 
2085  $exampletemplateinvoice = new FactureFournisseurRec($db);
2086  $invoice_predefined = new FactureFournisseurRec($db);
2087  if (empty($origin) && empty($originid) && $fac_recid > 0) {
2088  $invoice_predefined->fetch($fac_recid);
2089  }
2090 
2091  // Third party
2092  print '<tr><td class="fieldrequired">'.$langs->trans('Supplier').'</td>';
2093  print '<td>';
2094 
2095  if (!empty($societe->id) && $societe->id > 0 && ($fac_recid <= 0 || !empty($invoice_predefined->frequency))) {
2096  $absolute_discount = $societe->getAvailableDiscounts('', '', 0, 1);
2097  print $societe->getNomUrl(1, 'supplier');
2098  print '<input type="hidden" name="socid" value="'.$societe->id.'">';
2099  } else {
2100  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');
2101  // reload page to retrieve supplier informations
2102  if (!empty($conf->global->RELOAD_PAGE_ON_SUPPLIER_CHANGE)) {
2103  print '<script type="text/javascript">
2104  $(document).ready(function() {
2105  $("#socid").change(function() {
2106  var socid = $(this).val();
2107  var fac_rec = $(\'#fac_rec\').val();
2108  window.location.href = "'.$_SERVER["PHP_SELF"].'?action=create&socid="+socid+"&fac_rec="+fac_rec;
2109  });
2110  });
2111  </script>';
2112  }
2113  if ($fac_recid <= 0) {
2114  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>';
2115  }
2116  }
2117  print '</td></tr>';
2118 
2119  // Overwrite some values if creation of invoice is from a predefined invoice
2120  if (empty($origin) && empty($originid) && $fac_recid > 0) {
2121  $invoice_predefined->fetch($fac_recid);
2122 
2123  $dateinvoice = $invoice_predefined->date_when; // To use next gen date by default later
2124  if (empty($projectid)) {
2125  $projectid = $invoice_predefined->fk_project;
2126  }
2127  $cond_reglement_id = $invoice_predefined->cond_reglement_id;
2128  $mode_reglement_id = $invoice_predefined->mode_reglement_id;
2129  $fk_account = $invoice_predefined->fk_account;
2130  $note_public = $invoice_predefined->note_public;
2131  $note_private = $invoice_predefined->note_private;
2132 
2133  if (!empty($invoice_predefined->multicurrency_code)) {
2134  $currency_code = $invoice_predefined->multicurrency_code;
2135  }
2136  if (!empty($invoice_predefined->multicurrency_tx)) {
2137  $currency_tx = $invoice_predefined->multicurrency_tx;
2138  }
2139 
2140  $sql = 'SELECT r.rowid, r.titre as title, r.total_ttc';
2141  $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_rec as r';
2142  $sql .= ' WHERE r.fk_soc = '. (int) $invoice_predefined->socid;
2143 
2144  $resql = $db->query($sql);
2145  if ($resql) {
2146  $num = $db->num_rows($resql);
2147  $i = 0;
2148 
2149  if ($num > 0) {
2150  print '<tr><td>'.$langs->trans('CreateFromRepeatableInvoice').'</td><td>';
2151  //print '<input type="hidden" name="fac_rec" id="fac_rec" value="'.$fac_recid.'">';
2152  print '<select class="flat" id="fac_rec" name="fac_rec">'; // We may want to change the template to use
2153  print '<option value="0" selected></option>';
2154  while ($i < $num) {
2155  $objp = $db->fetch_object($resql);
2156  print '<option value="'.$objp->rowid.'"';
2157  if ($fac_recid == $objp->rowid) {
2158  print ' selected';
2159  $exampletemplateinvoice->fetch($fac_recid);
2160  }
2161  print '>'.$objp->title.' ('.price($objp->total_ttc).' '.$langs->trans("TTC").')</option>';
2162  $i++;
2163  }
2164  print '</select>';
2165  // Option to reload page to retrieve customer informations. Note, this clear other input
2166  if (empty($conf->global->RELOAD_PAGE_ON_TEMPLATE_CHANGE_DISABLED)) {
2167  print '<script type="text/javascript">
2168  $(document).ready(function() {
2169  $("#fac_rec").change(function() {
2170  console.log("We have changed the template invoice - Reload page");
2171  var fac_rec = $(this).val();
2172  var socid = $(\'#socid\').val();
2173  // For template invoice change, we must reuse data of template, not input already done, so we call a GET with action=create, not a POST submit.
2174  window.location.href = "'.$_SERVER["PHP_SELF"].'?action=create&socid="+socid+"&fac_rec="+fac_rec;
2175  });
2176  });
2177  </script>';
2178  }
2179  print '</td></tr>';
2180  }
2181  $db->free($resql);
2182  } else {
2183  dol_print_error($db);
2184  }
2185  }
2186 
2187  // Ref supplier
2188  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"';
2189  if (!empty($societe->id) && $societe->id > 0) {
2190  print ' autofocus';
2191  }
2192  print '></td>';
2193  print '</tr>';
2194 
2195  print '<tr><td class="tdtop fieldrequired">'.$langs->trans('Type').'</td><td>';
2196 
2197  print '<div class="tagtable">'."\n";
2198 
2199  // Standard invoice
2200  print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2201  $tmp = '<input type="radio" id="radio_standard" name="type" value="0"'.(GETPOST('type', 'int')? '' : 'checked').'> ';
2202  $desc = $form->textwithpicto($tmp.$langs->trans("InvoiceStandardAsk"), $langs->transnoentities("InvoiceStandardDesc"), 1, 'help', '', 0, 3);
2203  print $desc;
2204  print '</div></div>';
2205 
2206  if (empty($origin) || ($origin == 'order_supplier' && !empty($originid))) {
2207  // Deposit - Down payment
2208  if (empty($conf->global->INVOICE_DISABLE_DEPOSIT)) {
2209  print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2210  $tmp='<input type="radio" id="radio_deposit" name="type" value="3"' . (GETPOST('type') == 3 ? ' checked' : '') . '> ';
2211  print '<script type="text/javascript">
2212  jQuery(document).ready(function() {
2213  jQuery("#typestandardinvoice, #valuestandardinvoice").click(function() {
2214  jQuery("#radio_standard").prop("checked", true);
2215  });
2216  jQuery("#typedeposit, #valuedeposit").click(function() {
2217  jQuery("#radio_deposit").prop("checked", true);
2218  });
2219  jQuery("#typedeposit").change(function() {
2220  console.log("We change type of down payment");
2221  jQuery("#radio_deposit").prop("checked", true);
2222  setRadioForTypeOfInvoice();
2223  });
2224  jQuery("#radio_standard, #radio_deposit, #radio_replacement, #radio_template").change(function() {
2225  setRadioForTypeOfInvoice();
2226  });
2227  function setRadioForTypeOfInvoice() {
2228  console.log("Change radio");
2229  if (jQuery("#radio_deposit").prop("checked") && (jQuery("#typedeposit").val() == \'amount\' || jQuery("#typedeposit").val() == \'variable\')) {
2230  jQuery(".checkforselect").prop("disabled", true);
2231  jQuery(".checkforselect").prop("checked", false);
2232  } else {
2233  jQuery(".checkforselect").prop("disabled", false);
2234  jQuery(".checkforselect").prop("checked", true);
2235  }
2236  }
2237  });
2238  </script>';
2239 
2240  $tmp = $tmp.'<label for="radio_deposit" >'.$langs->trans("InvoiceDeposit").'</label>';
2241  $desc = $form->textwithpicto($tmp, $langs->transnoentities("InvoiceDepositDesc"), 1, 'help', '', 0, 3);
2242  print '<table class="nobordernopadding"><tr>';
2243  print '<td>';
2244  print $desc;
2245  print '</td>';
2246  if ($origin == 'order_supplier') {
2247  print '<td class="nowrap" style="padding-left: 15px">';
2248  $arraylist = array(
2249  'amount' => $langs->transnoentitiesnoconv('FixAmount', $langs->transnoentitiesnoconv('Deposit')),
2250  'variable' => $langs->transnoentitiesnoconv('VarAmountOneLine', $langs->transnoentitiesnoconv('Deposit')),
2251  'variablealllines' => $langs->transnoentitiesnoconv('VarAmountAllLines')
2252  );
2253  print $form->selectarray('typedeposit', $arraylist, GETPOST('typedeposit', 'aZ09'), 0, 0, 0, '', 1);
2254  print '</td>';
2255  print '<td class="nowrap" style="padding-left: 5px">';
2256  print '<span class="opacitymedium paddingleft">'.$langs->trans("AmountOrPercent").'</span><input type="text" id="valuedeposit" name="valuedeposit" class="width75 right" value="' . GETPOST('valuedeposit', 'int') . '"/>';
2257  print '</td>';
2258  }
2259  print '</tr></table>';
2260 
2261  print '</div></div>';
2262  }
2263  }
2264 
2265  /* Not yet supported for supplier
2266  if ($societe->id > 0)
2267  {
2268  // Replacement
2269  if (empty($conf->global->INVOICE_DISABLE_REPLACEMENT))
2270  {
2271  // Type invoice
2272  $facids = $facturestatic->list_replacable_supplier_invoices($societe->id);
2273  if ($facids < 0) {
2274  dol_print_error($db, $facturestatic->error, $facturestatic->errors);
2275  exit();
2276  }
2277  $options = "";
2278  foreach ($facids as $facparam)
2279  {
2280  $options .= '<option value="' . $facparam ['id'] . '"';
2281  if ($facparam ['id'] == GETPOST('fac_replacement') {
2282  $options .= ' selected';
2283  }
2284  $options .= '>' . $facparam ['ref'];
2285  $options .= ' (' . $facturestatic->LibStatut(0, $facparam ['status']) . ')';
2286  $options .= '</option>';
2287  }
2288 
2289  print '<!-- replacement line -->';
2290  print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2291  $tmp='<input type="radio" name="type" id="radio_replacement" value="1"' . (GETPOST('type') == 1 ? ' checked' : '');
2292  if (! $options) $tmp.=' disabled';
2293  $tmp.='> ';
2294  print '<script type="text/javascript">
2295  jQuery(document).ready(function() {
2296  jQuery("#fac_replacement").change(function() {
2297  jQuery("#radio_replacement").prop("checked", true);
2298  });
2299  });
2300  </script>';
2301  $text = $tmp.$langs->trans("InvoiceReplacementAsk") . ' ';
2302  $text .= '<select class="flat" name="fac_replacement" id="fac_replacement"';
2303  if (! $options)
2304  $text .= ' disabled';
2305  $text .= '>';
2306  if ($options) {
2307  $text .= '<option value="-1">&nbsp;</option>';
2308  $text .= $options;
2309  } else {
2310  $text .= '<option value="-1">' . $langs->trans("NoReplacableInvoice") . '</option>';
2311  }
2312  $text .= '</select>';
2313  $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceReplacementDesc"), 1, 'help', '', 0, 3);
2314  print $desc;
2315  print '</div></div>';
2316  }
2317  }
2318  else
2319  {
2320  print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2321  $tmp='<input type="radio" name="type" id="radio_replacement" value="0" disabled> ';
2322  $text = $tmp.$langs->trans("InvoiceReplacement") . ' ';
2323  $text.= '('.$langs->trans("YouMustCreateInvoiceFromSupplierThird").') ';
2324  $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceReplacementDesc"), 1, 'help', '', 0, 3);
2325  print $desc;
2326  print '</div></div>';
2327  }
2328  */
2329 
2330  if (empty($origin)) {
2331  if (!empty($societe->id) && $societe->id > 0) {
2332  // Credit note
2333  if (empty($conf->global->INVOICE_DISABLE_CREDIT_NOTE)) {
2334  // Show link for credit note
2335  $facids = $facturestatic->list_qualified_avoir_supplier_invoices($societe->id);
2336  if ($facids < 0) {
2337  dol_print_error($db, $facturestatic->error, $facturestatic->errors);
2338  exit;
2339  }
2340  $optionsav = "";
2341  $newinvoice_static = new FactureFournisseur($db);
2342  foreach ($facids as $key => $valarray) {
2343  $newinvoice_static->id = $key;
2344  $newinvoice_static->ref = $valarray ['ref'];
2345  $newinvoice_static->statut = $valarray ['status'];
2346  $newinvoice_static->type = $valarray ['type'];
2347  $newinvoice_static->paye = $valarray ['paye'];
2348 
2349  $optionsav .= '<option value="'.$key.'"';
2350  if ($key == GETPOST('fac_avoir', 'int')) {
2351  $optionsav .= ' selected';
2352  }
2353  $optionsav .= '>';
2354  $optionsav .= $newinvoice_static->ref;
2355  $optionsav .= ' ('.$newinvoice_static->getLibStatut(1, $valarray ['paymentornot']).')';
2356  $optionsav .= '</option>';
2357  }
2358 
2359  print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2360  $tmp = '<input type="radio" id="radio_creditnote" name="type" value="2"'.(GETPOST('type') == 2 ? ' checked' : '');
2361  if (!$optionsav && empty($conf->global->INVOICE_CREDIT_NOTE_STANDALONE)) {
2362  $tmp .= ' disabled';
2363  }
2364  $tmp .= '> ';
2365  // Show credit note options only if we checked credit note
2366  print '<script type="text/javascript">
2367  jQuery(document).ready(function() {
2368  if (! jQuery("#radio_creditnote").is(":checked"))
2369  {
2370  jQuery("#credit_note_options").hide();
2371  }
2372  jQuery("#radio_creditnote").click(function() {
2373  jQuery("#credit_note_options").show();
2374  });
2375  jQuery("#radio_standard, #radio_replacement, #radio_deposit").click(function() {
2376  jQuery("#credit_note_options").hide();
2377  });
2378  });
2379  </script>';
2380  $text = $tmp.$langs->transnoentities("InvoiceAvoirAsk").' ';
2381  // $text.='<input type="text" value="">';
2382  $text .= '<select class="flat valignmiddle" name="fac_avoir" id="fac_avoir"';
2383  if (!$optionsav) {
2384  $text .= ' disabled';
2385  }
2386  $text .= '>';
2387  if ($optionsav) {
2388  $text .= '<option value="-1"></option>';
2389  $text .= $optionsav;
2390  } else {
2391  $text .= '<option value="-1">'.$langs->trans("NoInvoiceToCorrect").'</option>';
2392  }
2393  $text .= '</select>';
2394  $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1, 'help', '', 0, 3);
2395  print $desc;
2396 
2397  print '<div id="credit_note_options" class="clearboth">';
2398  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' : '').' /> ';
2399  print '<label for="invoiceAvoirWithLines">'.$langs->trans('invoiceAvoirWithLines')."</label>";
2400  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' : '').' /> ';
2401  print '<label for="invoiceAvoirWithPaymentRestAmount">'.$langs->trans('invoiceAvoirWithPaymentRestAmount')."</label>";
2402  print '</div>';
2403 
2404  print '</div></div>';
2405  }
2406  } else {
2407  print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2408  if (empty($conf->global->INVOICE_CREDIT_NOTE_STANDALONE)) {
2409  $tmp = '<input type="radio" name="type" id="radio_creditnote" value="0" disabled> ';
2410  } else {
2411  $tmp='<input type="radio" name="type" id="radio_creditnote" value="2"> ';
2412  }
2413  $text = $tmp.$langs->trans("InvoiceAvoir").' ';
2414  $text .= '<span class="opacitymedium">('.$langs->trans("YouMustCreateInvoiceFromSupplierThird").')</span> ';
2415  $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1, 'help', '', 0, 3);
2416  print $desc;
2417  print '</div></div>'."\n";
2418  }
2419  }
2420 
2421  print '</div>';
2422 
2423  print '</td></tr>';
2424 
2425  if (!empty($societe->id) && $societe->id > 0) {
2426  // Discounts for third party
2427  print '<tr><td>'.$langs->trans('Discounts').'</td><td>';
2428 
2429  $thirdparty = $societe;
2430  $discount_type = 1;
2431  $backtopage = urlencode($_SERVER["PHP_SELF"].'?socid='.$societe->id.'&action='.$action.'&origin='.GETPOST('origin').'&originid='.GETPOST('originid'));
2432  include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
2433 
2434  print '</td></tr>';
2435  }
2436 
2437  // Label
2438  print '<tr><td>'.$langs->trans('Label').'</td><td><input class="minwidth200" name="label" value="'.dol_escape_htmltag(GETPOST('label')).'" type="text"></td></tr>';
2439 
2440  // Date invoice
2441  print '<tr><td class="fieldrequired">'.$langs->trans('DateInvoice').'</td><td>';
2442  print $form->selectDate($dateinvoice, '', '', '', '', "add", 1, 1);
2443  print '</td></tr>';
2444 
2445  // Due date
2446  print '<tr><td>'.$langs->trans('DateMaxPayment').'</td><td>';
2447  print $form->selectDate($datedue, 'ech', '', '', '', "add", 1, 1);
2448  print '</td></tr>';
2449 
2450  // Payment term
2451  print '<tr><td class="nowrap">'.$langs->trans('PaymentConditionsShort').'</td><td>';
2452  print $form->getSelectConditionsPaiements(GETPOSTISSET('cond_reglement_id') ?GETPOST('cond_reglement_id', 'int') : $cond_reglement_id, 'cond_reglement_id');
2453  print '</td></tr>';
2454 
2455  // Payment mode
2456  print '<tr><td>'.$langs->trans('PaymentMode').'</td><td>';
2457  print img_picto('', 'bank', 'class="pictofixedwidth"');
2458  $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');
2459  print '</td></tr>';
2460 
2461  // Bank Account
2462  if (isModEnabled("banque")) {
2463  print '<tr><td>'.$langs->trans('BankAccount').'</td><td>';
2464  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);
2465  print '</td></tr>';
2466  }
2467 
2468  // Project
2469  if (isModEnabled('project')) {
2470  $formproject = new FormProjets($db);
2471 
2472  $langs->load('projects');
2473  print '<tr><td>'.$langs->trans('Project').'</td><td>';
2474  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');
2475  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>';
2476  print '</td></tr>';
2477  }
2478 
2479  // Incoterms
2480  if (isModEnabled('incoterm')) {
2481  print '<tr>';
2482  print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), !empty($objectsrc->label_incoterms) ? $objectsrc->label_incoterms : '', 1).'</label></td>';
2483  print '<td colspan="3" class="maxwidthonsmartphone">';
2484  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 : ''));
2485  print '</td></tr>';
2486  }
2487 
2488  // Multicurrency
2489  if (isModEnabled("multicurrency")) {
2490  print '<tr>';
2491  print '<td>'.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).'</td>';
2492  print '<td class="maxwidthonsmartphone">';
2493  print $form->selectMultiCurrency((GETPOSTISSET('multicurrency_code') ?GETPOST('multicurrency_code', 'alpha') : $currency_code), 'multicurrency_code');
2494  print '</td></tr>';
2495  }
2496 
2497  // Help of substitution key
2498  $htmltext = '';
2499  if ($fac_recid > 0) {
2500  $dateexample = $newdateinvoice ? $newdateinvoice : $dateinvoice;
2501  if (empty($dateexample)) {
2502  $dateexample = dol_now();
2503  }
2504  $substitutionarray = array(
2505  '__TOTAL_HT__' => $langs->trans("AmountHT").' ('.$langs->trans("Example").': '.price($exampletemplateinvoice->total_ht).')',
2506  '__TOTAL_TTC__' => $langs->trans("AmountTTC").' ('.$langs->trans("Example").': '.price($exampletemplateinvoice->total_ttc).')',
2507  '__INVOICE_PREVIOUS_MONTH__' => $langs->trans("PreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%m').')',
2508  '__INVOICE_MONTH__' => $langs->trans("MonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%m').')',
2509  '__INVOICE_NEXT_MONTH__' => $langs->trans("NextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%m').')',
2510  '__INVOICE_PREVIOUS_MONTH_TEXT__' => $langs->trans("TextPreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%B').')',
2511  '__INVOICE_MONTH_TEXT__' => $langs->trans("TextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%B').')',
2512  '__INVOICE_NEXT_MONTH_TEXT__' => $langs->trans("TextNextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%B').')',
2513  '__INVOICE_PREVIOUS_YEAR__' => $langs->trans("PreviousYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'y'), '%Y').')',
2514  '__INVOICE_YEAR__' => $langs->trans("YearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%Y').')',
2515  '__INVOICE_NEXT_YEAR__' => $langs->trans("NextYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'y'), '%Y').')'
2516  );
2517 
2518  $htmltext = '<i>'.$langs->trans("FollowingConstantsWillBeSubstituted").':<br>';
2519  foreach ($substitutionarray as $key => $val) {
2520  $htmltext .= $key.' = '.$langs->trans($val).'<br>';
2521  }
2522  $htmltext .= '</i>';
2523  }
2524 
2525  // Intracomm report
2526  if (isModEnabled('intracommreport')) {
2527  $langs->loadLangs(array("intracommreport"));
2528  print '<tr><td>'.$langs->trans('IntracommReportTransportMode').'</td><td>';
2529  $form->selectTransportMode(GETPOSTISSET('transport_mode_id') ? GETPOST('transport_mode_id') : $transport_mode_id, 'transport_mode_id');
2530  print '</td></tr>';
2531  }
2532 
2533  if (empty($reshook)) {
2534  print $object->showOptionals($extrafields, 'create');
2535  }
2536 
2537  // Public note
2538  print '<tr><td>'.$langs->trans('NotePublic').'</td>';
2539  print '<td>';
2540  $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%');
2541  print $doleditor->Create(1);
2542  print '</td>';
2543  // print '<td><textarea name="note" wrap="soft" cols="60" rows="'.ROWS_5.'"></textarea></td>';
2544  print '</tr>';
2545 
2546  // Private note
2547  print '<tr><td>'.$langs->trans('NotePrivate').'</td>';
2548  print '<td>';
2549  $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%');
2550  print $doleditor->Create(1);
2551  print '</td>';
2552  // print '<td><textarea name="note" wrap="soft" cols="60" rows="'.ROWS_5.'"></textarea></td>';
2553  print '</tr>';
2554 
2555 
2556  if (!empty($objectsrc) && is_object($objectsrc)) {
2557  print "\n<!-- ".$classname." info -->";
2558  print "\n";
2559  print '<input type="hidden" name="amount" value="'.$objectsrc->total_ht.'">'."\n";
2560  print '<input type="hidden" name="total" value="'.$objectsrc->total_ttc.'">'."\n";
2561  print '<input type="hidden" name="tva" value="'.$objectsrc->total_tva.'">'."\n";
2562  print '<input type="hidden" name="origin" value="'.$objectsrc->element.'">';
2563  print '<input type="hidden" name="originid" value="'.$objectsrc->id.'">';
2564 
2565  $txt = $langs->trans($classname);
2566  if ($classname == 'CommandeFournisseur') {
2567  $langs->load('orders');
2568  $txt = $langs->trans("SupplierOrder");
2569  }
2570  print '<tr><td>'.$txt.'</td><td>'.$objectsrc->getNomUrl(1);
2571  // We check if Origin document (id and type is known) has already at least one invoice attached to it
2572  $objectsrc->fetchObjectLinked($originid, $origin, '', 'invoice_supplier');
2573 
2574  $invoice_supplier = $objectsrc->linkedObjects['invoice_supplier'];
2575 
2576  // count function need a array as argument (Note: the array must implement Countable too)
2577  if (is_array($invoice_supplier)) {
2578  $cntinvoice = count($invoice_supplier);
2579 
2580  if ($cntinvoice >= 1) {
2581  setEventMessages('WarningBillExist', null, 'warnings');
2582  echo ' ('.$langs->trans('LatestRelatedBill').end($invoice_supplier)->getNomUrl(1).')';
2583  }
2584  }
2585 
2586  print '</td></tr>';
2587  print '<tr><td>'.$langs->trans('AmountHT').'</td><td>'.price($objectsrc->total_ht).'</td></tr>';
2588  print '<tr><td>'.$langs->trans('AmountVAT').'</td><td>'.price($objectsrc->total_tva)."</td></tr>";
2589  if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) { //Localtax1
2590  print '<tr><td>'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax1)."</td></tr>";
2591  }
2592 
2593  if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) { //Localtax2
2594  print '<tr><td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax2)."</td></tr>";
2595  }
2596  print '<tr><td>'.$langs->trans('AmountTTC').'</td><td>'.price($objectsrc->total_ttc)."</td></tr>";
2597 
2598  if (isModEnabled("multicurrency")) {
2599  print '<tr><td>'.$langs->trans('MulticurrencyAmountHT').'</td><td>'.price($objectsrc->multicurrency_total_ht).'</td></tr>';
2600  print '<tr><td>'.$langs->trans('MulticurrencyAmountVAT').'</td><td>'.price($objectsrc->multicurrency_total_tva)."</td></tr>";
2601  print '<tr><td>'.$langs->trans('MulticurrencyAmountTTC').'</td><td>'.price($objectsrc->multicurrency_total_ttc)."</td></tr>";
2602  }
2603  }
2604 
2605  // Other options
2606  $parameters = array();
2607  $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2608  print $hookmanager->resPrint;
2609 
2610 
2611  print "</table>\n";
2612 
2613  print dol_get_fiche_end();
2614 
2615  print $form->buttonsSaveCancel("CreateDraft");
2616 
2617  // Show origin lines
2618  if (!empty($objectsrc) && is_object($objectsrc)) {
2619  print '<br>';
2620 
2621  $title = $langs->trans('ProductsAndServices');
2622  print load_fiche_titre($title);
2623 
2624  print '<div class="div-table-responsive-no-min">';
2625  print '<table class="noborder centpercent">';
2626 
2627  $objectsrc->printOriginLinesList('', $selectedLines);
2628 
2629  print '</table>';
2630  print '</div>';
2631  }
2632 
2633  print "</form>\n";
2634 } else {
2635  if ($id > 0 || !empty($ref)) {
2636  //
2637  // View or edit mode
2638  //
2639  $now = dol_now();
2640 
2641  $productstatic = new Product($db);
2642 
2643  $result = $object->fetch($id, $ref);
2644  if ($result <= 0) {
2645  $langs->load("errors");
2646  print $langs->trans("ErrorRecordNotFound");
2647  llxFooter();
2648  $db->close();
2649  exit;
2650  }
2651 
2652  $result = $object->fetch_thirdparty();
2653  if ($result < 0) {
2654  dol_print_error($db, $object->error, $object->errors);
2655  exit;
2656  }
2657 
2658  $societe = $object->thirdparty;
2659 
2660  $totalpaid = $object->getSommePaiement();
2661  $totalcreditnotes = $object->getSumCreditNotesUsed();
2662  $totaldeposits = $object->getSumDepositsUsed();
2663  // print "totalpaid=".$totalpaid." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits."
2664  // selleruserrevenuestamp=".$selleruserevenustamp;
2665 
2666  // We can also use bcadd to avoid pb with floating points
2667  // For example print 239.2 - 229.3 - 9.9; does not return 0.
2668  // $resteapayer=bcadd($object->total_ttc,$totalpaid,$conf->global->MAIN_MAX_DECIMALS_TOT);
2669  // $resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT);
2670  $resteapayer = price2num($object->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits, 'MT');
2671 
2672  // Multicurrency
2673  $multicurrency_resteapayer = 0;
2674  if (isModEnabled("multicurrency")) {
2675  $multicurrency_totalpaid = $object->getSommePaiement(1);
2676  $multicurrency_totalcreditnotes = $object->getSumCreditNotesUsed(1);
2677  $multicurrency_totaldeposits = $object->getSumDepositsUsed(1);
2678  $multicurrency_resteapayer = price2num($object->multicurrency_total_ttc - $multicurrency_totalpaid - $multicurrency_totalcreditnotes - $multicurrency_totaldeposits, 'MT');
2679  // Code to fix case of corrupted data
2680  // 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
2681  // 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)
2682  if ($resteapayer == 0 && $multicurrency_resteapayer != 0 && $object->multicurrency_code != $conf->currency) {
2683  $resteapayer = price2num($multicurrency_resteapayer / $object->multicurrency_tx, 'MT');
2684  }
2685  }
2686 
2687  if ($object->paye) {
2688  $resteapayer = 0;
2689  }
2690  $resteapayeraffiche = $resteapayer;
2691 
2692  if (!empty($conf->global->FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS)) { // Never use this
2693  $filterabsolutediscount = "fk_invoice_supplier_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
2694  $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
2695  } else {
2696  $filterabsolutediscount = "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')";
2697  $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')";
2698  }
2699 
2700  $absolute_discount = $societe->getAvailableDiscounts('', $filterabsolutediscount, 0, 1);
2701  $absolute_creditnote = $societe->getAvailableDiscounts('', $filtercreditnote, 0, 1);
2702  $absolute_discount = price2num($absolute_discount, 'MT');
2703  $absolute_creditnote = price2num($absolute_creditnote, 'MT');
2704 
2705  /*
2706  * View card
2707  */
2708  $objectidnext = $object->getIdReplacingInvoice();
2709 
2710  $head = facturefourn_prepare_head($object);
2711  $titre = $langs->trans('SupplierInvoice');
2712 
2713  print dol_get_fiche_head($head, 'card', $titre, -1, 'supplier_invoice');
2714 
2715  $formconfirm = '';
2716 
2717  // Confirmation de la conversion de l'avoir en reduc
2718  if ($action == 'converttoreduc') {
2719  $type_fac = '';
2720  if ($object->type == FactureFournisseur::TYPE_STANDARD) {
2721  $type_fac = 'ExcessPaid';
2722  } elseif ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
2723  $type_fac = 'CreditNote';
2724  } elseif ($object->type == FactureFournisseur::TYPE_DEPOSIT) {
2725  $type_fac = 'Deposit';
2726  }
2727  $text = $langs->trans('ConfirmConvertToReducSupplier', strtolower($langs->transnoentities($type_fac)));
2728  $text .= '<br>'.$langs->trans('ConfirmConvertToReducSupplier2');
2729  $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id, $langs->trans('ConvertToReduc'), $text, 'confirm_converttoreduc', '', "yes", 2);
2730  }
2731 
2732  // Clone confirmation
2733  if ($action == 'clone') {
2734  // Create an array for form
2735  $formquestion = array(
2736  array('type' => 'text', 'name' => 'newsupplierref', 'label' => $langs->trans("RefSupplier"), 'value' => $langs->trans("CopyOf").' '.$object->ref_supplier),
2737  array('type' => 'date', 'name' => 'newdate', 'label' => $langs->trans("Date"), 'value' => dol_now())
2738  );
2739  // Ask confirmation to clone
2740  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneInvoice', $object->ref), 'confirm_clone', $formquestion, 'yes', 1, 250);
2741  }
2742 
2743  // Confirmation of validation
2744  if ($action == 'valid') {
2745  // We check if number is temporary number
2746  if (preg_match('/^[\‍(]?PROV/i', $object->ref) || empty($object->ref)) {
2747  // empty should not happened, but when it occurs, the test save life
2748  $numref = $object->getNextNumRef($societe);
2749  } else {
2750  $numref = $object->ref;
2751  }
2752 
2753  if ($numref < 0) {
2754  setEventMessages($object->error, $object->errors, 'errors');
2755  $action = '';
2756  } else {
2757  $text = $langs->trans('ConfirmValidateBill', $numref);
2758  /*if (isModEnabled('notification'))
2759  {
2760  require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php';
2761  $notify=new Notify($db);
2762  $text.='<br>';
2763  $text.=$notify->confirmMessage('BILL_SUPPLIER_VALIDATE',$object->socid, $object);
2764  }*/
2765  $formquestion = array();
2766 
2767  $qualified_for_stock_change = 0;
2768  if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
2769  $qualified_for_stock_change = $object->hasProductsOrServices(2);
2770  } else {
2771  $qualified_for_stock_change = $object->hasProductsOrServices(1);
2772  }
2773 
2774  if (isModEnabled('stock') && !empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL) && $qualified_for_stock_change) {
2775  $langs->load("stocks");
2776  require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
2777  $formproduct = new FormProduct($db);
2778  $warehouse = new Entrepot($db);
2779  $warehouse_array = $warehouse->list_array();
2780  if (count($warehouse_array) == 1) {
2781  $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("WarehouseForStockDecrease", current($warehouse_array)) : $langs->trans("WarehouseForStockIncrease", current($warehouse_array));
2782  $value = '<input type="hidden" id="idwarehouse" name="idwarehouse" value="'.key($warehouse_array).'">';
2783  } else {
2784  $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("SelectWarehouseForStockDecrease") : $langs->trans("SelectWarehouseForStockIncrease");
2785  $value = $formproduct->selectWarehouses(GETPOST('idwarehouse') ?GETPOST('idwarehouse') : 'ifone', 'idwarehouse', '', 1);
2786  }
2787  $formquestion = array(
2788  array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $value)
2789  );
2790  }
2791 
2792  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateBill'), $text, 'confirm_valid', $formquestion, 1, 1);
2793  }
2794  }
2795 
2796  // Confirmation edit (back to draft)
2797  if ($action == 'edit') {
2798  $formquestion = array();
2799 
2800  $qualified_for_stock_change = 0;
2801  if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
2802  $qualified_for_stock_change = $object->hasProductsOrServices(2);
2803  } else {
2804  $qualified_for_stock_change = $object->hasProductsOrServices(1);
2805  }
2806  if (isModEnabled('stock') && !empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL) && $qualified_for_stock_change) {
2807  $langs->load("stocks");
2808  require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
2809  $formproduct = new FormProduct($db);
2810  $warehouse = new Entrepot($db);
2811  $warehouse_array = $warehouse->list_array();
2812  if (count($warehouse_array) == 1) {
2813  $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("WarehouseForStockIncrease", current($warehouse_array)) : $langs->trans("WarehouseForStockDecrease", current($warehouse_array));
2814  $value = '<input type="hidden" id="idwarehouse" name="idwarehouse" value="'.key($warehouse_array).'">';
2815  } else {
2816  $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("SelectWarehouseForStockIncrease") : $langs->trans("SelectWarehouseForStockDecrease");
2817  $value = $formproduct->selectWarehouses(GETPOST('idwarehouse') ?GETPOST('idwarehouse') : 'ifone', 'idwarehouse', '', 1);
2818  }
2819  $formquestion = array(
2820  array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $value)
2821  );
2822  }
2823  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('UnvalidateBill'), $langs->trans('ConfirmUnvalidateBill', $object->ref), 'confirm_edit', $formquestion, 1, 1);
2824  }
2825 
2826  // Confirmation set paid
2827  if ($action == 'paid' && ($resteapayer <= 0 || (!empty($conf->global->SUPPLIER_INVOICE_CAN_SET_PAID_EVEN_IF_PARTIALLY_PAID) && $resteapayer == $object->total_ttc))) {
2828  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidBill', $object->ref), 'confirm_paid', '', 0, 1);
2829  }
2830 
2831  if ($action == 'paid' && $resteapayer > 0 && (empty($conf->global->SUPPLIER_INVOICE_CAN_SET_PAID_EVEN_IF_PARTIALLY_PAID) || $resteapayer != $object->total_ttc)) {
2832  $close = array();
2833  // Code
2834  $i = 0;
2835  $close[$i]['code'] = 'discount_vat'; // escompte
2836  $i++;
2837  $close[$i]['code'] = 'badsupplier';
2838  $i++;
2839  $close[$i]['code'] = 'other';
2840  $i++;
2841  // Help
2842  $i = 0;
2843  $close[$i]['label'] = $langs->trans("HelpEscompte").'<br><br>'.$langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");
2844  $i++;
2845  $close[$i]['label'] = $langs->trans("ConfirmClassifyPaidPartiallyReasonBadSupplierDesc");
2846  $i++;
2847  $close[$i]['label'] = $langs->trans("Other");
2848  $i++;
2849  // Text
2850  $i = 0;
2851  $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscount", $resteapayer, $langs->trans("Currency".$conf->currency)), $close[$i]['label'], 1);
2852  $i++;
2853  $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer", $resteapayer, $langs->trans("Currency".$conf->currency)), $close[$i]['label'], 1);
2854  $i++;
2855  $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("Other"), $close[$i]['label'], 1);
2856  $i++;
2857  // arrayreasons[code]=reason
2858  foreach ($close as $key => $val) {
2859  $arrayreasons[$close[$key]['code']] = $close[$key]['reason'];
2860  }
2861 
2862  // Create a form table
2863  $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'));
2864  // Incomplete payment. We ask if the reason is discount or other
2865  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidPartially', $object->ref), 'confirm_paid_partially', $formquestion, "yes", 1, 310);
2866  }
2867 
2868  // Confirmation of the abandoned classification
2869  if ($action == 'canceled') {
2870  // Code
2871  $close[1]['code'] = 'badsupplier';
2872  $close[2]['code'] = 'abandon';
2873  // Help
2874  $close[1]['label'] = $langs->trans("ConfirmClassifyPaidPartiallyReasonBadSupplierDesc");
2875  $close[2]['label'] = $langs->trans("ConfirmClassifyAbandonReasonOtherDesc");
2876  // Text
2877  $close[1]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadSupplier", $object->ref), $close[1]['label'], 1);
2878  $close[2]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"), $close[2]['label'], 1);
2879  // arrayreasons
2880  $arrayreasons[$close[1]['code']] = $close[1]['reason'];
2881  $arrayreasons[$close[2]['code']] = $close[2]['reason'];
2882 
2883  // Create a form table
2884  $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'));
2885 
2886  $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('CancelBill'), $langs->trans('ConfirmCancelBill', $object->ref), 'confirm_canceled', $formquestion, "yes", 1, 250);
2887  }
2888 
2889  // Confirmation de la suppression de la facture fournisseur
2890  if ($action == 'delete') {
2891  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteBill'), $langs->trans('ConfirmDeleteBill'), 'confirm_delete', '', 0, 1);
2892  }
2893  if ($action == 'deletepayment') {
2894  $payment_id = GETPOST('paiement_id');
2895  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&paiement_id='.$payment_id, $langs->trans('DeletePayment'), $langs->trans('ConfirmDeletePayment'), 'confirm_delete_paiement', '', 0, 1);
2896  }
2897 
2898  // Confirmation to delete line
2899  if ($action == 'ask_deleteline') {
2900  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1);
2901  }
2902 
2903  if (!$formconfirm) {
2904  $parameters = array('formConfirm' => $formconfirm, 'lineid'=>$lineid);
2905  $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2906  if (empty($reshook)) {
2907  $formconfirm .= $hookmanager->resPrint;
2908  } elseif ($reshook > 0) {
2909  $formconfirm = $hookmanager->resPrint;
2910  }
2911  }
2912 
2913  // Print form confirm
2914  print $formconfirm;
2915 
2916 
2917  // Supplier invoice card
2918  $linkback = '<a href="'.DOL_URL_ROOT.'/fourn/facture/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
2919 
2920  $morehtmlref = '<div class="refidno">';
2921  // Ref supplier
2922  $morehtmlref .= $form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $usercancreate, 'string', '', 0, 1);
2923  $morehtmlref .= $form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $usercancreate, 'string', '', null, null, '', 1);
2924  // Thirdparty
2925  $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1, 'supplier');
2926  if (empty($conf->global->MAIN_DISABLE_OTHER_LINK) && $object->thirdparty->id > 0) {
2927  $morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/fourn/facture/list.php?socid='.$object->thirdparty->id.'&search_company='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherBills").'</a>)';
2928  }
2929  // Project
2930  if (isModEnabled('project')) {
2931  $langs->load("projects");
2932  $morehtmlref .= '<br>';
2933  if ($permissiontoadd) {
2934  $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
2935  if ($action != 'classify') {
2936  $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
2937  }
2938  $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, ($action == 'classify' ? 1 : 0), 0, 1, '');
2939  } else {
2940  if (!empty($object->fk_project)) {
2941  $proj = new Project($db);
2942  $proj->fetch($object->fk_project);
2943  $morehtmlref .= $proj->getNomUrl(1);
2944  if ($proj->title) {
2945  $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
2946  }
2947  }
2948  }
2949  }
2950  $morehtmlref .= '</div>';
2951 
2952  $object->totalpaid = $totalpaid; // To give a chance to dol_banner_tab to use already paid amount to show correct status
2953 
2954  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
2955 
2956  print '<div class="fichecenter">';
2957  print '<div class="fichehalfleft">';
2958  print '<div class="underbanner clearboth"></div>';
2959 
2960  print '<table class="border tableforfield centpercent">';
2961 
2962  // Type
2963  print '<tr><td class="titlefield">'.$langs->trans('Type').'</td><td>';
2964  print '<span class="badgeneutral">';
2965  print $object->getLibType();
2966  print '</span>';
2967  if ($object->type == FactureFournisseur::TYPE_REPLACEMENT) {
2968  $facreplaced = new FactureFournisseur($db);
2969  $facreplaced->fetch($object->fk_facture_source);
2970  print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("ReplaceInvoice", $facreplaced->getNomUrl(1)).'</span>';
2971  }
2972  if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
2973  $facusing = new FactureFournisseur($db);
2974  if ($object->fk_facture_source > 0) {
2975  $facusing->fetch($object->fk_facture_source);
2976  print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("CorrectInvoice", $facusing->getNomUrl(1)).'</span>';
2977  } else {
2978  print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("CorrectedInvoiceNotFound").'</span>';
2979  }
2980  }
2981 
2982  $facidavoir = $object->getListIdAvoirFromInvoice();
2983  if (count($facidavoir) > 0) {
2984  $invoicecredits = array();
2985  foreach ($facidavoir as $id) {
2986  $facavoir = new FactureFournisseur($db);
2987  $facavoir->fetch($id);
2988  $invoicecredits[] = $facavoir->getNomUrl(1);
2989  }
2990  print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("InvoiceHasAvoir") . (count($invoicecredits) ? ' ' : '') . implode(',', $invoicecredits);
2991  print '</span>';
2992  }
2993  if (isset($objectidnext) && $objectidnext > 0) {
2994  $facthatreplace = new FactureFournisseur($db);
2995  $facthatreplace->fetch($facidnext);
2996  print ' <span class="opacitymediumbycolor paddingleft">'.str_replace('{s1}', $facthatreplace->getNomUrl(1), $langs->transnoentities("ReplacedByInvoice", '{s1}')).'</span>';
2997  }
2998  if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT) {
2999  $discount = new DiscountAbsolute($db);
3000  $result = $discount->fetch(0, 0, $object->id);
3001  if ($result > 0) {
3002  print ' <span class="opacitymediumbycolor paddingleft">';
3003  $s = $langs->trans("CreditNoteConvertedIntoDiscount", '{s1}', '{s2}');
3004  $s = str_replace('{s1}', $object->getLibType(1), $s);
3005  $s = str_replace('{s2}', $discount->getNomUrl(1, 'discount'), $s);
3006  print $s;
3007  print '</span><br>';
3008  }
3009  }
3010 
3011  if ($object->fk_fac_rec_source > 0) {
3012  $tmptemplate = new FactureFournisseurRec($db);
3013  $result = $tmptemplate->fetch($object->fk_fac_rec_source);
3014  if ($result > 0) {
3015  print ' <span class="opacitymediumbycolor paddingleft">';
3016  $link = '<a href="'.DOL_URL_ROOT.'/fourn/facture/card-rec.php?facid='.$tmptemplate->id.'">'.dol_escape_htmltag($tmptemplate->titre).'</a>';
3017  $s = $langs->transnoentities("GeneratedFromSupplierTemplate", $link);
3018 
3019  print $s;
3020  print '</span>';
3021  }
3022  }
3023  print '</td></tr>';
3024 
3025 
3026  // Relative and absolute discounts
3027  print '<!-- Discounts -->'."\n";
3028  print '<tr><td>'.$langs->trans('DiscountStillRemaining');
3029  print '</td><td>';
3030 
3031  $thirdparty = $societe;
3032  $discount_type = 1;
3033  $backtopage = urlencode($_SERVER["PHP_SELF"].'?facid='.$object->id);
3034  include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
3035 
3036  print '</td></tr>';
3037 
3038  // Label
3039  print '<tr>';
3040  print '<td>'.$form->editfieldkey("Label", 'label', $object->label, $object, $usercancreate).'</td>';
3041  print '<td>'.$form->editfieldval("Label", 'label', $object->label, $object, $usercancreate).'</td>';
3042  print '</tr>';
3043 
3044  //$form_permission = ($object->statut < FactureFournisseur::STATUS_CLOSED) && $usercancreate && ($object->getSommePaiement() <= 0);
3045  $form_permission = ($object->statut < FactureFournisseur::STATUS_CLOSED) && $usercancreate;
3046 
3047  // Date
3048  print '<tr><td>';
3049  print $form->editfieldkey("DateInvoice", 'datef', $object->datep, $object, $form_permission, 'datepicker');
3050  print '</td><td colspan="3">';
3051  print $form->editfieldval("Date", 'datef', $object->datep, $object, $form_permission, 'datepicker');
3052  print '</td>';
3053 
3054  // Default terms of the settlement
3055  $langs->load('bills');
3056  print '<tr><td class="nowrap">';
3057  print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
3058  print $langs->trans('PaymentConditions');
3059  print '<td>';
3060  if ($action != 'editconditions' && $form_permission) {
3061  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>';
3062  }
3063  print '</tr></table>';
3064  print '</td><td>';
3065  if ($action == 'editconditions') {
3066  $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'cond_reglement_id');
3067  } else {
3068  $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'none');
3069  }
3070  print "</td>";
3071  print '</tr>';
3072 
3073  // Due date
3074  print '<tr><td>';
3075  print $form->editfieldkey("DateMaxPayment", 'date_lim_reglement', $object->date_echeance, $object, $form_permission, 'datepicker');
3076  print '</td><td>';
3077  print $form->editfieldval("DateMaxPayment", 'date_lim_reglement', $object->date_echeance, $object, $form_permission, 'datepicker');
3078  if ($action != 'editdate_lim_reglement' && $object->hasDelay()) {
3079  print img_warning($langs->trans('Late'));
3080  }
3081  print '</td>';
3082 
3083  // Mode of payment
3084  $langs->load('bills');
3085  print '<tr><td class="nowrap">';
3086  print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
3087  print $langs->trans('PaymentMode');
3088  print '</td>';
3089  if ($action != 'editmode' && $form_permission) {
3090  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>';
3091  }
3092  print '</tr></table>';
3093  print '</td><td>';
3094  if ($action == 'editmode') {
3095  $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->mode_reglement_id, 'mode_reglement_id', 'DBIT', 1, 1);
3096  } else {
3097  $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->mode_reglement_id, 'none');
3098  }
3099  print '</td></tr>';
3100 
3101  // Multicurrency
3102  if (isModEnabled("multicurrency")) {
3103  // Multicurrency code
3104  print '<tr>';
3105  print '<td>';
3106  print '<table class="nobordernopadding" width="100%"><tr><td>';
3107  print $form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0);
3108  print '</td>';
3109  if ($action != 'editmulticurrencycode' && $object->statut == $object::STATUS_DRAFT) {
3110  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>';
3111  }
3112  print '</tr></table>';
3113  print '</td><td>';
3114  if ($action == 'editmulticurrencycode') {
3115  $form->form_multicurrency_code($_SERVER['PHP_SELF'].'?id='.$object->id, $object->multicurrency_code, 'multicurrency_code');
3116  } else {
3117  $form->form_multicurrency_code($_SERVER['PHP_SELF'].'?id='.$object->id, $object->multicurrency_code, 'none');
3118  }
3119  print '</td></tr>';
3120 
3121  // Multicurrency rate
3122  if ($object->multicurrency_code != $conf->currency || $object->multicurrency_tx != 1) {
3123  print '<tr>';
3124  print '<td>';
3125  print '<table class="nobordernopadding centpercent"><tr><td>';
3126  print $form->editfieldkey('CurrencyRate', 'multicurrency_tx', '', $object, 0);
3127  print '</td>';
3128  if ($action != 'editmulticurrencyrate' && $object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) {
3129  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>';
3130  }
3131  print '</tr></table>';
3132  print '</td><td>';
3133  if ($action == 'editmulticurrencyrate' || $action == 'actualizemulticurrencyrate') {
3134  if ($action == 'actualizemulticurrencyrate') {
3135  list($object->fk_multicurrency, $object->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($object->db, $object->multicurrency_code);
3136  }
3137  $form->form_multicurrency_rate($_SERVER['PHP_SELF'].'?id='.$object->id, $object->multicurrency_tx, 'multicurrency_tx', $object->multicurrency_code);
3138  } else {
3139  $form->form_multicurrency_rate($_SERVER['PHP_SELF'].'?id='.$object->id, $object->multicurrency_tx, 'none', $object->multicurrency_code);
3140  if ($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) {
3141  print '<div class="inline-block"> &nbsp; &nbsp; &nbsp; &nbsp; ';
3142  print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=actualizemulticurrencyrate">'.$langs->trans("ActualizeCurrency").'</a>';
3143  print '</div>';
3144  }
3145  }
3146  print '</td></tr>';
3147  }
3148  }
3149 
3150  // Bank Account
3151  if (isModEnabled("banque")) {
3152  print '<tr><td class="nowrap">';
3153  print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
3154  print $langs->trans('BankAccount');
3155  print '<td>';
3156  if ($action != 'editbankaccount' && $usercancreate) {
3157  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>';
3158  }
3159  print '</tr></table>';
3160  print '</td><td>';
3161  if ($action == 'editbankaccount') {
3162  $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'fk_account', 1);
3163  } else {
3164  $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none');
3165  }
3166  print "</td>";
3167  print '</tr>';
3168  }
3169 
3170  // Incoterms
3171  if (isModEnabled('incoterm')) {
3172  print '<tr><td>';
3173  print '<table width="100%" class="nobordernopadding"><tr><td>';
3174  print $langs->trans('IncotermLabel');
3175  print '<td><td class="right">';
3176  if ($usercancreate) {
3177  print '<a class="editfielda" href="'.DOL_URL_ROOT.'/fourn/facture/card.php?facid='.$object->id.'&action=editincoterm&token='.newToken().'">'.img_edit().'</a>';
3178  } else {
3179  print '&nbsp;';
3180  }
3181  print '</td></tr></table>';
3182  print '</td>';
3183  print '<td>';
3184  if ($action != 'editincoterm') {
3185  print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1);
3186  } else {
3187  print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id);
3188  }
3189  print '</td></tr>';
3190  }
3191 
3192  // Intracomm report
3193  if (isModEnabled('intracommreport')) {
3194  $langs->loadLangs(array("intracommreport"));
3195  print '<tr><td>';
3196  print '<table class="nobordernopadding centpercent"><tr><td>';
3197  print $langs->trans('IntracommReportTransportMode');
3198  print '</td>';
3199  if ($action != 'editmode' && ($user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer)) {
3200  print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editmode&token='.newToken().'&id='.$object->id.'">'.img_edit().'</a></td>';
3201  }
3202  print '</tr></table>';
3203  print '</td>';
3204  print '<td>';
3205  if ($action == 'editmode') {
3206  $form->formSelectTransportMode($_SERVER['PHP_SELF'].'?id='.$object->id, $object->transport_mode_id, 'transport_mode_id', 1, 1);
3207  } else {
3208  $form->formSelectTransportMode($_SERVER['PHP_SELF'].'?id='.$object->id, $object->transport_mode_id, 'none');
3209  }
3210  print '</td></tr>';
3211  }
3212 
3213  // Other attributes
3214  $cols = 2;
3215  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
3216 
3217  print '</table>';
3218  print '</div>';
3219 
3220  print '<div class="fichehalfright">';
3221  print '<div class="underbanner clearboth"></div>';
3222 
3223  print '<table class="border tableforfield centpercent">';
3224 
3225  if (isModEnabled("multicurrency") && ($object->multicurrency_code != $conf->currency)) {
3226  // Multicurrency Amount HT
3227  print '<tr><td class="titlefieldmiddle">'.$form->editfieldkey('MulticurrencyAmountHT', 'multicurrency_total_ht', '', $object, 0).'</td>';
3228  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>';
3229  print '</tr>';
3230 
3231  // Multicurrency Amount VAT
3232  print '<tr><td>'.$form->editfieldkey('MulticurrencyAmountVAT', 'multicurrency_total_tva', '', $object, 0).'</td>';
3233  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>';
3234  print '</tr>';
3235 
3236  // Multicurrency Amount TTC
3237  print '<tr><td>'.$form->editfieldkey('MulticurrencyAmountTTC', 'multicurrency_total_ttc', '', $object, 0).'</td>';
3238  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>';
3239  print '</tr>';
3240  }
3241 
3242  // Amount
3243  print '<tr><td class="titlefield">'.$langs->trans('AmountHT').'</td>';
3244  print '<td class="nowrap right amountcard">'.price($object->total_ht, 1, $langs, 0, -1, -1, $conf->currency).'</td>';
3245  print '</tr>';
3246 
3247  // VAT
3248  print '<tr><td>'.$langs->trans('AmountVAT').'</td>';
3249  print '<td class="nowrap right amountcard">';
3250  if (GETPOST('calculationrule')) {
3251  $calculationrule = GETPOST('calculationrule', 'alpha');
3252  } else {
3253  $calculationrule = (empty($conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND) ? 'totalofround' : 'roundoftotal');
3254  }
3255  if ($calculationrule == 'totalofround') {
3256  $calculationrulenum = 1;
3257  } else {
3258  $calculationrulenum = 2;
3259  }
3260  // Show link for "recalculate"
3261  if ($object->getVentilExportCompta() == 0) {
3262  $s = '<span class="hideonsmartphone opacitymedium">'.$langs->trans("ReCalculate").' </span>';
3263  $s .= '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=calculate&calculationrule=totalofround">'.$langs->trans("Mode1").'</a>';
3264  $s .= ' / ';
3265  $s .= '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=calculate&calculationrule=roundoftotal">'.$langs->trans("Mode2").'</a>';
3266  print '<div class="inline-block">';
3267  print $form->textwithtooltip($s, $langs->trans("CalculationRuleDesc", $calculationrulenum).'<br>'.$langs->trans("CalculationRuleDescSupplier"), 2, 1, img_picto('', 'help'), '', 3, '', 0, 'recalculate');
3268  print '&nbsp; &nbsp; &nbsp; &nbsp;';
3269  print '</div>';
3270  }
3271  print price($object->total_tva, 1, $langs, 0, -1, -1, $conf->currency);
3272  print '</td></tr>';
3273 
3274  // Amount Local Taxes
3275  //TODO: Place into a function to control showing by country or study better option
3276  if ($societe->localtax1_assuj == "1") { //Localtax1
3277  print '<tr><td>'.$langs->transcountry("AmountLT1", $societe->country_code).'</td>';
3278  print '<td class="nowrap right amountcard">'.price($object->total_localtax1, 1, $langs, 0, -1, -1, $conf->currency).'</td>';
3279  print '</tr>';
3280  }
3281  if ($societe->localtax2_assuj == "1") { //Localtax2
3282  print '<tr><td>'.$langs->transcountry("AmountLT2", $societe->country_code).'</td>';
3283  print '<td class="nowrap right amountcard">'.price($object->total_localtax2, 1, $langs, 0, -1, -1, $conf->currency).'</td>';
3284  print '</tr>';
3285  }
3286  print '<tr><td>'.$langs->trans('AmountTTC').'</td>';
3287  print '<td colspan="3" class="nowrap right amountcard">'.price($object->total_ttc, 1, $langs, 0, -1, -1, $conf->currency).'</td>';
3288  print '</tr>';
3289 
3290  print '</table>';
3291 
3292 
3293  // List of payments
3294 
3295  $totalpaid = 0;
3296 
3297  $sign = 1;
3298  if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
3299  $sign = - 1;
3300  }
3301 
3302  $nbrows = 9; $nbcols = 3;
3303  if (isModEnabled('project')) {
3304  $nbrows++;
3305  }
3306  if (isModEnabled("banque")) {
3307  $nbrows++; $nbcols++;
3308  }
3309  if (isModEnabled('incoterm')) {
3310  $nbrows++;
3311  }
3312  if (isModEnabled("multicurrency")) {
3313  $nbrows += 5;
3314  }
3315 
3316  // Local taxes
3317  if ($societe->localtax1_assuj == "1") {
3318  $nbrows++;
3319  }
3320  if ($societe->localtax2_assuj == "1") {
3321  $nbrows++;
3322  }
3323 
3324  $sql = 'SELECT p.datep as dp, p.ref, p.num_paiement as num_payment, p.rowid, p.fk_bank,';
3325  $sql .= ' c.id as paiement_type, c.code as payment_code,';
3326  $sql .= ' pf.amount,';
3327  $sql .= ' ba.rowid as baid, ba.ref as baref, ba.label, ba.number as banumber, ba.account_number, ba.fk_accountancy_journal';
3328  $sql .= ' FROM '.MAIN_DB_PREFIX.'paiementfourn as p';
3329  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid';
3330  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid';
3331  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id';
3332  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf ON pf.fk_paiementfourn = p.rowid';
3333  $sql .= ' WHERE pf.fk_facturefourn = '.((int) $object->id);
3334  $sql .= ' ORDER BY p.datep, p.tms';
3335 
3336  $result = $db->query($sql);
3337  if ($result) {
3338  $num = $db->num_rows($result);
3339  $i = 0;
3340 
3341  print '<div class="div-table-responsive-no-min">';
3342  print '<table class="noborder paymenttable centpercent">';
3343  print '<tr class="liste_titre">';
3344  print '<td class="liste_titre">'.($object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("PaymentsBack") : $langs->trans('Payments')).'</td>';
3345  print '<td>'.$langs->trans('Date').'</td>';
3346  print '<td>'.$langs->trans('Type').'</td>';
3347  if (isModEnabled("banque")) {
3348  print '<td class="right">'.$langs->trans('BankAccount').'</td>';
3349  }
3350  print '<td class="right">'.$langs->trans('Amount').'</td>';
3351  print '<td width="18">&nbsp;</td>';
3352  print '</tr>';
3353 
3354  if ($num > 0) {
3355  while ($i < $num) {
3356  $objp = $db->fetch_object($result);
3357 
3358  $paymentstatic->id = $objp->rowid;
3359  $paymentstatic->datepaye = $db->jdate($objp->dp);
3360  $paymentstatic->ref = ($objp->ref ? $objp->ref : $objp->rowid);
3361  $paymentstatic->num_payment = $objp->num_payment;
3362 
3363  $paymentstatic->paiementcode = $objp->payment_code;
3364  $paymentstatic->type_code = $objp->payment_code;
3365  $paymentstatic->type_label = $objp->payment_type;
3366 
3367  print '<tr class="oddeven">';
3368  print '<td class="nowraponall">';
3369  print $paymentstatic->getNomUrl(1);
3370  print '</td>';
3371  print '<td>'.dol_print_date($db->jdate($objp->dp), 'day').'</td>';
3372  $s = $form->form_modes_reglement(null, $objp->paiement_type, 'none', '', 1, 0, '', 1).' '.$objp->num_payment;
3373  print '<td class="tdoverflowmax125" title="'.dol_escape_htmltag($s).'">';
3374  print $s;
3375  print '</td>';
3376  if (isModEnabled("banque")) {
3377  $bankaccountstatic->id = $objp->baid;
3378  $bankaccountstatic->ref = $objp->baref;
3379  $bankaccountstatic->label = $objp->baref;
3380  $bankaccountstatic->number = $objp->banumber;
3381 
3382  if (isModEnabled('accounting')) {
3383  $bankaccountstatic->account_number = $objp->account_number;
3384 
3385  $accountingjournal = new AccountingJournal($db);
3386  $accountingjournal->fetch($objp->fk_accountancy_journal);
3387  $bankaccountstatic->accountancy_journal = $accountingjournal->getNomUrl(0, 1, 1, '', 1);
3388  }
3389 
3390  print '<td class="right">';
3391  if ($objp->baid > 0) {
3392  print $bankaccountstatic->getNomUrl(1, 'transactions');
3393  }
3394  print '</td>';
3395  }
3396  print '<td class="right">'.price($sign * $objp->amount).'</td>';
3397  print '<td class="center">';
3398  if ($object->statut == FactureFournisseur::STATUS_VALIDATED && $object->paye == 0 && $user->socid == 0) {
3399  print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=deletepayment&token='.newToken().'&paiement_id='.$objp->rowid.'">';
3400  print img_delete();
3401  print '</a>';
3402  }
3403  print '</td>';
3404  print '</tr>';
3405  $totalpaid += $objp->amount;
3406  $i++;
3407  }
3408  } else {
3409  print '<tr class="oddeven"><td colspan="'.$nbcols.'"><span class="opacitymedium">'.$langs->trans("None").'</span></td><td></td><td></td></tr>';
3410  }
3411 
3412  /*
3413  if ($object->paye == 0)
3414  {
3415  print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans('AlreadyPaid').' :</td><td class="right">'.price($totalpaid).'</td><td></td></tr>';
3416  print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("Billed").' :</td><td class="right">'.price($object->total_ttc).'</td><td></td></tr>';
3417 
3418  $resteapayer = $object->total_ttc - $totalpaid;
3419 
3420  print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans('RemainderToPay').' :</td>';
3421  print '<td class="right'.($resteapayer?' amountremaintopay':'').'">'.price($resteapayer).'</td><td></td></tr>';
3422  }
3423  */
3424 
3425  $db->free($result);
3426  } else {
3427  dol_print_error($db);
3428  }
3429 
3430  if ($object->type != FactureFournisseur::TYPE_CREDIT_NOTE) {
3431  // Total already paid
3432  print '<tr><td colspan="'.$nbcols.'" class="right">';
3433  print '<span class="opacitymedium">';
3434  if ($object->type != FactureFournisseur::TYPE_DEPOSIT) {
3435  print $langs->trans('AlreadyPaidNoCreditNotesNoDeposits');
3436  } else {
3437  print $langs->trans('AlreadyPaid');
3438  }
3439  print '</span>';
3440  print '</td><td class="right"'.(($totalpaid > 0) ? ' class="amountalreadypaid"' : '').'>'.price($totalpaid).'</td><td>&nbsp;</td></tr>';
3441 
3442  //$resteapayer = $object->total_ttc - $totalpaid;
3443  $resteapayeraffiche = $resteapayer;
3444 
3445  $cssforamountpaymentcomplete = 'amountpaymentcomplete';
3446 
3447  // Loop on each credit note or deposit amount applied
3448  $creditnoteamount = 0;
3449  $depositamount = 0;
3450 
3451  $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
3452  $sql .= " re.description, re.fk_invoice_supplier_source";
3453  $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re";
3454  $sql .= " WHERE fk_invoice_supplier = ".((int) $object->id);
3455  $resql = $db->query($sql);
3456  if ($resql) {
3457  $num = $db->num_rows($resql);
3458  $i = 0;
3459  $invoice = new FactureFournisseur($db);
3460  while ($i < $num) {
3461  $obj = $db->fetch_object($resql);
3462  $invoice->fetch($obj->fk_invoice_supplier_source);
3463  print '<tr><td colspan="'.$nbcols.'" class="right">';
3464  if ($invoice->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
3465  print $langs->trans("CreditNote").' ';
3466  }
3467  if ($invoice->type == FactureFournisseur::TYPE_DEPOSIT) {
3468  print $langs->trans("Deposit").' ';
3469  }
3470  print $invoice->getNomUrl(0);
3471  print ' :</td>';
3472  print '<td class="right">'.price($obj->amount_ttc).'</td>';
3473  print '<td class="right">';
3474  print '<a href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=unlinkdiscount&discountid='.$obj->rowid.'">'.img_delete().'</a>';
3475  print '</td></tr>';
3476  $i++;
3477  if ($invoice->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
3478  $creditnoteamount += $obj->amount_ttc;
3479  }
3480  if ($invoice->type == FactureFournisseur::TYPE_DEPOSIT) {
3481  $depositamount += $obj->amount_ttc;
3482  }
3483  }
3484  } else {
3485  dol_print_error($db);
3486  }
3487 
3488  // Paye partiellement 'escompte'
3489  if (($object->statut == FactureFournisseur::STATUS_CLOSED || $object->statut == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'discount_vat') {
3490  print '<tr><td colspan="'.$nbcols.'" class="right nowrap">';
3491  print '<span class="opacitymedium">';
3492  print $form->textwithpicto($langs->trans("Discount"), $langs->trans("HelpEscompte"), - 1);
3493  print '</span>';
3494  print '</td><td class="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaid).'</td><td>&nbsp;</td></tr>';
3495  $resteapayeraffiche = 0;
3496  $cssforamountpaymentcomplete = 'amountpaymentneutral';
3497  }
3498  // Paye partiellement ou Abandon 'badsupplier'
3499  if (($object->statut == FactureFournisseur::STATUS_CLOSED || $object->statut == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'badsupplier') {
3500  print '<tr><td colspan="'.$nbcols.'" class="right nowrap">';
3501  print '<span class="opacitymedium">';
3502  print $form->textwithpicto($langs->trans("Abandoned"), $langs->trans("HelpAbandonBadCustomer"), - 1);
3503  print '</span>';
3504  print '</td><td class="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaid).'</td><td>&nbsp;</td></tr>';
3505  // $resteapayeraffiche=0;
3506  $cssforamountpaymentcomplete = 'amountpaymentneutral';
3507  }
3508  // Paye partiellement ou Abandon 'product_returned'
3509  if (($object->statut == FactureFournisseur::STATUS_CLOSED || $object->statut == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'product_returned') {
3510  print '<tr><td colspan="'.$nbcols.'" class="right nowrap">';
3511  print '<span class="opacitymedium">';
3512  print $form->textwithpicto($langs->trans("ProductReturned"), $langs->trans("HelpAbandonProductReturned"), - 1);
3513  print '</span>';
3514  print '</td><td class="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaid).'</td><td>&nbsp;</td></tr>';
3515  $resteapayeraffiche = 0;
3516  $cssforamountpaymentcomplete = 'amountpaymentneutral';
3517  }
3518  // Paye partiellement ou Abandon 'abandon'
3519  if (($object->statut == FactureFournisseur::STATUS_CLOSED || $object->statut == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'abandon') {
3520  print '<tr><td colspan="'.$nbcols.'" class="right nowrap">';
3521  $text = $langs->trans("HelpAbandonOther");
3522  if ($object->close_note) {
3523  $text .= '<br><br><b>'.$langs->trans("Reason").'</b>:'.$object->close_note;
3524  }
3525  print '<span class="opacitymedium">';
3526  print $form->textwithpicto($langs->trans("Abandoned"), $text, - 1);
3527  print '</span>';
3528  print '</td><td class="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaid).'</td><td>&nbsp;</td></tr>';
3529  $resteapayeraffiche = 0;
3530  $cssforamountpaymentcomplete = 'amountpaymentneutral';
3531  }
3532 
3533  // Billed
3534  print '<tr><td colspan="'.$nbcols.'" class="right">';
3535  print '<span class="opacitymedium">';
3536  print $langs->trans("Billed");
3537  print '</span>';
3538  print '</td><td class="right">'.price($object->total_ttc).'</td><td>&nbsp;</td></tr>';
3539 
3540  // Remainder to pay
3541  print '<tr><td colspan="'.$nbcols.'" class="right">';
3542  print '<span class="opacitymedium">';
3543  print $langs->trans('RemainderToPay');
3544  if ($resteapayeraffiche < 0) {
3545  print ' ('.$langs->trans('NegativeIfExcessPaid').')';
3546  }
3547  print '</span>';
3548  print '</td>';
3549  print '<td class="right'.($resteapayeraffiche ? ' amountremaintopay' : (' '.$cssforamountpaymentcomplete)).'">'.price($resteapayeraffiche).'</td><td>&nbsp;</td></tr>';
3550 
3551  // Remainder to pay Multicurrency
3552  if (isModEnabled('multicurreny') && $object->multicurrency_code != $conf->currency || $object->multicurrency_tx != 1) {
3553  print '<tr><td colspan="'.$nbcols.'" class="right">';
3554  print '<span class="opacitymedium">';
3555  print $langs->trans('RemainderToPayMulticurrency');
3556  if ($resteapayeraffiche < 0) {
3557  print ' ('.$langs->trans('NegativeIfExcessPaid').')';
3558  }
3559  print '</span>';
3560  print '</td>';
3561  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>';
3562  }
3563  } else { // Credit note
3564  $cssforamountpaymentcomplete = 'amountpaymentneutral';
3565 
3566  // Total already paid back
3567  print '<tr><td colspan="'.$nbcols.'" class="right">';
3568  print $langs->trans('AlreadyPaidBack');
3569  print ' :</td><td class="right">'.price($sign * $totalpaid).'</td><td>&nbsp;</td></tr>';
3570 
3571  // Billed
3572  print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("Billed").' :</td><td class="right">'.price($sign * $object->total_ttc).'</td><td>&nbsp;</td></tr>';
3573 
3574  // Remainder to pay back
3575  print '<tr><td colspan="'.$nbcols.'" class="right">';
3576  print '<span class="opacitymedium">';
3577  print $langs->trans('RemainderToPayBack');
3578  if ($resteapayeraffiche > 0) {
3579  print ' ('.$langs->trans('NegativeIfExcessRefunded').')';
3580  }
3581  print '</td>';
3582  print '</span>';
3583  print '<td class="right'.($resteapayeraffiche ? ' amountremaintopay' : (' '.$cssforamountpaymentcomplete)).'">'.price($sign * $resteapayeraffiche).'</td><td>&nbsp;</td></tr>';
3584 
3585  // Remainder to pay back Multicurrency
3586  if (isModEnabled('multicurreny') && $object->multicurrency_code != $conf->currency || $object->multicurrency_tx != 1) {
3587  print '<tr><td colspan="'.$nbcols.'" class="right">';
3588  print '<span class="opacitymedium">';
3589  print $langs->trans('RemainderToPayBackMulticurrency');
3590  if ($resteapayeraffiche> 0) {
3591  print ' ('.$langs->trans('NegativeIfExcessRefunded').')';
3592  }
3593  print '</span>';
3594  print '</td>';
3595  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>';
3596  }
3597 
3598  // Sold credit note
3599  // print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans('TotalTTC').' :</td>';
3600  // print '<td class="right" style="border: 1px solid;" bgcolor="#f0f0f0"><b>'.price($sign *
3601  // $object->total_ttc).'</b></td><td>&nbsp;</td></tr>';
3602  }
3603 
3604  print '</table>';
3605  print '</div>';
3606 
3607  print '</div>';
3608  print '</div>';
3609 
3610  print '<div class="clearboth"></div><br>';
3611 
3612  if (!empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) {
3613  $blocname = 'contacts';
3614  $title = $langs->trans('ContactsAddresses');
3615  include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
3616  }
3617 
3618  if (!empty($conf->global->MAIN_DISABLE_NOTES_TAB)) {
3619  $colwidth = 20;
3620  $blocname = 'notes';
3621  $title = $langs->trans('Notes');
3622  include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
3623  }
3624 
3625 
3626  /*
3627  * Lines
3628  */
3629  print '<form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="POST">';
3630  print '<input type="hidden" name="token" value="'.newToken().'">';
3631  print '<input type="hidden" name="action" value="'.(($action != 'editline') ? 'addline' : 'updateline').'">';
3632  print '<input type="hidden" name="mode" value="">';
3633  print '<input type="hidden" name="page_y" value="">';
3634  print '<input type="hidden" name="id" value="'.$object->id.'">';
3635  print '<input type="hidden" name="socid" value="'.$societe->id.'">';
3636 
3637  if (!empty($conf->use_javascript_ajax) && $object->statut == FactureFournisseur::STATUS_DRAFT) {
3638  include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
3639  }
3640 
3641  print '<div class="div-table-responsive-no-min">';
3642  print '<table id="tablelines" class="noborder noshadow centpercent">';
3643 
3644  global $forceall, $senderissupplier, $dateSelector, $inputalsopricewithtax;
3645  $forceall = 1; $dateSelector = 0; $inputalsopricewithtax = 1;
3646  $senderissupplier = 2; // $senderissupplier=2 is same than 1 but disable test on minimum qty and disable autofill qty with minimum.
3647  //if (!empty($conf->global->SUPPLIER_INVOICE_WITH_NOPRICEDEFINED)) $senderissupplier=2;
3648  if (!empty($conf->global->SUPPLIER_INVOICE_WITH_PREDEFINED_PRICES_ONLY)) {
3649  $senderissupplier = 1;
3650  }
3651 
3652  // Show object lines
3653  if (!empty($object->lines)) {
3654  $object->printObjectLines($action, $societe, $mysoc, $lineid, 1);
3655  }
3656 
3657  $num = count($object->lines);
3658 
3659  // Form to add new line
3660  if ($object->statut == FactureFournisseur::STATUS_DRAFT && $usercancreate) {
3661  if ($action != 'editline') {
3662  // Add free products/services
3663 
3664  $parameters = array();
3665  $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
3666  if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
3667  if (empty($reshook))
3668  $object->formAddObjectLine(1, $societe, $mysoc);
3669  }
3670  }
3671 
3672  print '</table>';
3673  print '</div>';
3674  print '</form>';
3675 
3676  print dol_get_fiche_end();
3677 
3678 
3679  if ($action != 'presend') {
3680  /*
3681  * Buttons actions
3682  */
3683 
3684  print '<div class="tabsAction">';
3685 
3686  $parameters = array();
3687  $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
3688  // modified by hook
3689  if (empty($reshook)) {
3690  // Modify a validated invoice with no payments
3691  if ($object->statut == FactureFournisseur::STATUS_VALIDATED && $action != 'confirm_edit' && $object->getSommePaiement() == 0 && $usercancreate) {
3692  // We check if lines of invoice are not already transfered into accountancy
3693  $ventilExportCompta = $object->getVentilExportCompta(); // Should be 0 since the sum of payments are zero. But we keep the protection.
3694 
3695  if ($ventilExportCompta == 0) {
3696  print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=edit&token='.newToken().'">'.$langs->trans('Modify').'</a>';
3697  } else {
3698  print '<span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseDispatchedInBookkeeping").'">'.$langs->trans('Modify').'</span>';
3699  }
3700  }
3701 
3702  $discount = new DiscountAbsolute($db);
3703  $result = $discount->fetch(0, 0, $object->id);
3704 
3705  // Reopen a standard paid invoice
3706  if (($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_REPLACEMENT
3707  || ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && empty($discount->id))
3708  || ($object->type == FactureFournisseur::TYPE_DEPOSIT && empty($discount->id)))
3709  && ($object->statut == FactureFournisseur::STATUS_CLOSED || $object->statut == FactureFournisseur::STATUS_ABANDONED)) { // A paid invoice (partially or completely)
3710  if (!$objectidnext && $object->close_code != 'replaced' && $usercancreate) { // Not replaced by another invoice
3711  print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans('ReOpen').'</a>';
3712  } else {
3713  if ($usercancreate) {
3714  print '<span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('ReOpen').'</span>';
3715  } elseif (empty($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED)) {
3716  print '<span class="butActionRefused classfortooltip">'.$langs->trans('ReOpen').'</span>';
3717  }
3718  }
3719  }
3720 
3721  // Validate
3722  if ($action != 'confirm_edit' && $object->statut == FactureFournisseur::STATUS_DRAFT) {
3723  if (count($object->lines)) {
3724  if ($usercanvalidate) {
3725  print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=valid"';
3726  print '>'.$langs->trans('Validate').'</a>';
3727  } else {
3728  print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'"';
3729  print '>'.$langs->trans('Validate').'</a>';
3730  }
3731  }
3732  }
3733 
3734  // Send by mail
3735  if (empty($user->socid)) {
3736  if (($object->statut == FactureFournisseur::STATUS_VALIDATED || $object->statut == FactureFournisseur::STATUS_CLOSED)) {
3737  if ($usercansend) {
3738  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=presend&mode=init#formmailbeforetitle">'.$langs->trans('SendMail').'</a>';
3739  } else {
3740  print '<span class="butActionRefused classfortooltip">'.$langs->trans('SendMail').'</span>';
3741  }
3742  }
3743  }
3744 
3745  // Create payment
3746  if ($object->type != FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == FactureFournisseur::STATUS_VALIDATED && $object->paye == 0) {
3747  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
3748  }
3749 
3750  // Reverse back money or convert to reduction
3751  if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_STANDARD) {
3752  // For credit note only
3753  if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0) {
3754  if ($resteapayer == 0) {
3755  print '<span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseRemainderToPayIsZero").'">'.$langs->trans('DoPaymentBack').'</span>';
3756  } else {
3757  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>';
3758  }
3759  }
3760 
3761  // For standard invoice with excess paid
3762  if ($object->type == FactureFournisseur::TYPE_STANDARD && empty($object->paye) && ($object->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits) < 0 && $usercancreate && empty($discount->id)) {
3763  print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=converttoreduc">'.$langs->trans('ConvertExcessPaidToReduc').'</a>';
3764  }
3765  // For credit note
3766  if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $usercancreate
3767  && (!empty($conf->global->SUPPLIER_INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED) || $object->getSommePaiement() == 0)
3768  ) {
3769  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>';
3770  }
3771  // For deposit invoice
3772  if ($object->type == FactureFournisseur::TYPE_DEPOSIT && $usercancreate && $object->statut > 0 && empty($discount->id)) {
3773  print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=converttoreduc">'.$langs->trans('ConvertToReduc').'</a>';
3774  }
3775  }
3776 
3777  // Classify paid
3778  if ($object->statut == FactureFournisseur::STATUS_VALIDATED && $object->paye == 0 && (
3779  ($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))) ||
3780  ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $resteapayer >= 0) ||
3781  ($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)))
3782  )
3783  ) {
3784  print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=paid">'.$langs->trans('ClassifyPaid').'</a>';
3785  }
3786 
3787  // Classify 'closed not completely paid' (possible if validated and not yet filed paid)
3788  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)) {
3789  if ($totalpaid > 0 || $totalcreditnotes > 0) {
3790  // If one payment or one credit note was linked to this invoice
3791  print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;action=paid">'.$langs->trans('ClassifyPaidPartially').'</a>';
3792  } else {
3793  if (empty($conf->global->INVOICE_CAN_NEVER_BE_CANCELED)) {
3794  print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;action=canceled">'.$langs->trans('ClassifyCanceled').'</a>';
3795  }
3796  }
3797  }
3798 
3799  // Create event
3800  /*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.
3801  {
3802  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>';
3803  }*/
3804 
3805  // Create a credit note
3806  if (($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_DEPOSIT) && $object->statut > 0 && $usercancreate) {
3807  if (!$objectidnext) {
3808  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>';
3809  }
3810  }
3811 
3812  // Clone
3813  if ($action != 'edit' && $usercancreate) {
3814  print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=clone&amp;socid='.$object->socid.'">'.$langs->trans('ToClone').'</a>';
3815  }
3816 
3817  // Clone as predefined / Create template
3818  if (($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_DEPOSIT) && $object->statut == 0 && $usercancreate) {
3819  if (!$objectidnext && count($object->lines) > 0) {
3820  print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/card-rec.php?facid='.$object->id.'&amp;action=create">'.$langs->trans("ChangeIntoRepeatableInvoice").'</a>';
3821  }
3822  }
3823 
3824  // Delete
3825  $isErasable = $object->is_erasable();
3826  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)
3827  $enableDelete = false;
3828  $htmltooltip = '';
3829  $params = (empty($conf->use_javascript_ajax) ? array() : array('attr' => array('class' => 'reposition')));
3830  //var_dump($isErasable); var_dump($params);
3831  if ($isErasable == -4) {
3832  $htmltooltip = $langs->trans("DisabledBecausePayments");
3833  } elseif ($isErasable == -3) { // Should never happen with supplier invoice
3834  $htmltooltip = $langs->trans("DisabledBecauseNotLastSituationInvoice");
3835  } elseif ($isErasable == -2) { // Should never happen with supplier invoice
3836  $htmltooltip = $langs->trans("DisabledBecauseNotLastInvoice");
3837  } elseif ($isErasable == -1) {
3838  $htmltooltip = $langs->trans("DisabledBecauseDispatchedInBookkeeping");
3839  } elseif ($isErasable <= 0) { // Any other cases
3840  $htmltooltip = $langs->trans("DisabledBecauseNotErasable");
3841  } else {
3842  $enableDelete = true;
3843  $htmltooltip = '';
3844  }
3845  print dolGetButtonAction($htmltooltip, $langs->trans("Delete"), 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), $object->id, $enableDelete, $params);
3846  }
3847  print '</div>';
3848 
3849  if ($action != 'confirm_edit') {
3850  print '<div class="fichecenter"><div class="fichehalfleft">';
3851 
3852  /*
3853  * Generated documents
3854  */
3855  $ref = dol_sanitizeFileName($object->ref);
3856  $subdir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier').$ref;
3857  $filedir = $conf->fournisseur->facture->dir_output.'/'.$subdir;
3858  $urlsource = $_SERVER['PHP_SELF'].'?id='.$object->id;
3859  $genallowed = $usercanread;
3860  $delallowed = $usercancreate;
3861  $modelpdf = (!empty($object->model_pdf) ? $object->model_pdf : (empty($conf->global->INVOICE_SUPPLIER_ADDON_PDF) ? '' : $conf->global->INVOICE_SUPPLIER_ADDON_PDF));
3862 
3863  print $formfile->showdocuments('facture_fournisseur', $subdir, $filedir, $urlsource, $genallowed, $delallowed, $modelpdf, 1, 0, 0, 40, 0, '', '', '', $societe->default_lang);
3864  $somethingshown = $formfile->numoffiles;
3865 
3866  // Show links to link elements
3867  $linktoelem = $form->showLinkToObjectBlock($object, null, array('invoice_supplier'));
3868  $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
3869 
3870  print '</div><div class="fichehalfright">';
3871 
3872  // List of actions on element
3873  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
3874  $formactions = new FormActions($db);
3875  $somethingshown = $formactions->showactions($object, 'invoice_supplier', $socid, 1, 'listaction'.($genallowed ? 'largetitle' : ''));
3876 
3877  print '</div></div>';
3878  }
3879  }
3880  }
3881 
3882  // Select mail models is same action as presend
3883  if (GETPOST('modelselected')) {
3884  $action = 'presend';
3885  }
3886 
3887  // Presend form
3888  $modelmail = 'invoice_supplier_send';
3889  $defaulttopic = 'SendBillRef';
3890  $diroutput = $conf->fournisseur->facture->dir_output;
3891  $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO';
3892  $trackid = 'sinv'.$object->id;
3893 
3894  include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
3895  }
3896 }
3897 
3898 
3899 // End of page
3900 llxFooter();
3901 $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.