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