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