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