PageRenderTime 37ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/htdocs/compta/facture.php

https://github.com/zeert/dolibarr
PHP | 3331 lines | 2653 code | 351 blank | 327 comment | 929 complexity | 0e6934c45d5b9ad7898c0d41c0ccc530 MD5 | raw file
Possible License(s): LGPL-2.0
  1. <?php
  2. /* Copyright (C) 2002-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
  4. * Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
  5. * Copyright (C) 2005 Marc Barilley / Ocebo <marc@ocebo.com>
  6. * Copyright (C) 2005-2012 Regis Houssin <regis@dolibarr.fr>
  7. * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
  8. * Copyright (C) 2010-2012 Juanjo Menent <jmenent@2byte.es>
  9. * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. */
  24. /**
  25. * \file htdocs/compta/facture.php
  26. * \ingroup facture
  27. * \brief Page to create/see an invoice
  28. */
  29. require('../main.inc.php');
  30. require_once(DOL_DOCUMENT_ROOT."/core/class/html.formfile.class.php");
  31. require_once(DOL_DOCUMENT_ROOT."/core/class/html.formother.class.php");
  32. require_once(DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php');
  33. require_once(DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php');
  34. require_once(DOL_DOCUMENT_ROOT.'/core/class/discount.class.php');
  35. require_once(DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php');
  36. require_once(DOL_DOCUMENT_ROOT."/core/lib/functions2.lib.php");
  37. require_once(DOL_DOCUMENT_ROOT.'/core/lib/invoice.lib.php');
  38. require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php");
  39. if (! empty($conf->commande->enabled)) require_once(DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php');
  40. if (! empty($conf->projet->enabled))
  41. {
  42. require_once(DOL_DOCUMENT_ROOT.'/projet/class/project.class.php');
  43. require_once(DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php');
  44. }
  45. $langs->load('bills');
  46. //print 'ee'.$langs->trans('BillsCustomer');exit;
  47. $langs->load('companies');
  48. $langs->load('products');
  49. $langs->load('main');
  50. if (! empty($conf->margin->enabled))
  51. $langs->load('margins');
  52. $sall=trim(GETPOST('sall'));
  53. $projectid=(GETPOST('projectid')?GETPOST('projectid','int'):0);
  54. $id=(GETPOST('id','int')?GETPOST('id','int'):GETPOST('facid','int')); // For backward compatibility
  55. $ref=GETPOST('ref','alpha');
  56. $socid=GETPOST('socid','int');
  57. $action=GETPOST('action','alpha');
  58. $confirm=GETPOST('confirm','alpha');
  59. $lineid=GETPOST('lineid','int');
  60. $userid=GETPOST('userid','int');
  61. $search_ref=GETPOST('sf_ref')?GETPOST('sf_ref','alpha'):GETPOST('search_ref','alpha');
  62. $search_societe=GETPOST('search_societe','alpha');
  63. $search_montant_ht=GETPOST('search_montant_ht','alpha');
  64. $search_montant_ttc=GETPOST('search_montant_ttc','alpha');
  65. //PDF
  66. $hidedetails = (GETPOST('hidedetails','int') ? GETPOST('hidedetails','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0));
  67. $hidedesc = (GETPOST('hidedesc','int') ? GETPOST('hidedesc','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0));
  68. $hideref = (GETPOST('hideref','int') ? GETPOST('hideref','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0));
  69. // Security check
  70. $fieldid = (! empty($ref)?'facnumber':'rowid');
  71. if ($user->societe_id) $socid=$user->societe_id;
  72. $result = restrictedArea($user, 'facture', $id,'','','fk_soc',$fieldid);
  73. // Nombre de ligne pour choix de produit/service predefinis
  74. $NBLINES=4;
  75. $usehm=(! empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE)?$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE:0);
  76. $object=new Facture($db);
  77. // Load object
  78. if ($id > 0 || ! empty($ref))
  79. {
  80. $ret=$object->fetch($id, $ref);
  81. }
  82. // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array
  83. include_once(DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php');
  84. $hookmanager=new HookManager($db);
  85. $hookmanager->initHooks(array('invoicecard'));
  86. /*
  87. * Actions
  88. */
  89. $parameters=array('socid'=>$socid);
  90. $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks
  91. // Action clone object
  92. if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->facture->creer)
  93. {
  94. if (1==0 && empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"]))
  95. {
  96. $mesgs[]='<div class="error">'.$langs->trans("NoCloneOptionsSpecified").'</div>';
  97. }
  98. else
  99. {
  100. if ($object->fetch($id) > 0)
  101. {
  102. $result=$object->createFromClone($socid, $hookmanager);
  103. if ($result > 0)
  104. {
  105. header("Location: ".$_SERVER['PHP_SELF'].'?facid='.$result);
  106. exit;
  107. }
  108. else
  109. {
  110. $mesgs[]=$object->error;
  111. $action='';
  112. }
  113. }
  114. }
  115. }
  116. // Change status of invoice
  117. else if ($action == 'reopen' && $user->rights->facture->creer)
  118. {
  119. $result = $object->fetch($id);
  120. if ($object->statut == 2
  121. || ($object->statut == 3 && $object->close_code != 'replaced'))
  122. {
  123. $result = $object->set_unpaid($user);
  124. if ($result > 0)
  125. {
  126. Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id);
  127. exit;
  128. }
  129. else
  130. {
  131. $mesgs[]='<div class="error">'.$object->error.'</div>';
  132. }
  133. }
  134. }
  135. // Delete invoice
  136. else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->facture->supprimer)
  137. {
  138. $result = $object->fetch($id);
  139. $object->fetch_thirdparty();
  140. $result = $object->delete();
  141. if ($result > 0)
  142. {
  143. Header('Location: '.DOL_URL_ROOT.'/compta/facture/list.php');
  144. exit;
  145. }
  146. else
  147. {
  148. $mesgs[]='<div class="error">'.$object->error.'</div>';
  149. }
  150. }
  151. // Delete line
  152. else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->facture->creer)
  153. {
  154. $object->fetch($id);
  155. $object->fetch_thirdparty();
  156. $result = $object->deleteline($_GET['lineid'], $user);
  157. if ($result > 0)
  158. {
  159. // Define output language
  160. $outputlangs = $langs;
  161. $newlang='';
  162. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
  163. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
  164. if (! empty($newlang))
  165. {
  166. $outputlangs = new Translate("",$conf);
  167. $outputlangs->setDefaultLang($newlang);
  168. }
  169. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
  170. {
  171. $ret=$object->fetch($id); // Reload to get new records
  172. $result=facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
  173. }
  174. if ($result >= 0)
  175. {
  176. Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id);
  177. exit;
  178. }
  179. }
  180. else
  181. {
  182. $mesgs[]='<div clas="error">'.$object->error.'</div>';
  183. $action='';
  184. }
  185. }
  186. // Delete link of credit note to invoice
  187. else if ($action == 'unlinkdiscount' && $user->rights->facture->creer)
  188. {
  189. $discount=new DiscountAbsolute($db);
  190. $result=$discount->fetch($_GET["discountid"]);
  191. $discount->unlink_invoice();
  192. }
  193. // Validation
  194. else if ($action == 'valid' && $user->rights->facture->creer)
  195. {
  196. $object->fetch($id);
  197. // On verifie signe facture
  198. if ($object->type == 2)
  199. {
  200. // Si avoir, le signe doit etre negatif
  201. if ($object->total_ht >= 0)
  202. {
  203. $mesgs[]='<div class="error">'.$langs->trans("ErrorInvoiceAvoirMustBeNegative").'</div>';
  204. $action='';
  205. }
  206. }
  207. else
  208. {
  209. // Si non avoir, le signe doit etre positif
  210. if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ht < 0)
  211. {
  212. $mesgs[]='<div class="error">'.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive").'</div>';
  213. $action='';
  214. }
  215. }
  216. }
  217. else if ($action == 'set_thirdparty' && $user->rights->facture->creer)
  218. {
  219. $object->fetch($id);
  220. $object->setValueFrom('fk_soc',$socid);
  221. Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id);
  222. exit;
  223. }
  224. else if ($action == 'classin' && $user->rights->facture->creer)
  225. {
  226. $object->fetch($id);
  227. $object->setProject($_POST['projectid']);
  228. }
  229. else if ($action == 'setmode' && $user->rights->facture->creer)
  230. {
  231. $object->fetch($id);
  232. $result = $object->setPaymentMethods(GETPOST('mode_reglement_id','int'));
  233. if ($result < 0) dol_print_error($db,$object->error);
  234. }
  235. else if ($action == 'setinvoicedate' && $user->rights->facture->creer)
  236. {
  237. $object->fetch($id);
  238. $object->date=dol_mktime(12,0,0,$_POST['invoicedatemonth'],$_POST['invoicedateday'],$_POST['invoicedateyear']);
  239. if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement=$object->date;
  240. $result=$object->update($user);
  241. if ($result < 0) dol_print_error($db,$object->error);
  242. }
  243. else if ($action == 'setpaymentterm' && $user->rights->facture->creer)
  244. {
  245. $object->fetch($id);
  246. $object->date_lim_reglement=dol_mktime(12,0,0,$_POST['paymenttermmonth'],$_POST['paymenttermday'],$_POST['paymenttermyear']);
  247. if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement=$object->date;
  248. $result=$object->update($user);
  249. if ($result < 0) dol_print_error($db,$object->error);
  250. }
  251. else if ($action == 'setconditions' && $user->rights->facture->creer)
  252. {
  253. $object->fetch($id);
  254. $result=$object->setPaymentTerms(GETPOST('cond_reglement_id','int'));
  255. if ($result < 0) dol_print_error($db,$object->error);
  256. }
  257. else if ($action == 'setremisepercent' && $user->rights->facture->creer)
  258. {
  259. $object->fetch($id);
  260. $result = $object->set_remise($user, $_POST['remise_percent']);
  261. }
  262. else if ($action == "setabsolutediscount" && $user->rights->facture->creer)
  263. {
  264. // POST[remise_id] ou POST[remise_id_for_payment]
  265. if (! empty($_POST["remise_id"]))
  266. {
  267. $ret=$object->fetch($id);
  268. if ($ret > 0)
  269. {
  270. $result=$object->insert_discount($_POST["remise_id"]);
  271. if ($result < 0)
  272. {
  273. $mesgs[]='<div class="error">'.$object->error.'</div>';
  274. }
  275. }
  276. else
  277. {
  278. dol_print_error($db,$object->error);
  279. }
  280. }
  281. if (! empty($_POST["remise_id_for_payment"]))
  282. {
  283. require_once(DOL_DOCUMENT_ROOT.'/core/class/discount.class.php');
  284. $discount = new DiscountAbsolute($db);
  285. $discount->fetch($_POST["remise_id_for_payment"]);
  286. $result=$discount->link_to_invoice(0,$id);
  287. if ($result < 0)
  288. {
  289. $mesgs[]='<div class="error">'.$discount->error.'</div>';
  290. }
  291. }
  292. }
  293. else if ($action == 'set_ref_client' && $user->rights->facture->creer)
  294. {
  295. $object->fetch($id);
  296. $object->set_ref_client($_POST['ref_client']);
  297. }
  298. else if ($action == 'setnote_public' && $user->rights->facture->creer)
  299. {
  300. $object->fetch($id);
  301. $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES));
  302. if ($result < 0) dol_print_error($db,$object->error);
  303. }
  304. else if ($action == 'setnote' && $user->rights->facture->creer)
  305. {
  306. $object->fetch($id);
  307. $result=$object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES));
  308. if ($result < 0) dol_print_error($db,$object->error);
  309. }
  310. // Classify to validated
  311. else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->facture->valider)
  312. {
  313. $idwarehouse=GETPOST('idwarehouse');
  314. $object->fetch($id);
  315. $object->fetch_thirdparty();
  316. // Check parameters
  317. if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1))
  318. {
  319. if (! $idwarehouse || $idwarehouse == -1)
  320. {
  321. $error++;
  322. $mesgs[]=$langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse"));
  323. $action='';
  324. }
  325. }
  326. if (! $error)
  327. {
  328. $result = $object->validate($user,'',$idwarehouse);
  329. if ($result >= 0)
  330. {
  331. // Define output language
  332. $outputlangs = $langs;
  333. $newlang='';
  334. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
  335. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
  336. if (! empty($newlang))
  337. {
  338. $outputlangs = new Translate("",$conf);
  339. $outputlangs->setDefaultLang($newlang);
  340. }
  341. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
  342. {
  343. $ret=$object->fetch($id); // Reload to get new records
  344. facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
  345. }
  346. }
  347. else
  348. {
  349. $mesgs[]='<div class="error">'.$object->error.'</div>';
  350. }
  351. }
  352. }
  353. // Go back to draft status (unvalidate)
  354. else if ($action == 'confirm_modif' && ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate))
  355. {
  356. $idwarehouse=GETPOST('idwarehouse');
  357. $object->fetch($id);
  358. $object->fetch_thirdparty();
  359. // Check parameters
  360. if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1))
  361. {
  362. if (! $idwarehouse || $idwarehouse == -1)
  363. {
  364. $error++;
  365. $mesgs[]=$langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse"));
  366. $action='';
  367. }
  368. }
  369. if (! $error)
  370. {
  371. // On verifie si la facture a des paiements
  372. $sql = 'SELECT pf.amount';
  373. $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf';
  374. $sql.= ' WHERE pf.fk_facture = '.$object->id;
  375. $result = $db->query($sql);
  376. if ($result)
  377. {
  378. $i = 0;
  379. $num = $db->num_rows($result);
  380. while ($i < $num)
  381. {
  382. $objp = $db->fetch_object($result);
  383. $totalpaye += $objp->amount;
  384. $i++;
  385. }
  386. }
  387. else
  388. {
  389. dol_print_error($db,'');
  390. }
  391. $resteapayer = $object->total_ttc - $totalpaye;
  392. // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees
  393. $ventilExportCompta = $object->getVentilExportCompta();
  394. // On verifie si aucun paiement n'a ete effectue
  395. if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0)
  396. {
  397. $object->set_draft($user, $idwarehouse);
  398. // Define output language
  399. $outputlangs = $langs;
  400. $newlang='';
  401. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
  402. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
  403. if (! empty($newlang))
  404. {
  405. $outputlangs = new Translate("",$conf);
  406. $outputlangs->setDefaultLang($newlang);
  407. }
  408. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
  409. {
  410. $ret=$object->fetch($id); // Reload to get new records
  411. facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
  412. }
  413. }
  414. }
  415. }
  416. // Classify "paid"
  417. else if ($action == 'confirm_paid' && $confirm == 'yes' && $user->rights->facture->paiement)
  418. {
  419. $object->fetch($id);
  420. $result = $object->set_paid($user);
  421. }
  422. // Classif "paid partialy"
  423. else if ($action == 'confirm_paid_partially' && $confirm == 'yes' && $user->rights->facture->paiement)
  424. {
  425. $object->fetch($id);
  426. $close_code=$_POST["close_code"];
  427. $close_note=$_POST["close_note"];
  428. if ($close_code)
  429. {
  430. $result = $object->set_paid($user,$close_code,$close_note);
  431. }
  432. else
  433. {
  434. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("Reason")).'</div>';
  435. }
  436. }
  437. // Classify "abandoned"
  438. else if ($action == 'confirm_canceled' && $confirm == 'yes')
  439. {
  440. $object->fetch($id);
  441. $close_code=$_POST["close_code"];
  442. $close_note=$_POST["close_note"];
  443. if ($close_code)
  444. {
  445. $result = $object->set_canceled($user,$close_code,$close_note);
  446. }
  447. else
  448. {
  449. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("Reason")).'</div>';
  450. }
  451. }
  452. // Convertir en reduc
  453. else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->facture->creer)
  454. {
  455. $db->begin();
  456. $object->fetch($id);
  457. $object->fetch_thirdparty();
  458. $object->fetch_lines();
  459. if (! $object->paye) // protection against multiple submit
  460. {
  461. // Boucle sur chaque taux de tva
  462. $i=0;
  463. foreach($object->lines as $line)
  464. {
  465. $amount_ht[$line->tva_tx]+=$line->total_ht;
  466. $amount_tva[$line->tva_tx]+=$line->total_tva;
  467. $amount_ttc[$line->tva_tx]+=$line->total_ttc;
  468. $i++;
  469. }
  470. // Insert one discount by VAT rate category
  471. $discount = new DiscountAbsolute($db);
  472. if ($object->type == 2) $discount->description='(CREDIT_NOTE)';
  473. elseif ($object->type == 3) $discount->description='(DEPOSIT)';
  474. else {
  475. $this->error="CantConvertToReducAnInvoiceOfThisType";
  476. return -1;
  477. }
  478. $discount->tva_tx=abs($object->total_ttc);
  479. $discount->fk_soc=$object->socid;
  480. $discount->fk_facture_source=$object->id;
  481. $error=0;
  482. foreach($amount_ht as $tva_tx => $xxx)
  483. {
  484. $discount->amount_ht=abs($amount_ht[$tva_tx]);
  485. $discount->amount_tva=abs($amount_tva[$tva_tx]);
  486. $discount->amount_ttc=abs($amount_ttc[$tva_tx]);
  487. $discount->tva_tx=abs($tva_tx);
  488. $result=$discount->create($user);
  489. if ($result < 0)
  490. {
  491. $error++;
  492. break;
  493. }
  494. }
  495. if (! $error)
  496. {
  497. // Classe facture
  498. $result=$object->set_paid($user);
  499. if ($result > 0)
  500. {
  501. //$mesgs[]='OK'.$discount->id;
  502. $db->commit();
  503. }
  504. else
  505. {
  506. $mesgs[]='<div class="error">'.$object->error.'</div>';
  507. $db->rollback();
  508. }
  509. }
  510. else
  511. {
  512. $mesgs[]='<div class="error">'.$discount->error.'</div>';
  513. $db->rollback();
  514. }
  515. }
  516. }
  517. /*
  518. * Insert new invoice in database
  519. */
  520. else if ($action == 'add' && $user->rights->facture->creer)
  521. {
  522. $object->socid=GETPOST('socid','int');
  523. $db->begin();
  524. $error=0;
  525. // Replacement invoice
  526. if ($_POST['type'] == 1)
  527. {
  528. $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
  529. if (empty($datefacture))
  530. {
  531. $error++;
  532. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("Date")).'</div>';
  533. }
  534. if (! ($_POST['fac_replacement'] > 0))
  535. {
  536. $error++;
  537. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("ReplaceInvoice")).'</div>';
  538. }
  539. if (! $error)
  540. {
  541. // This is a replacement invoice
  542. $result=$object->fetch($_POST['fac_replacement']);
  543. $object->fetch_thirdparty();
  544. $object->date = $datefacture;
  545. $object->note_public = trim($_POST['note_public']);
  546. $object->note = trim($_POST['note']);
  547. $object->ref_client = $_POST['ref_client'];
  548. $object->ref_int = $_POST['ref_int'];
  549. $object->modelpdf = $_POST['model'];
  550. $object->fk_project = $_POST['projectid'];
  551. $object->cond_reglement_id = $_POST['cond_reglement_id'];
  552. $object->mode_reglement_id = $_POST['mode_reglement_id'];
  553. $object->remise_absolue = $_POST['remise_absolue'];
  554. $object->remise_percent = $_POST['remise_percent'];
  555. // Proprietes particulieres a facture de remplacement
  556. $object->fk_facture_source = $_POST['fac_replacement'];
  557. $object->type = 1;
  558. $id=$object->createFromCurrent($user);
  559. if ($id <= 0) $mesgs[]=$object->error;
  560. }
  561. }
  562. // Credit note invoice
  563. if ($_POST['type'] == 2)
  564. {
  565. if (! $_POST['fac_avoir'] > 0)
  566. {
  567. $error++;
  568. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("CorrectInvoice")).'</div>';
  569. }
  570. $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
  571. if (empty($datefacture))
  572. {
  573. $error++;
  574. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("Date")).'</div>';
  575. }
  576. if (! $error)
  577. {
  578. // Si facture avoir
  579. $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
  580. //$result=$object->fetch($_POST['fac_avoir']);
  581. $object->socid = $_POST['socid'];
  582. $object->number = $_POST['facnumber'];
  583. $object->date = $datefacture;
  584. $object->note_public = trim($_POST['note_public']);
  585. $object->note = trim($_POST['note']);
  586. $object->ref_client = $_POST['ref_client'];
  587. $object->ref_int = $_POST['ref_int'];
  588. $object->modelpdf = $_POST['model'];
  589. $object->fk_project = $_POST['projectid'];
  590. $object->cond_reglement_id = 0;
  591. $object->mode_reglement_id = $_POST['mode_reglement_id'];
  592. $object->remise_absolue = $_POST['remise_absolue'];
  593. $object->remise_percent = $_POST['remise_percent'];
  594. // Proprietes particulieres a facture avoir
  595. $object->fk_facture_source = $_POST['fac_avoir'];
  596. $object->type = 2;
  597. $id = $object->create($user);
  598. // Add predefined lines
  599. for ($i = 1; $i <= $NBLINES; $i++)
  600. {
  601. if ($_POST['idprod'.$i])
  602. {
  603. $product=new Product($db);
  604. $product->fetch($_POST['idprod'.$i]);
  605. $startday=dol_mktime(12, 0, 0, $_POST['date_start'.$i.'month'], $_POST['date_start'.$i.'day'], $_POST['date_start'.$i.'year']);
  606. $endday=dol_mktime(12, 0, 0, $_POST['date_end'.$i.'month'], $_POST['date_end'.$i.'day'], $_POST['date_end'.$i.'year']);
  607. $result=$object->addline($id,$product->description,$product->price, $_POST['qty'.$i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod'.$i], $_POST['remise_percent'.$i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type);
  608. }
  609. }
  610. }
  611. }
  612. // Standard invoice or Deposit invoice created from a Predefined invoice
  613. if (($_POST['type'] == 0 || $_POST['type'] == 3) && $_POST['fac_rec'] > 0)
  614. {
  615. $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
  616. if (empty($datefacture))
  617. {
  618. $error++;
  619. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("Date")).'</div>';
  620. }
  621. if (! $error)
  622. {
  623. $object->socid = $_POST['socid'];
  624. $object->type = $_POST['type'];
  625. $object->number = $_POST['facnumber'];
  626. $object->date = $datefacture;
  627. $object->note_public = trim($_POST['note_public']);
  628. $object->note = trim($_POST['note']);
  629. $object->ref_client = $_POST['ref_client'];
  630. $object->ref_int = $_POST['ref_int'];
  631. $object->modelpdf = $_POST['model'];
  632. // Source facture
  633. $object->fac_rec = $_POST['fac_rec'];
  634. $id = $object->create($user);
  635. }
  636. }
  637. // Standard or deposit or proforma invoice
  638. if (($_POST['type'] == 0 || $_POST['type'] == 3 || $_POST['type'] == 4) && $_POST['fac_rec'] <= 0)
  639. {
  640. $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
  641. if (empty($datefacture))
  642. {
  643. $error++;
  644. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("Date")).'</div>';
  645. }
  646. if (! $error)
  647. {
  648. // Si facture standard
  649. $object->socid = $_POST['socid'];
  650. $object->type = $_POST['type'];
  651. $object->number = $_POST['facnumber'];
  652. $object->date = $datefacture;
  653. $object->note_public = trim($_POST['note_public']);
  654. $object->note = trim($_POST['note']);
  655. $object->ref_client = $_POST['ref_client'];
  656. $object->ref_int = $_POST['ref_int'];
  657. $object->modelpdf = $_POST['model'];
  658. $object->fk_project = $_POST['projectid'];
  659. $object->cond_reglement_id = ($_POST['type'] == 3?1:$_POST['cond_reglement_id']);
  660. $object->mode_reglement_id = $_POST['mode_reglement_id'];
  661. $object->amount = $_POST['amount'];
  662. $object->remise_absolue = $_POST['remise_absolue'];
  663. $object->remise_percent = $_POST['remise_percent'];
  664. // If creation from another object of another module (Example: origin=propal, originid=1)
  665. if ($_POST['origin'] && $_POST['originid'])
  666. {
  667. // Parse element/subelement (ex: project_task)
  668. $element = $subelement = $_POST['origin'];
  669. if (preg_match('/^([^_]+)_([^_]+)/i',$_POST['origin'],$regs))
  670. {
  671. $element = $regs[1];
  672. $subelement = $regs[2];
  673. }
  674. // For compatibility
  675. if ($element == 'order') { $element = $subelement = 'commande'; }
  676. if ($element == 'propal') { $element = 'comm/propal'; $subelement = 'propal'; }
  677. if ($element == 'contract') { $element = $subelement = 'contrat'; }
  678. if ($element == 'inter') { $element = $subelement = 'ficheinter'; }
  679. if ($element == 'shipping') {$element = $subelement = 'expedition'; }
  680. $object->origin = $_POST['origin'];
  681. $object->origin_id = $_POST['originid'];
  682. // Possibility to add external linked objects with hooks
  683. $object->linked_objects[$object->origin] = $object->origin_id;
  684. if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects']))
  685. {
  686. $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']);
  687. }
  688. $id = $object->create($user);
  689. if ($id > 0)
  690. {
  691. dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
  692. $classname = ucfirst($subelement);
  693. $srcobject = new $classname($db);
  694. dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines");
  695. $result=$srcobject->fetch($object->origin_id);
  696. if ($result > 0)
  697. {
  698. $lines = $srcobject->lines;
  699. if (empty($lines) && method_exists($srcobject,'fetch_lines')) $lines = $srcobject->fetch_lines();
  700. $fk_parent_line=0;
  701. $num=count($lines);
  702. for ($i=0;$i<$num;$i++)
  703. {
  704. $desc=($lines[$i]->desc?$lines[$i]->desc:$lines[$i]->libelle);
  705. if ($lines[$i]->subprice < 0)
  706. {
  707. // Negative line, we create a discount line
  708. $discount = new DiscountAbsolute($db);
  709. $discount->fk_soc=$object->socid;
  710. $discount->amount_ht=abs($lines[$i]->total_ht);
  711. $discount->amount_tva=abs($lines[$i]->total_tva);
  712. $discount->amount_ttc=abs($lines[$i]->total_ttc);
  713. $discount->tva_tx=$lines[$i]->tva_tx;
  714. $discount->fk_user=$user->id;
  715. $discount->description=$desc;
  716. $discountid=$discount->create($user);
  717. if ($discountid > 0)
  718. {
  719. $result=$object->insert_discount($discountid); // This include link_to_invoice
  720. }
  721. else
  722. {
  723. $mesgs[]=$discount->error;
  724. $error++;
  725. break;
  726. }
  727. }
  728. else
  729. {
  730. // Positive line
  731. $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0);
  732. // Date start
  733. $date_start=false;
  734. if ($lines[$i]->date_debut_prevue) $date_start=$lines[$i]->date_debut_prevue;
  735. if ($lines[$i]->date_debut_reel) $date_start=$lines[$i]->date_debut_reel;
  736. if ($lines[$i]->date_start) $date_start=$lines[$i]->date_start;
  737. //Date end
  738. $date_end=false;
  739. if ($lines[$i]->date_fin_prevue) $date_end=$lines[$i]->date_fin_prevue;
  740. if ($lines[$i]->date_fin_reel) $date_end=$lines[$i]->date_fin_reel;
  741. if ($lines[$i]->date_end) $date_end=$lines[$i]->date_end;
  742. // Reset fk_parent_line for no child products and special product
  743. if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) {
  744. $fk_parent_line = 0;
  745. }
  746. $result = $object->addline(
  747. $id,
  748. $desc,
  749. $lines[$i]->subprice,
  750. $lines[$i]->qty,
  751. $lines[$i]->tva_tx,
  752. $lines[$i]->localtax1_tx,
  753. $lines[$i]->localtax2_tx,
  754. $lines[$i]->fk_product,
  755. $lines[$i]->remise_percent,
  756. $date_start,
  757. $date_end,
  758. 0,
  759. $lines[$i]->info_bits,
  760. $lines[$i]->fk_remise_except,
  761. 'HT',
  762. 0,
  763. $product_type,
  764. $lines[$i]->rang,
  765. $lines[$i]->special_code,
  766. $object->origin,
  767. $lines[$i]->rowid,
  768. $fk_parent_line,
  769. $lines[$i]->fk_fournprice,
  770. $lines[$i]->pa_ht
  771. );
  772. if ($result > 0)
  773. {
  774. $lineid=$result;
  775. }
  776. else
  777. {
  778. $lineid=0;
  779. $error++;
  780. break;
  781. }
  782. // Defined the new fk_parent_line
  783. if ($result > 0 && $lines[$i]->product_type == 9) {
  784. $fk_parent_line = $result;
  785. }
  786. }
  787. }
  788. // Hooks
  789. $parameters=array('objFrom'=>$srcobject);
  790. $reshook=$hookmanager->executeHooks('createFrom',$parameters,$object,$action); // Note that $action and $object may have been modified by hook
  791. if ($reshook < 0) $error++;
  792. }
  793. else
  794. {
  795. $mesgs[]=$srcobject->error;
  796. $error++;
  797. }
  798. }
  799. else
  800. {
  801. $mesgs[]=$object->error;
  802. $error++;
  803. }
  804. }
  805. // If some invoice's lines already known
  806. else
  807. {
  808. $id = $object->create($user);
  809. for ($i = 1; $i <= $NBLINES; $i++)
  810. {
  811. if ($_POST['idprod'.$i])
  812. {
  813. $product=new Product($db);
  814. $product->fetch($_POST['idprod'.$i]);
  815. $startday=dol_mktime(12, 0, 0, $_POST['date_start'.$i.'month'], $_POST['date_start'.$i.'day'], $_POST['date_start'.$i.'year']);
  816. $endday=dol_mktime(12, 0, 0, $_POST['date_end'.$i.'month'], $_POST['date_end'.$i.'day'], $_POST['date_end'.$i.'year']);
  817. $result=$object->addline($id,$product->description,$product->price, $_POST['qty'.$i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod'.$i], $_POST['remise_percent'.$i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type);
  818. }
  819. }
  820. }
  821. }
  822. }
  823. // End of object creation, we show it
  824. if ($id > 0 && ! $error)
  825. {
  826. $db->commit();
  827. Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id);
  828. exit;
  829. }
  830. else
  831. {
  832. $db->rollback();
  833. $action='create';
  834. $_GET["origin"]=$_POST["origin"];
  835. $_GET["originid"]=$_POST["originid"];
  836. $mesgs[]='<div class="error">'.$object->error.'</div>';
  837. }
  838. }
  839. // Add a new line
  840. else if (($action == 'addline' || $action == 'addline_predef') && $user->rights->facture->creer)
  841. {
  842. $result=0;
  843. if ($_POST['np_price'] < 0 && $_POST["qty"] < 0)
  844. {
  845. $langs->load("errors");
  846. $mesgs[]='<div class="error">'.$langs->trans("ErrorBothFieldCantBeNegative",$langs->transnoentitiesnoconv("UnitPriceHT"),$langs->transnoentitiesnoconv("Qty")).'</div>';
  847. $result = -1 ;
  848. }
  849. if (empty($_POST['idprod']) && $_POST["type"] < 0)
  850. {
  851. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")).'</div>';
  852. $result = -1 ;
  853. }
  854. if (empty($_POST['idprod']) && (! isset($_POST["np_price"]) || $_POST["np_price"]=='')) // Unit price can be 0 but not ''
  855. {
  856. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("UnitPriceHT")).'</div>';
  857. $result = -1 ;
  858. }
  859. if (empty($_POST['idprod']) && empty($_POST["np_desc"]) && empty($_POST["dp_desc"]))
  860. {
  861. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Description")).'</div>';
  862. $result = -1 ;
  863. }
  864. if (! isset($_POST['qty']) || $_POST['qty']=='')
  865. {
  866. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv('Qty')).'</div>';
  867. $result = -1 ;
  868. }
  869. if ($result >= 0 && ( ($_POST['np_price']!='' && ($_POST['np_desc'] || $_POST['dp_desc'])) || $_POST['idprod'] ) )
  870. {
  871. $ret=$object->fetch($id);
  872. if ($ret < 0)
  873. {
  874. dol_print_error($db,$object->error);
  875. exit;
  876. }
  877. $ret=$object->fetch_thirdparty();
  878. $suffixe = $_POST['idprod'] ? '_predef' : '';
  879. $date_start=dol_mktime($_POST['date_start'.$suffixe.'hour'],$_POST['date_start'.$suffixe.'min'],$_POST['date_start'.$suffixe.'sec'],$_POST['date_start'.$suffixe.'month'],$_POST['date_start'.$suffixe.'day'],$_POST['date_start'.$suffixe.'year']);
  880. $date_end=dol_mktime($_POST['date_end'.$suffixe.'hour'],$_POST['date_end'.$suffixe.'min'],$_POST['date_end'.$suffixe.'sec'],$_POST['date_end'.$suffixe.'month'],$_POST['date_end'.$suffixe.'day'],$_POST['date_end'.$suffixe.'year']);
  881. $price_base_type = 'HT';
  882. // Ecrase $pu par celui du produit
  883. // Ecrase $desc par celui du produit
  884. // Ecrase $txtva par celui du produit
  885. // Ecrase $base_price_type par celui du produit
  886. if ($_POST['idprod'])
  887. {
  888. $prod = new Product($db);
  889. $prod->fetch($_POST['idprod']);
  890. $tva_tx = get_default_tva($mysoc,$object->client,$prod->id);
  891. $tva_npr = get_default_npr($mysoc,$object->client,$prod->id);
  892. // We define price for product
  893. if ($conf->global->PRODUIT_MULTIPRICES && $object->client->price_level)
  894. {
  895. $pu_ht = $prod->multiprices[$object->client->price_level];
  896. $pu_ttc = $prod->multiprices_ttc[$object->client->price_level];
  897. $price_min = $prod->multiprices_min[$object->client->price_level];
  898. $price_base_type = $prod->multiprices_base_type[$object->client->price_level];
  899. }
  900. else
  901. {
  902. $pu_ht = $prod->price;
  903. $pu_ttc = $prod->price_ttc;
  904. $price_min = $prod->price_min;
  905. $price_base_type = $prod->price_base_type;
  906. }
  907. // On reevalue prix selon taux tva car taux tva transaction peut etre different
  908. // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur).
  909. if ($tva_tx != $prod->tva_tx)
  910. {
  911. if ($price_base_type != 'HT')
  912. {
  913. $pu_ht = price2num($pu_ttc / (1 + ($tva_tx/100)), 'MU');
  914. }
  915. else
  916. {
  917. $pu_ttc = price2num($pu_ht * (1 + ($tva_tx/100)), 'MU');
  918. }
  919. }
  920. // Define output language
  921. if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE))
  922. {
  923. $outputlangs = $langs;
  924. $newlang='';
  925. if (empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id');
  926. if (empty($newlang)) $newlang=$object->client->default_lang;
  927. if (! empty($newlang))
  928. {
  929. $outputlangs = new Translate("",$conf);
  930. $outputlangs->setDefaultLang($newlang);
  931. }
  932. $desc = (! empty($prod->multilangs[$outputlangs->defaultlang]["description"])) ? $prod->multilangs[$outputlangs->defaultlang]["description"] : $prod->description;
  933. }
  934. else
  935. {
  936. $desc = $prod->description;
  937. }
  938. $desc.= ($desc && $_POST['np_desc']) ? ((dol_textishtml($desc) || dol_textishtml($_POST['np_desc']))?"<br>\n":"\n") : "";
  939. $desc.= $_POST['np_desc'];
  940. if (! empty($prod->customcode) || ! empty($prod->country_code))
  941. {
  942. $tmptxt='(';
  943. if (! empty($prod->customcode)) $tmptxt.=$langs->transnoentitiesnoconv("CustomCode").': '.$prod->customcode;
  944. if (! empty($prod->customcode) && ! empty($prod->country_code)) $tmptxt.=' - ';
  945. if (! empty($prod->country_code)) $tmptxt.=$langs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code,0,$db,$langs,0);
  946. $tmptxt.=')';
  947. $desc.= (dol_textishtml($desc)?"<br>\n":"\n").$tmptxt;
  948. }
  949. $type = $prod->type;
  950. }
  951. else
  952. {
  953. $pu_ht=$_POST['np_price'];
  954. $tva_tx=str_replace('*','',$_POST['np_tva_tx']);
  955. $tva_npr=preg_match('/\*/',$_POST['np_tva_tx'])?1:0;
  956. $desc=$_POST['dp_desc'];
  957. $type=$_POST["type"];
  958. }
  959. $localtax1_tx=get_localtax($tva_tx,1,$object->client);
  960. $localtax2_tx=get_localtax($tva_tx,2,$object->client);
  961. // ajout prix achat
  962. $fk_fournprice = $_POST['np_fournprice'];
  963. if ( ! empty($_POST['np_buying_price']) )
  964. $pa_ht = $_POST['np_buying_price'];
  965. else
  966. $pa_ht = null;
  967. $info_bits=0;
  968. if ($tva_npr) $info_bits |= 0x01;
  969. if ($result >= 0)
  970. {
  971. if($price_min && (price2num($pu_ht)*(1-price2num($_POST['remise_percent'])/100) < price2num($price_min)))
  972. {
  973. $object->error = $langs->trans("CantBeLessThanMinPrice",price2num($price_min,'MU').' '.$langs->trans("Currency".$conf->currency));
  974. $result = -1 ;
  975. }
  976. else
  977. {
  978. // Insert line
  979. $result = $object->addline(
  980. $id,
  981. $desc,
  982. $pu_ht,
  983. $_POST['qty'],
  984. $tva_tx,
  985. $localtax1_tx,
  986. $localtax2_tx,
  987. $_POST['idprod'],
  988. $_POST['remise_percent'],
  989. $date_start,
  990. $date_end,
  991. 0,
  992. $info_bits,
  993. '',
  994. $price_base_type,
  995. $pu_ttc,
  996. $type,
  997. -1,
  998. 0,
  999. '',
  1000. 0,
  1001. GETPOST('fk_parent_line'),
  1002. $fk_fournprice,
  1003. $pa_ht
  1004. );
  1005. }
  1006. }
  1007. }
  1008. if ($result > 0)
  1009. {
  1010. // Define output language
  1011. $outputlangs = $langs;
  1012. $newlang='';
  1013. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
  1014. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
  1015. if (! empty($newlang))
  1016. {
  1017. $outputlangs = new Translate("",$conf);
  1018. $outputlangs->setDefaultLang($newlang);
  1019. }
  1020. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
  1021. {
  1022. $ret=$object->fetch($id); // Reload to get new records
  1023. facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
  1024. }
  1025. unset($_POST['qty']);
  1026. unset($_POST['type']);
  1027. unset($_POST['idprod']);
  1028. unset($_POST['remise_percent']);
  1029. unset($_POST['dp_desc']);
  1030. unset($_POST['np_desc']);
  1031. unset($_POST['np_price']);
  1032. unset($_POST['np_tva_tx']);
  1033. unset($_POST['np_buying_price']);
  1034. }
  1035. else
  1036. {
  1037. $mesgs[]='<div class="error">'.$object->error.'</div>';
  1038. }
  1039. $action='';
  1040. }
  1041. else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['save'] == $langs->trans('Save'))
  1042. {
  1043. if (! $object->fetch($id) > 0) dol_print_error($db);
  1044. $object->fetch_thirdparty();
  1045. // Clean parameters
  1046. $date_start='';
  1047. $date_end='';
  1048. $date_start=dol_mktime($_POST['date_start'.$suffixe.'hour'],$_POST['date_start'.$suffixe.'min'],$_POST['date_start'.$suffixe.'sec'],$_POST['date_start'.$suffixe.'month'],$_POST['date_start'.$suffixe.'day'],$_POST['date_start'.$suffixe.'year']);
  1049. $date_end=dol_mktime($_POST['date_end'.$suffixe.'hour'],$_POST['date_end'.$suffixe.'min'],$_POST['date_end'.$suffixe.'sec'],$_POST['date_end'.$suffixe.'month'],$_POST['date_end'.$suffixe.'day'],$_POST['date_end'.$suffixe.'year']);
  1050. $description=dol_htmlcleanlastbr($_POST['desc']);
  1051. $up_ht=GETPOST('pu')?GETPOST('pu'):GETPOST('subprice');
  1052. // Define info_bits
  1053. $info_bits=0;
  1054. if (preg_match('/\*/',$_POST['tva_tx'])) $info_bits |= 0x01;
  1055. // Define vat_rate
  1056. $vat_rate=$_POST['tva_tx'];
  1057. $vat_rate=str_replace('*','',$vat_rate);
  1058. $localtax1_rate=get_localtax($vat_rate,1,$object->client);
  1059. $localtax2_rate=get_localtax($vat_rate,2,$object->client);
  1060. // ajout prix d'achat
  1061. $fk_fournprice = $_POST['fournprice'];
  1062. if ( ! empty($_POST['buying_price']) )
  1063. $pa_ht = $_POST['buying_price'];
  1064. else
  1065. $pa_ht = null;
  1066. // Check parameters
  1067. if (! GETPOST('productid') && GETPOST("type") < 0)
  1068. {
  1069. $mesgs[] = '<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")).'</div>';
  1070. $result = -1 ;
  1071. }
  1072. // Check minimum price
  1073. if (GETPOST('productid'))
  1074. {
  1075. $productid = GETPOST('productid');
  1076. $product = new Product($db);
  1077. $product->fetch($productid);
  1078. $type=$product->type;
  1079. $price_min = $product->price_min;
  1080. if ($conf->global->PRODUIT_MULTIPRICES && $object->client->price_level) $price_min = $product->multiprices_min[$object->client->price_level];
  1081. }
  1082. if ($object->type!=2 && $price_min && GETPOST('productid') && (price2num($up_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min)))
  1083. {
  1084. //print "CantBeLessThanMinPrice ".$up_ht." - ".GETPOST('remise_percent')." - ".$product->price_min;
  1085. $mesgs[] = '<div class="error">'.$langs->trans("CantBeLessThanMinPrice",price2num($price_min,'MU').' '.$langs->trans("Currency".$conf->currency)).'</div>';
  1086. $result=-1;
  1087. }
  1088. // Define params
  1089. if (GETPOST('productid')) $type=$product->type;
  1090. else $type=GETPOST("type");
  1091. // Update line
  1092. if ($result >= 0)
  1093. {
  1094. $result = $object->updateline(
  1095. GETPOST('lineid'),
  1096. $description,
  1097. $up_ht,
  1098. GETPOST('qty'),
  1099. GETPOST('remise_percent'),
  1100. $date_start,
  1101. $date_end,
  1102. $vat_rate,
  1103. $localtax1_rate,
  1104. $localtax2_rate,
  1105. 'HT',
  1106. $info_bits,
  1107. $type,
  1108. GETPOST('fk_parent_line'),
  1109. 0,
  1110. $fk_fournprice,
  1111. $pa_ht
  1112. );
  1113. // Define output language
  1114. $outputlangs = $langs;
  1115. $newlang='';
  1116. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id');
  1117. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
  1118. if (! empty($newlang))
  1119. {
  1120. $outputlangs = new Translate("",$conf);
  1121. $outputlangs->setDefaultLang($newlang);
  1122. }
  1123. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
  1124. {
  1125. $ret=$object->fetch($id); // Reload to get new records
  1126. facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
  1127. unset($_POST['qty']);
  1128. unset($_POST['type']);
  1129. unset($_POST['np_price']);
  1130. unset($_POST['dp_desc']);
  1131. unset($_POST['np_tva_tx']);
  1132. unset($_POST['np_buying_price']);
  1133. }
  1134. }
  1135. }
  1136. else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['cancel'] == $langs->trans('Cancel'))
  1137. {
  1138. Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); // Pour reaffichage de la fiche en cours d'edition
  1139. exit;
  1140. }
  1141. // Modify line position (up)
  1142. else if ($action == 'up' && $user->rights->facture->creer)
  1143. {
  1144. $object->fetch($id);
  1145. $object->fetch_thirdparty();
  1146. $object->line_up($_GET['rowid']);
  1147. // Define output language
  1148. $outputlangs = $langs;
  1149. $newlang='';
  1150. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
  1151. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
  1152. if (! empty($newlang))
  1153. {
  1154. $outputlangs = new Translate("",$conf);
  1155. $outputlangs->setDefaultLang($newlang);
  1156. }
  1157. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
  1158. Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.'#'.$_GET['rowid']);
  1159. exit;
  1160. }
  1161. // Modify line position (down)
  1162. else if ($action == 'down' && $user->rights->facture->creer)
  1163. {
  1164. $object->fetch($id);
  1165. $object->fetch_thirdparty();
  1166. $object->line_down($_GET['rowid']);
  1167. // Define output language
  1168. $outputlangs = $langs;
  1169. $newlang='';
  1170. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
  1171. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
  1172. if (! empty($newlang))
  1173. {
  1174. $outputlangs = new Translate("",$conf);
  1175. $outputlangs->setDefaultLang($newlang);
  1176. }
  1177. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
  1178. Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.'#'.$_GET['rowid']);
  1179. exit;
  1180. }
  1181. /*
  1182. * Add file in email form
  1183. */
  1184. if (GETPOST('addfile'))
  1185. {
  1186. require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
  1187. // Set tmp user directory
  1188. $vardir=$conf->user->dir_output."/".$user->id;
  1189. $upload_dir_tmp = $vardir.'/temp';
  1190. dol_add_file_process($upload_dir_tmp,0,0);
  1191. $action='presend';
  1192. }
  1193. /*
  1194. * Remove file in email form
  1195. */
  1196. if (! empty($_POST['removedfile']))
  1197. {
  1198. require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
  1199. // Set tmp user directory
  1200. $vardir=$conf->user->dir_output."/".$user->id;
  1201. $upload_dir_tmp = $vardir.'/temp';
  1202. // TODO Delete only files that was uploaded from email form
  1203. dol_remove_file_process($_POST['removedfile'],0);
  1204. $action='presend';
  1205. }
  1206. /*
  1207. * Send mail
  1208. */
  1209. if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_POST['removedfile'] && ! $_POST['cancel'])
  1210. {
  1211. $langs->load('mails');
  1212. $actiontypecode='';$subject='';$actionmsg='';$actionmsg2='';
  1213. $result=$object->fetch($id);
  1214. $result=$object->fetch_thirdparty();
  1215. if ($result > 0)
  1216. {
  1217. // $ref = dol_sanitizeFileName($object->ref);
  1218. // $file = $conf->facture->dir_output . '/' . $ref . '/' . $ref . '.pdf';
  1219. // if (is_readable($file))
  1220. // {
  1221. if ($_POST['sendto'])
  1222. {
  1223. // Le destinataire a ete fourni via le champ libre
  1224. $sendto = $_POST['sendto'];
  1225. $sendtoid = 0;
  1226. }
  1227. elseif ($_POST['receiver'] != '-1')
  1228. {
  1229. // Recipient was provided from combo list
  1230. if ($_POST['receiver'] == 'thirdparty') // Id of third party
  1231. {
  1232. $sendto = $object->client->email;
  1233. $sendtoid = 0;
  1234. }
  1235. else // Id du contact
  1236. {
  1237. $sendto = $object->client->contact_get_property($_POST['receiver'],'email');
  1238. $sendtoid = $_POST['receiver'];
  1239. }
  1240. }
  1241. if (dol_strlen($sendto))
  1242. {
  1243. $langs->load("commercial");
  1244. $from = $_POST['fromname'] . ' <' . $_POST['frommail'] .'>';
  1245. $replyto = $_POST['replytoname']. ' <' . $_POST['replytomail'].'>';
  1246. $message = $_POST['message'];
  1247. $sendtocc = $_POST['sendtocc'];
  1248. $deliveryreceipt = $_POST['deliveryreceipt'];
  1249. if ($action == 'send')
  1250. {
  1251. if (dol_strlen($_POST['subject'])) $subject = $_POST['subject'];
  1252. else $subject = $langs->transnoentities('Bill').' '.$object->ref;
  1253. $actiontypecode='AC_FAC';
  1254. $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n";
  1255. if ($message)
  1256. {
  1257. $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n";
  1258. $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n";
  1259. $actionmsg.=$message;
  1260. }
  1261. //$actionmsg2=$langs->transnoentities('Action'.$actiontypecode);
  1262. }
  1263. if ($action == 'relance')
  1264. {
  1265. if (dol_strlen($_POST['subject'])) $subject = $_POST['subject'];
  1266. else $subject = $langs->transnoentities('Relance facture '.$object->ref);
  1267. $actiontypecode='AC_FAC';
  1268. $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n";
  1269. if ($message) {
  1270. $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n";
  1271. $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n";
  1272. $actionmsg.=$message;
  1273. }
  1274. //$actionmsg2=$langs->transnoentities('Action'.$actiontypecode);
  1275. }
  1276. // Create form object
  1277. include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php');
  1278. $formmail = new FormMail($db);
  1279. $attachedfiles=$formmail->get_attached_files();
  1280. $filepath = $attachedfiles['paths'];
  1281. $filename = $attachedfiles['names'];
  1282. $mimetype = $attachedfiles['mimes'];
  1283. // Send mail
  1284. require_once(DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php');
  1285. $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,'',$deliveryreceipt,-1);
  1286. if ($mailfile->error)
  1287. {
  1288. $mesgs[]='<div class="error">'.$mailfile->error.'</div>';
  1289. }
  1290. else
  1291. {
  1292. $result=$mailfile->sendfile();
  1293. if ($result)
  1294. {
  1295. $error=0;
  1296. // Initialisation donnees
  1297. $object->sendtoid = $sendtoid;
  1298. $object->actiontypecode = $actiontypecode;
  1299. $object->actionmsg = $actionmsg; // Long text
  1300. $object->actionmsg2 = $actionmsg2; // Short text
  1301. $object->fk_element = $object->id;
  1302. $object->elementtype = $object->element;
  1303. // Appel des triggers
  1304. include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php");
  1305. $interface=new Interfaces($db);
  1306. $result=$interface->run_triggers('BILL_SENTBYMAIL',$object,$user,$langs,$conf);
  1307. if ($result < 0) { $error++; $this->errors=$interface->errors; }
  1308. // Fin appel triggers
  1309. if ($error)
  1310. {
  1311. dol_print_error($db);
  1312. }
  1313. else
  1314. {
  1315. // Redirect here
  1316. // This avoid sending mail twice if going out and then back to page
  1317. $mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2));
  1318. setEventMessage($mesg);
  1319. Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id);
  1320. exit;
  1321. }
  1322. }
  1323. else
  1324. {
  1325. $langs->load("other");
  1326. $mesg='<div class="error">';
  1327. if ($mailfile->error)
  1328. {
  1329. $mesg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto);
  1330. $mesg.='<br>'.$mailfile->error;
  1331. }
  1332. else
  1333. {
  1334. $mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS';
  1335. }
  1336. $mesg.='</div>';
  1337. $mesgs[]=$mesg;
  1338. }
  1339. }
  1340. /* }
  1341. else
  1342. {
  1343. $langs->load("other");
  1344. $mesgs[]='<div class="error">'.$langs->trans('ErrorMailRecipientIsEmpty').'</div>';
  1345. dol_syslog('Recipient email is empty');
  1346. }*/
  1347. }
  1348. else
  1349. {
  1350. $langs->load("errors");
  1351. $mesgs[]='<div class="error">'.$langs->trans('ErrorCantReadFile',$file).'</div>';
  1352. dol_syslog('Failed to read file: '.$file);
  1353. }
  1354. }
  1355. else
  1356. {
  1357. $langs->load("other");
  1358. $mesgs[]='<div class="error">'.$langs->trans('ErrorFailedToReadEntity',$langs->trans("Invoice")).'</div>';
  1359. dol_syslog('Impossible de lire les donnees de la facture. Le fichier facture n\'a peut-etre pas ete genere.');
  1360. }
  1361. $action = 'presend';
  1362. }
  1363. /*
  1364. * Generate document
  1365. */
  1366. else if ($action == 'builddoc') // En get ou en post
  1367. {
  1368. $object->fetch($id);
  1369. $object->fetch_thirdparty();
  1370. if (GETPOST('model'))
  1371. {
  1372. $object->setDocModel($user, GETPOST('model'));
  1373. }
  1374. // Define output language
  1375. $outputlangs = $langs;
  1376. $newlang='';
  1377. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id');
  1378. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
  1379. if (! empty($newlang))
  1380. {
  1381. $outputlangs = new Translate("",$conf);
  1382. $outputlangs->setDefaultLang($newlang);
  1383. }
  1384. $result=facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
  1385. if ($result <= 0)
  1386. {
  1387. dol_print_error($db,$result);
  1388. exit;
  1389. }
  1390. else
  1391. {
  1392. Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc'));
  1393. exit;
  1394. }
  1395. }
  1396. // Remove file in doc form
  1397. else if ($action == 'remove_file')
  1398. {
  1399. if ($object->fetch($id))
  1400. {
  1401. require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
  1402. $object->fetch_thirdparty();
  1403. $langs->load("other");
  1404. $upload_dir = $conf->facture->dir_output;
  1405. $file = $upload_dir . '/' . GETPOST('file');
  1406. $ret=dol_delete_file($file,0,0,0,$object);
  1407. if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile')));
  1408. else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors');
  1409. $action='';
  1410. }
  1411. }
  1412. if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB))
  1413. {
  1414. if ($action == 'addcontact' && $user->rights->facture->creer)
  1415. {
  1416. $result = $object->fetch($id);
  1417. if ($result > 0 && $id > 0)
  1418. {
  1419. $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
  1420. $result = $result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]);
  1421. }
  1422. if ($result >= 0)
  1423. {
  1424. Header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
  1425. exit;
  1426. }
  1427. else
  1428. {
  1429. if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS')
  1430. {
  1431. $langs->load("errors");
  1432. $mesgs[] = '<div class="error">'.$langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType").'</div>';
  1433. }
  1434. else
  1435. {
  1436. $mesgs[] = '<div class="error">'.$object->error.'</div>';
  1437. }
  1438. }
  1439. }
  1440. // bascule du statut d'un contact
  1441. else if ($action == 'swapstatut' && $user->rights->facture->creer)
  1442. {
  1443. if ($object->fetch($id))
  1444. {
  1445. $result=$object->swapContactStatus(GETPOST('ligne'));
  1446. }
  1447. else
  1448. {
  1449. dol_print_error($db);
  1450. }
  1451. }
  1452. // Efface un contact
  1453. else if ($action == 'deletecontact' && $user->rights->facture->creer)
  1454. {
  1455. $object->fetch($id);
  1456. $result = $object->delete_contact($lineid);
  1457. if ($result >= 0)
  1458. {
  1459. Header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
  1460. exit;
  1461. }
  1462. else {
  1463. dol_print_error($db);
  1464. }
  1465. }
  1466. }
  1467. /*
  1468. * View
  1469. */
  1470. llxHeader('',$langs->trans('Bill'),'EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes');
  1471. $form = new Form($db);
  1472. $htmlother = new FormOther($db);
  1473. $formfile = new FormFile($db);
  1474. $bankaccountstatic=new Account($db);
  1475. $now=dol_now();
  1476. /*********************************************************************
  1477. *
  1478. * Mode creation
  1479. *
  1480. **********************************************************************/
  1481. if ($action == 'create')
  1482. {
  1483. $facturestatic=new Facture($db);
  1484. print_fiche_titre($langs->trans('NewBill'));
  1485. $soc = new Societe($db);
  1486. if ($socid) $res=$soc->fetch($socid);
  1487. if (GETPOST('origin') && GETPOST('originid'))
  1488. {
  1489. // Parse element/subelement (ex: project_task)
  1490. $element = $subelement = GETPOST('origin');
  1491. if (preg_match('/^([^_]+)_([^_]+)/i',GETPOST('origin'),$regs))
  1492. {
  1493. $element = $regs[1];
  1494. $subelement = $regs[2];
  1495. }
  1496. if ($element == 'project')
  1497. {
  1498. $projectid=GETPOST('originid');
  1499. }
  1500. else
  1501. {
  1502. // For compatibility
  1503. if ($element == 'order' || $element == 'commande') { $element = $subelement = 'commande'; }
  1504. if ($element == 'propal') { $element = 'comm/propal'; $subelement = 'propal'; }
  1505. if ($element == 'contract') { $element = $subelement = 'contrat'; }
  1506. if ($element == 'shipping') { $element = $subelement = 'expedition'; }
  1507. dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
  1508. $classname = ucfirst($subelement);
  1509. $objectsrc = new $classname($db);
  1510. $objectsrc->fetch(GETPOST('originid'));
  1511. if (empty($objectsrc->lines) && method_exists($objectsrc,'fetch_lines')) $objectsrc->fetch_lines();
  1512. $objectsrc->fetch_thirdparty();
  1513. $projectid = (!empty($objectsrc->fk_project)?$objectsrc->fk_project:'');
  1514. $ref_client = (!empty($objectsrc->ref_client)?$objectsrc->ref_client:'');
  1515. $ref_int = (!empty($objectsrc->ref_int)?$objectsrc->ref_int:'');
  1516. $soc = $objectsrc->client;
  1517. $cond_reglement_id = (!empty($objectsrc->cond_reglement_id)?$objectsrc->cond_reglement_id:(!empty($soc->cond_reglement_id)?$soc->cond_reglement_id:1));
  1518. $mode_reglement_id = (!empty($objectsrc->mode_reglement_id)?$objectsrc->mode_reglement_id:(!empty($soc->mode_reglement_id)?$soc->mode_reglement_id:0));
  1519. $remise_percent = (!empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(!empty($soc->remise_percent)?$soc->remise_percent:0));
  1520. $remise_absolue = (!empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(!empty($soc->remise_absolue)?$soc->remise_absolue:0));
  1521. $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0;
  1522. }
  1523. }
  1524. else
  1525. {
  1526. $cond_reglement_id = $soc->cond_reglement_id;
  1527. $mode_reglement_id = $soc->mode_reglement_id;
  1528. $remise_percent = $soc->remise_percent;
  1529. $remise_absolue = 0;
  1530. $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0;
  1531. }
  1532. $absolute_discount=$soc->getAvailableDiscounts();
  1533. if ($conf->use_javascript_ajax)
  1534. {
  1535. print ajax_combobox('fac_replacement');
  1536. print ajax_combobox('fac_avoir');
  1537. }
  1538. print '<form name="add" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
  1539. print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
  1540. print '<input type="hidden" name="action" value="add">';
  1541. print '<input type="hidden" name="socid" value="'.$soc->id.'">' ."\n";
  1542. print '<input name="facnumber" type="hidden" value="provisoire">';
  1543. print '<input name="ref_client" type="hidden" value="'.$ref_client.'">';
  1544. print '<input name="ref_int" type="hidden" value="'.$ref_int.'">';
  1545. print '<input type="hidden" name="origin" value="'.GETPOST('origin').'">';
  1546. print '<input type="hidden" name="originid" value="'.GETPOST('originid').'">';
  1547. print '<table class="border" width="100%">';
  1548. // Ref
  1549. print '<tr><td class="fieldrequired">'.$langs->trans('Ref').'</td><td colspan="2">'.$langs->trans('Draft').'</td></tr>';
  1550. // Factures predefinies
  1551. if (empty($_GET['propalid']) && empty($_GET['commandeid']) && empty($_GET['contratid']) && empty($_GET['originid']))
  1552. {
  1553. $sql = 'SELECT r.rowid, r.titre, r.total_ttc';
  1554. $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_rec as r';
  1555. $sql.= ' WHERE r.fk_soc = '.$soc->id;
  1556. $resql=$db->query($sql);
  1557. if ($resql)
  1558. {
  1559. $num = $db->num_rows($resql);
  1560. $i = 0;
  1561. if ($num > 0)
  1562. {
  1563. print '<tr><td>'.$langs->trans('CreateFromRepeatableInvoice').'</td><td>';
  1564. print '<select class="flat" name="fac_rec">';
  1565. print '<option value="0" selected="selected"></option>';
  1566. while ($i < $num)
  1567. {
  1568. $objp = $db->fetch_object($resql);
  1569. print '<option value="'.$objp->rowid.'"';
  1570. if ($_POST["fac_rec"] == $objp->rowid) print ' selected="selected"';
  1571. print '>'.$objp->titre.' ('.price($objp->total_ttc).' '.$langs->trans("TTC").')</option>';
  1572. $i++;
  1573. }
  1574. print '</select></td></tr>';
  1575. }
  1576. $db->free($resql);
  1577. }
  1578. else
  1579. {
  1580. dol_print_error($db);
  1581. }
  1582. }
  1583. // Tiers
  1584. print '<tr><td class="fieldrequired">'.$langs->trans('Customer').'</td><td colspan="2">';
  1585. print $soc->getNomUrl(1);
  1586. print '<input type="hidden" name="socid" value="'.$soc->id.'">';
  1587. print '</td>';
  1588. print '</tr>'."\n";
  1589. // Type de facture
  1590. $facids=$facturestatic->list_replacable_invoices($soc->id);
  1591. if ($facids < 0)
  1592. {
  1593. dol_print_error($db,$facturestatic);
  1594. exit;
  1595. }
  1596. $options="";
  1597. foreach ($facids as $facparam)
  1598. {
  1599. $options.='<option value="'.$facparam['id'].'"';
  1600. if ($facparam['id'] == $_POST['fac_replacement']) $options.=' selected="selected"';
  1601. $options.='>'.$facparam['ref'];
  1602. $options.=' ('.$facturestatic->LibStatut(0,$facparam['status']).')';
  1603. $options.='</option>';
  1604. }
  1605. $facids=$facturestatic->list_qualified_avoir_invoices($soc->id);
  1606. if ($facids < 0)
  1607. {
  1608. dol_print_error($db,$facturestatic);
  1609. exit;
  1610. }
  1611. $optionsav="";
  1612. foreach ($facids as $key => $value)
  1613. {
  1614. $newinvoice=new Facture($db);
  1615. $newinvoice->fetch($key);
  1616. $optionsav.='<option value="'.$key.'"';
  1617. if ($key == $_POST['fac_avoir']) $optionsav.=' selected="selected"';
  1618. $optionsav.='>';
  1619. $optionsav.=$newinvoice->ref;
  1620. $optionsav.=' ('.$newinvoice->getLibStatut(1,$value).')';
  1621. $optionsav.='</option>';
  1622. }
  1623. print '<tr><td valign="top" class="fieldrequired">'.$langs->trans('Type').'</td><td colspan="2">';
  1624. print '<table class="nobordernopadding">'."\n";
  1625. // Standard invoice
  1626. print '<tr height="18"><td width="16px" valign="middle">';
  1627. print '<input type="radio" name="type" value="0"'.(GETPOST('type')==0?' checked="checked"':'').'>';
  1628. print '</td><td valign="middle">';
  1629. $desc=$form->textwithpicto($langs->trans("InvoiceStandardAsk"),$langs->transnoentities("InvoiceStandardDesc"),1);
  1630. print $desc;
  1631. print '</td></tr>'."\n";
  1632. // Deposit
  1633. print '<tr height="18"><td width="16px" valign="middle">';
  1634. print '<input type="radio" name="type" value="3"'.(GETPOST('type')==3?' checked="checked"':'').'>';
  1635. print '</td><td valign="middle">';
  1636. $desc=$form->textwithpicto($langs->trans("InvoiceDeposit"),$langs->transnoentities("InvoiceDepositDesc"),1);
  1637. print $desc;
  1638. print '</td></tr>'."\n";
  1639. // Proforma
  1640. if ($conf->global->FACTURE_USE_PROFORMAT)
  1641. {
  1642. print '<tr height="18"><td width="16px" valign="middle">';
  1643. print '<input type="radio" name="type" value="4"'.(GETPOST('type')==4?' checked="checked"':'').'>';
  1644. print '</td><td valign="middle">';
  1645. $desc=$form->textwithpicto($langs->trans("InvoiceProForma"),$langs->transnoentities("InvoiceProFormaDesc"),1);
  1646. print $desc;
  1647. print '</td></tr>'."\n";
  1648. }
  1649. // Replacement
  1650. print '<tr height="18"><td valign="middle">';
  1651. print '<input type="radio" name="type" value="1"'.(GETPOST('type')==1?' checked="checked"':'');
  1652. if (! $options) print ' disabled="disabled"';
  1653. print '>';
  1654. print '</td><td valign="middle">';
  1655. $text=$langs->trans("InvoiceReplacementAsk").' ';
  1656. $text.='<select class="flat" name="fac_replacement" id="fac_replacement"';
  1657. if (! $options) $text.=' disabled="disabled"';
  1658. $text.='>';
  1659. if ($options)
  1660. {
  1661. $text.='<option value="-1"></option>';
  1662. $text.=$options;
  1663. }
  1664. else
  1665. {
  1666. $text.='<option value="-1">'.$langs->trans("NoReplacableInvoice").'</option>';
  1667. }
  1668. $text.='</select>';
  1669. $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceReplacementDesc"),1);
  1670. print $desc;
  1671. print '</td></tr>'."\n";
  1672. // Credit note
  1673. print '<tr height="18"><td valign="middle">';
  1674. print '<input type="radio" name="type" value="2"'.(GETPOST('type')==2?' checked=true':'');
  1675. if (! $optionsav) print ' disabled="disabled"';
  1676. print '>';
  1677. print '</td><td valign="middle">';
  1678. $text=$langs->transnoentities("InvoiceAvoirAsk").' ';
  1679. // $text.='<input type="text" value="">';
  1680. $text.='<select class="flat" name="fac_avoir" id="fac_avoir"';
  1681. if (! $optionsav) $text.=' disabled="disabled"';
  1682. $text.='>';
  1683. if ($optionsav)
  1684. {
  1685. $text.='<option value="-1"></option>';
  1686. $text.=$optionsav;
  1687. }
  1688. else
  1689. {
  1690. $text.='<option value="-1">'.$langs->trans("NoInvoiceToCorrect").'</option>';
  1691. }
  1692. $text.='</select>';
  1693. $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceAvoirDesc"),1);
  1694. print $desc;
  1695. print '</td></tr>'."\n";
  1696. print '</table>';
  1697. print '</td></tr>';
  1698. // Discounts for third party
  1699. print '<tr><td>'.$langs->trans('Discounts').'</td><td colspan="2">';
  1700. if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",'<a href="'.DOL_URL_ROOT.'/comm/remise.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?socid='.$soc->id.'&action='.$action.'&origin='.GETPOST('origin').'&originid='.GETPOST('originid')).'">'.$soc->remise_client.'</a>');
  1701. else print $langs->trans("CompanyHasNoRelativeDiscount");
  1702. print ' <a href="'.DOL_URL_ROOT.'/comm/remise.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?socid='.$soc->id.'&action='.$action.'&origin='.GETPOST('origin').'&originid='.GETPOST('originid')).'">('.$langs->trans("EditRelativeDiscount").')</a>';
  1703. print '. ';
  1704. print '<br>';
  1705. if ($absolute_discount) print $langs->trans("CompanyHasAbsoluteDiscount",'<a href="'.DOL_URL_ROOT.'/comm/remx.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?socid='.$soc->id.'&action='.$action.'&origin='.GETPOST('origin').'&originid='.GETPOST('originid')).'">'.price($absolute_discount).'</a>',$langs->trans("Currency".$conf->currency));
  1706. else print $langs->trans("CompanyHasNoAbsoluteDiscount");
  1707. print ' <a href="'.DOL_URL_ROOT.'/comm/remx.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?socid='.$soc->id.'&action='.$action.'&origin='.GETPOST('origin').'&originid='.GETPOST('originid')).'">('.$langs->trans("EditGlobalDiscounts").')</a>';
  1708. print '.';
  1709. print '</td></tr>';
  1710. // Date invoice
  1711. print '<tr><td class="fieldrequired">'.$langs->trans('Date').'</td><td colspan="2">';
  1712. $form->select_date($dateinvoice,'','','','',"add",1,1);
  1713. print '</td></tr>';
  1714. // Payment term
  1715. print '<tr><td nowrap>'.$langs->trans('PaymentConditionsShort').'</td><td colspan="2">';
  1716. $form->select_conditions_paiements(isset($_POST['cond_reglement_id'])?$_POST['cond_reglement_id']:$cond_reglement_id,'cond_reglement_id');
  1717. print '</td></tr>';
  1718. // Payment mode
  1719. print '<tr><td>'.$langs->trans('PaymentMode').'</td><td colspan="2">';
  1720. $form->select_types_paiements(isset($_POST['mode_reglement_id'])?$_POST['mode_reglement_id']:$mode_reglement_id,'mode_reglement_id');
  1721. print '</td></tr>';
  1722. // Project
  1723. if ($conf->projet->enabled)
  1724. {
  1725. $langs->load('projects');
  1726. print '<tr><td>'.$langs->trans('Project').'</td><td colspan="2">';
  1727. select_projects($soc->id, $projectid, 'projectid');
  1728. print '</td></tr>';
  1729. }
  1730. // Other attributes
  1731. $parameters=array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"');
  1732. $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook
  1733. if (empty($reshook) && ! empty($extrafields->attribute_label))
  1734. {
  1735. foreach($extrafields->attribute_label as $key=>$label)
  1736. {
  1737. $value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]);
  1738. print '<tr><td>'.$label.'</td><td colspan="3">';
  1739. print $extrafields->showInputField($key,$value);
  1740. print '</td></tr>'."\n";
  1741. }
  1742. }
  1743. // Modele PDF
  1744. print '<tr><td>'.$langs->trans('Model').'</td>';
  1745. print '<td>';
  1746. include_once(DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php');
  1747. $liste=ModelePDFFactures::liste_modeles($db);
  1748. print $form->selectarray('model',$liste,$conf->global->FACTURE_ADDON_PDF);
  1749. print "</td></tr>";
  1750. // Public note
  1751. print '<tr>';
  1752. print '<td class="border" valign="top">'.$langs->trans('NotePublic').'</td>';
  1753. print '<td valign="top" colspan="2">';
  1754. print '<textarea name="note_public" wrap="soft" cols="70" rows="'.ROWS_3.'">';
  1755. if (is_object($objectsrc)) // Take value from source object
  1756. {
  1757. print $objectsrc->note_public;
  1758. }
  1759. print '</textarea></td></tr>';
  1760. // Private note
  1761. if (! $user->societe_id)
  1762. {
  1763. print '<tr>';
  1764. print '<td class="border" valign="top">'.$langs->trans('NotePrivate').'</td>';
  1765. print '<td valign="top" colspan="2">';
  1766. print '<textarea name="note" wrap="soft" cols="70" rows="'.ROWS_3.'">';
  1767. if (is_object($objectsrc)) // Take value from source object
  1768. {
  1769. print $objectsrc->note;
  1770. }
  1771. print '</textarea></td></tr>';
  1772. }
  1773. if (is_object($objectsrc))
  1774. {
  1775. // TODO for compatibility
  1776. if ($_GET['origin'] == 'contrat')
  1777. {
  1778. // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva
  1779. $objectsrc->remise_absolue=$remise_absolue;
  1780. $objectsrc->remise_percent=$remise_percent;
  1781. $objectsrc->update_price(1,-1,1);
  1782. }
  1783. print "\n<!-- ".$classname." info -->";
  1784. print "\n";
  1785. print '<input type="hidden" name="amount" value="'.$objectsrc->total_ht.'">'."\n";
  1786. print '<input type="hidden" name="total" value="'.$objectsrc->total_ttc.'">'."\n";
  1787. print '<input type="hidden" name="tva" value="'.$objectsrc->total_tva.'">'."\n";
  1788. print '<input type="hidden" name="origin" value="'.$objectsrc->element.'">';
  1789. print '<input type="hidden" name="originid" value="'.$objectsrc->id.'">';
  1790. $newclassname=$classname;
  1791. if ($newclassname=='Propal') $newclassname='CommercialProposal';
  1792. print '<tr><td>'.$langs->trans($newclassname).'</td><td colspan="2">'.$objectsrc->getNomUrl(1).'</td></tr>';
  1793. print '<tr><td>'.$langs->trans('TotalHT').'</td><td colspan="2">'.price($objectsrc->total_ht).'</td></tr>';
  1794. print '<tr><td>'.$langs->trans('TotalVAT').'</td><td colspan="2">'.price($objectsrc->total_tva)."</td></tr>";
  1795. if ($mysoc->pays_code=='ES')
  1796. {
  1797. if ($mysoc->localtax1_assuj=="1") //Localtax1 RE
  1798. {
  1799. print '<tr><td>'.$langs->transcountry("AmountLT1",$mysoc->pays_code).'</td><td colspan="2">'.price($objectsrc->total_localtax1)."</td></tr>";
  1800. }
  1801. if ($mysoc->localtax2_assuj=="1") //Localtax2 IRPF
  1802. {
  1803. print '<tr><td>'.$langs->transcountry("AmountLT2",$mysoc->pays_code).'</td><td colspan="2">'.price($objectsrc->total_localtax2)."</td></tr>";
  1804. }
  1805. }
  1806. print '<tr><td>'.$langs->trans('TotalTTC').'</td><td colspan="2">'.price($objectsrc->total_ttc)."</td></tr>";
  1807. }
  1808. else
  1809. {
  1810. // Show deprecated optional form to add product line here
  1811. if ($conf->global->PRODUCT_SHOW_WHEN_CREATE)
  1812. {
  1813. print '<tr><td colspan="3">';
  1814. // Zone de choix des produits predefinis a la creation
  1815. print '<table class="noborder" width="100%">';
  1816. print '<tr>';
  1817. print '<td>'.$langs->trans('ProductsAndServices').'</td>';
  1818. print '<td>'.$langs->trans('Qty').'</td>';
  1819. print '<td>'.$langs->trans('ReductionShort').'</td>';
  1820. print '<td> &nbsp; &nbsp; </td>';
  1821. if ($conf->service->enabled)
  1822. {
  1823. print '<td>'.$langs->trans('ServiceLimitedDuration').'</td>';
  1824. }
  1825. print '</tr>';
  1826. for ($i = 1 ; $i <= $NBLINES ; $i++)
  1827. {
  1828. print '<tr>';
  1829. print '<td>';
  1830. // multiprix
  1831. if($conf->global->PRODUIT_MULTIPRICES)
  1832. $form->select_produits('','idprod'.$i,'',$conf->product->limit_size,$soc->price_level);
  1833. else
  1834. $form->select_produits('','idprod'.$i,'',$conf->product->limit_size);
  1835. print '</td>';
  1836. print '<td><input type="text" size="2" name="qty'.$i.'" value="1"></td>';
  1837. print '<td nowrap="nowrap"><input type="text" size="1" name="remise_percent'.$i.'" value="'.$soc->remise_client.'">%</td>';
  1838. print '<td>&nbsp;</td>';
  1839. // Si le module service est actif, on propose des dates de debut et fin a la ligne
  1840. if ($conf->service->enabled)
  1841. {
  1842. print '<td nowrap="nowrap">';
  1843. print '<table class="nobordernopadding"><tr class="nocellnopadd">';
  1844. print '<td class="nobordernopadding" nowrap="nowrap">';
  1845. print $langs->trans('From').' ';
  1846. print '</td><td class="nobordernopadding" nowrap="nowrap">';
  1847. print $form->select_date('','date_start'.$i,$usehm,$usehm,1,"add");
  1848. print '</td></tr>';
  1849. print '<td class="nobordernopadding" nowrap="nowrap">';
  1850. print $langs->trans('to').' ';
  1851. print '</td><td class="nobordernopadding" nowrap="nowrap">';
  1852. print $form->select_date('','date_end'.$i,$usehm,$usehm,1,"add");
  1853. print '</td></tr></table>';
  1854. print '</td>';
  1855. }
  1856. print "</tr>\n";
  1857. }
  1858. print '</table>';
  1859. print '</td></tr>';
  1860. }
  1861. }
  1862. print "</table>\n";
  1863. // Button "Create Draft"
  1864. print '<br><center><input type="submit" class="button" name="bouton" value="'.$langs->trans('CreateDraft').'"></center>';
  1865. print "</form>\n";
  1866. // Show origin lines
  1867. if (is_object($objectsrc))
  1868. {
  1869. print '<br>';
  1870. $title=$langs->trans('ProductsAndServices');
  1871. print_titre($title);
  1872. print '<table class="noborder" width="100%">';
  1873. $objectsrc->printOriginLinesList($hookmanager);
  1874. print '</table>';
  1875. }
  1876. }
  1877. else if ($id > 0 || ! empty($ref))
  1878. {
  1879. /*
  1880. * Show object in view mode
  1881. */
  1882. $result=$object->fetch($id,$ref);
  1883. if ($result > 0)
  1884. {
  1885. if ($user->societe_id>0 && $user->societe_id!=$object->socid) accessforbidden('',0);
  1886. $result=$object->fetch_thirdparty();
  1887. $soc = new Societe($db);
  1888. $soc->fetch($object->socid);
  1889. $totalpaye = $object->getSommePaiement();
  1890. $totalcreditnotes = $object->getSumCreditNotesUsed();
  1891. $totaldeposits = $object->getSumDepositsUsed();
  1892. //print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits;
  1893. // We can also use bcadd to avoid pb with floating points
  1894. // For example print 239.2 - 229.3 - 9.9; does not return 0.
  1895. //$resteapayer=bcadd($object->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT);
  1896. //$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT);
  1897. $resteapayer = price2num($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits,'MT');
  1898. if ($object->paye) $resteapayer=0;
  1899. $resteapayeraffiche=$resteapayer;
  1900. if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
  1901. {
  1902. $filterabsolutediscount="fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
  1903. $filtercreditnote="fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
  1904. }
  1905. else
  1906. {
  1907. $filterabsolutediscount="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')";
  1908. $filtercreditnote="fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'";
  1909. }
  1910. $absolute_discount=$soc->getAvailableDiscounts('',$filterabsolutediscount);
  1911. $absolute_creditnote=$soc->getAvailableDiscounts('',$filtercreditnote);
  1912. $absolute_discount=price2num($absolute_discount,'MT');
  1913. $absolute_creditnote=price2num($absolute_creditnote,'MT');
  1914. $author = new User($db);
  1915. if ($object->user_author)
  1916. {
  1917. $author->fetch($object->user_author);
  1918. }
  1919. $objectidnext=$object->getIdReplacingInvoice();
  1920. $head = facture_prepare_head($object);
  1921. dol_fiche_head($head, 'compta', $langs->trans('InvoiceCustomer'), 0, 'bill');
  1922. $formconfirm='';
  1923. // Confirmation de la conversion de l'avoir en reduc
  1924. if ($action == 'converttoreduc')
  1925. {
  1926. $text=$langs->trans('ConfirmConvertToReduc');
  1927. $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('ConvertToReduc'),$text,'confirm_converttoreduc','',"yes",2);
  1928. }
  1929. // Confirmation to delete invoice
  1930. if ($action == 'delete')
  1931. {
  1932. $text=$langs->trans('ConfirmDeleteBill');
  1933. $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete','',0,1);
  1934. }
  1935. // Confirmation de la validation
  1936. if ($action == 'valid')
  1937. {
  1938. // on verifie si l'objet est en numerotation provisoire
  1939. $objectref = substr($object->ref, 1, 4);
  1940. if ($objectref == 'PROV')
  1941. {
  1942. $savdate=$object->date;
  1943. if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION))
  1944. {
  1945. $object->date=dol_now();
  1946. $object->date_lim_reglement=$object->calculate_date_lim_reglement();
  1947. }
  1948. $numref = $object->getNextNumRef($soc);
  1949. //$object->date=$savdate;
  1950. }
  1951. else
  1952. {
  1953. $numref = $object->ref;
  1954. }
  1955. $text=$langs->trans('ConfirmValidateBill',$numref);
  1956. if ($conf->notification->enabled)
  1957. {
  1958. require_once(DOL_DOCUMENT_ROOT ."/core/class/notify.class.php");
  1959. $notify=new Notify($db);
  1960. $text.='<br>';
  1961. $text.=$notify->confirmMessage('NOTIFY_VAL_FAC',$object->socid);
  1962. }
  1963. $formquestion=array();
  1964. if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1))
  1965. {
  1966. $langs->load("stocks");
  1967. require_once(DOL_DOCUMENT_ROOT."/product/class/html.formproduct.class.php");
  1968. $formproduct=new FormProduct($db);
  1969. $label=$object->type==2?$langs->trans("SelectWarehouseForStockIncrease"):$langs->trans("SelectWarehouseForStockDecrease");
  1970. $formquestion=array(
  1971. //'text' => $langs->trans("ConfirmClone"),
  1972. //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
  1973. //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
  1974. array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1)));
  1975. }
  1976. if ($object->type != 2 && $object->total_ttc < 0) // Can happen only if $conf->global->FACTURE_ENABLE_NEGATIVE is on
  1977. {
  1978. $text.='<br>'.img_warning().' '.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive");
  1979. }
  1980. $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ValidateBill'),$text,'confirm_valid',$formquestion,(($object->type != 2 && $object->total_ttc < 0)?"no":"yes"),($conf->notification->enabled?0:2));
  1981. }
  1982. // Confirm back to draft status
  1983. if ($action == 'modif')
  1984. {
  1985. $text=$langs->trans('ConfirmUnvalidateBill',$object->ref);
  1986. $formquestion=array();
  1987. if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1))
  1988. {
  1989. $langs->load("stocks");
  1990. require_once(DOL_DOCUMENT_ROOT."/product/class/html.formproduct.class.php");
  1991. $formproduct=new FormProduct($db);
  1992. $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease");
  1993. $formquestion=array(
  1994. //'text' => $langs->trans("ConfirmClone"),
  1995. //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
  1996. //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
  1997. array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1)));
  1998. }
  1999. $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('UnvalidateBill'),$text,'confirm_modif',$formquestion,"yes",1);
  2000. }
  2001. // Confirmation du classement paye
  2002. if ($action == 'paid' && $resteapayer <= 0)
  2003. {
  2004. $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidBill',$object->ref),'confirm_paid','',"yes",1);
  2005. }
  2006. if ($action == 'paid' && $resteapayer > 0)
  2007. {
  2008. // Code
  2009. $i=0;
  2010. $close[$i]['code']='discount_vat';$i++;
  2011. $close[$i]['code']='badcustomer';$i++;
  2012. // Help
  2013. $i=0;
  2014. $close[$i]['label']=$langs->trans("HelpEscompte").'<br><br>'.$langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");$i++;
  2015. $close[$i]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");$i++;
  2016. // Texte
  2017. $i=0;
  2018. $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscountVat",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++;
  2019. $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++;
  2020. // arrayreasons[code]=reason
  2021. foreach($close as $key => $val)
  2022. {
  2023. $arrayreasons[$close[$key]['code']]=$close[$key]['reason'];
  2024. }
  2025. // Cree un tableau formulaire
  2026. $formquestion=array(
  2027. 'text' => $langs->trans("ConfirmClassifyPaidPartiallyQuestion"),
  2028. array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons),
  2029. array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100')
  2030. );
  2031. // Paiement incomplet. On demande si motif = escompte ou autre
  2032. $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidPartially',$object->ref),'confirm_paid_partially',$formquestion,"yes");
  2033. }
  2034. // Confirmation du classement abandonne
  2035. if ($action == 'canceled')
  2036. {
  2037. // S'il y a une facture de remplacement pas encore validee (etat brouillon),
  2038. // on ne permet pas de classer abandonner la facture.
  2039. if ($objectidnext)
  2040. {
  2041. $facturereplacement=new Facture($db);
  2042. $facturereplacement->fetch($objectidnext);
  2043. $statusreplacement=$facturereplacement->statut;
  2044. }
  2045. if ($objectidnext && $statusreplacement == 0)
  2046. {
  2047. print '<div class="error">'.$langs->trans("ErrorCantCancelIfReplacementInvoiceNotValidated").'</div>';
  2048. }
  2049. else
  2050. {
  2051. // Code
  2052. $close[1]['code']='badcustomer';
  2053. $close[2]['code']='abandon';
  2054. // Help
  2055. $close[1]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");
  2056. $close[2]['label']=$langs->trans("ConfirmClassifyAbandonReasonOtherDesc");
  2057. // Texte
  2058. $close[1]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$object->ref),$close[1]['label'],1);
  2059. $close[2]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"),$close[2]['label'],1);
  2060. // arrayreasons
  2061. $arrayreasons[$close[1]['code']]=$close[1]['reason'];
  2062. $arrayreasons[$close[2]['code']]=$close[2]['reason'];
  2063. // Cree un tableau formulaire
  2064. $formquestion=array(
  2065. 'text' => $langs->trans("ConfirmCancelBillQuestion"),
  2066. array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons),
  2067. array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100')
  2068. );
  2069. $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('CancelBill'),$langs->trans('ConfirmCancelBill',$object->ref),'confirm_canceled',$formquestion,"yes");
  2070. }
  2071. }
  2072. // Confirmation de la suppression d'une ligne produit
  2073. if ($action == 'ask_deleteline')
  2074. {
  2075. $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1);
  2076. }
  2077. // Clone confirmation
  2078. if ($action == 'clone')
  2079. {
  2080. // Create an array for form
  2081. $formquestion=array(
  2082. //'text' => $langs->trans("ConfirmClone"),
  2083. //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1)
  2084. );
  2085. // Paiement incomplet. On demande si motif = escompte ou autre
  2086. $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('CloneInvoice'),$langs->trans('ConfirmCloneInvoice',$object->ref),'confirm_clone',$formquestion,'yes',1);
  2087. }
  2088. if (! $formconfirm)
  2089. {
  2090. $parameters=array('lineid'=>$lineid);
  2091. $formconfirm=$hookmanager->executeHooks('formConfirm',$parameters,$object,$action); // Note that $action and $object may have been modified by hook
  2092. }
  2093. // Print form confirm
  2094. print $formconfirm;
  2095. // Invoice content
  2096. print '<table class="border" width="100%">';
  2097. $linkback = '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php'.(! empty($socid)?'?socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>';
  2098. // Ref
  2099. print '<tr><td width="20%">'.$langs->trans('Ref').'</td>';
  2100. print '<td colspan="5">';
  2101. $morehtmlref='';
  2102. $discount=new DiscountAbsolute($db);
  2103. $result=$discount->fetch(0,$object->id);
  2104. if ($result > 0)
  2105. {
  2106. $morehtmlref=' ('.$langs->trans("CreditNoteConvertedIntoDiscount",$discount->getNomUrl(1,'discount')).')';
  2107. }
  2108. if ($result < 0)
  2109. {
  2110. dol_print_error('',$discount->error);
  2111. }
  2112. print $form->showrefnav($object, 'ref', $linkback, 1, 'facnumber', 'ref', $morehtmlref);
  2113. print '</td></tr>';
  2114. // Ref customer
  2115. print '<tr><td width="20%">';
  2116. print '<table class="nobordernopadding" width="100%"><tr><td>';
  2117. print $langs->trans('RefCustomer');
  2118. print '</td>';
  2119. if ($action != 'refclient' && $object->brouillon) print '<td align="right"><a href="'.$_SERVER['PHP_SELF'].'?action=refclient&amp;id='.$object->id.'">'.img_edit($langs->trans('Modify')).'</a></td>';
  2120. print '</tr></table>';
  2121. print '</td>';
  2122. print '<td colspan="5">';
  2123. if ($user->rights->facture->creer && $action == 'refclient')
  2124. {
  2125. print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
  2126. print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
  2127. print '<input type="hidden" name="action" value="set_ref_client">';
  2128. print '<input type="text" class="flat" size="20" name="ref_client" value="'.$object->ref_client.'">';
  2129. print ' <input type="submit" class="button" value="'.$langs->trans('Modify').'">';
  2130. print '</form>';
  2131. }
  2132. else
  2133. {
  2134. print $object->ref_client;
  2135. }
  2136. print '</td></tr>';
  2137. // Third party
  2138. print '<tr><td>';
  2139. print '<table class="nobordernopadding" width="100%">';
  2140. print '<tr><td>'.$langs->trans('Company').'</td>';
  2141. print '</td><td colspan="5">';
  2142. if (! empty($conf->global->FACTURE_CHANGE_THIRDPARTY) && $action != 'editthirdparty' && $object->brouillon && $user->rights->facture->creer)
  2143. print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editthirdparty&amp;facid='.$object->id.'">'.img_edit($langs->trans('SetLinkToThirdParty'),1).'</a></td>';
  2144. print '</tr></table>';
  2145. print '</td><td colspan="5">';
  2146. if ($action == 'editthirdparty')
  2147. {
  2148. $form->form_thirdparty($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,'socid');
  2149. }
  2150. else
  2151. {
  2152. print ' &nbsp;'.$soc->getNomUrl(1,'compta');
  2153. print ' &nbsp; (<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?socid='.$object->socid.'">'.$langs->trans('OtherBills').'</a>)';
  2154. }
  2155. print '</tr>';
  2156. // Type
  2157. print '<tr><td>'.$langs->trans('Type').'</td><td colspan="5">';
  2158. print $object->getLibType();
  2159. if ($object->type == 1)
  2160. {
  2161. $facreplaced=new Facture($db);
  2162. $facreplaced->fetch($object->fk_facture_source);
  2163. print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')';
  2164. }
  2165. if ($object->type == 2)
  2166. {
  2167. $facusing=new Facture($db);
  2168. $facusing->fetch($object->fk_facture_source);
  2169. print ' ('.$langs->transnoentities("CorrectInvoice",$facusing->getNomUrl(1)).')';
  2170. }
  2171. $facidavoir=$object->getListIdAvoirFromInvoice();
  2172. if (count($facidavoir) > 0)
  2173. {
  2174. print ' ('.$langs->transnoentities("InvoiceHasAvoir");
  2175. $i=0;
  2176. foreach($facidavoir as $id)
  2177. {
  2178. if ($i==0) print ' ';
  2179. else print ',';
  2180. $facavoir=new Facture($db);
  2181. $facavoir->fetch($id);
  2182. print $facavoir->getNomUrl(1);
  2183. }
  2184. print ')';
  2185. }
  2186. if ($objectidnext > 0)
  2187. {
  2188. $facthatreplace=new Facture($db);
  2189. $facthatreplace->fetch($objectidnext);
  2190. print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')';
  2191. }
  2192. print '</td></tr>';
  2193. // Relative and absolute discounts
  2194. $addrelativediscount='<a href="'.DOL_URL_ROOT.'/comm/remise.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"]).'?facid='.$object->id.'">'.$langs->trans("EditRelativeDiscounts").'</a>';
  2195. $addabsolutediscount='<a href="'.DOL_URL_ROOT.'/comm/remx.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"]).'?facid='.$object->id.'">'.$langs->trans("EditGlobalDiscounts").'</a>';
  2196. $addcreditnote='<a href="'.DOL_URL_ROOT.'/compta/facture.php?action=create&socid='.$soc->id.'&type=2&backtopage='.urlencode($_SERVER["PHP_SELF"]).'?facid='.$object->id.'">'.$langs->trans("AddCreditNote").'</a>';
  2197. print '<tr><td>'.$langs->trans('Discounts');
  2198. print '</td><td colspan="5">';
  2199. if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client);
  2200. else print $langs->trans("CompanyHasNoRelativeDiscount");
  2201. //print ' ('.$addrelativediscount.')';
  2202. if ($absolute_discount > 0)
  2203. {
  2204. print '. ';
  2205. if ($object->statut > 0 || $object->type == 2 || $object->type == 3)
  2206. {
  2207. if ($object->statut == 0)
  2208. {
  2209. print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency));
  2210. print '. ';
  2211. }
  2212. else
  2213. {
  2214. if ($object->statut < 1 || $object->type == 2 || $object->type == 3)
  2215. {
  2216. $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency));
  2217. print '<br>'.$text.'.<br>';
  2218. }
  2219. else
  2220. {
  2221. $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency));
  2222. $text2=$langs->trans("AbsoluteDiscountUse");
  2223. print $form->textwithpicto($text,$text2);
  2224. }
  2225. }
  2226. }
  2227. else
  2228. {
  2229. // Remise dispo de type remise fixe (not credit note)
  2230. print '<br>';
  2231. $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, GETPOST('discountid'), 'remise_id', $soc->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' ('.$addabsolutediscount.')');
  2232. }
  2233. }
  2234. else
  2235. {
  2236. if ($absolute_creditnote > 0) // If not, link will be added later
  2237. {
  2238. if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')<br>';
  2239. else print '. ';
  2240. }
  2241. else print '. ';
  2242. }
  2243. if ($absolute_creditnote > 0)
  2244. {
  2245. // If validated, we show link "add credit note to payment"
  2246. if ($object->statut != 1 || $object->type == 2 || $object->type == 3)
  2247. {
  2248. if ($object->statut == 0 && $object->type != 3)
  2249. {
  2250. $text=$langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency));
  2251. print $form->textwithpicto($text,$langs->trans("CreditNoteDepositUse"));
  2252. }
  2253. else
  2254. {
  2255. print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'.';
  2256. }
  2257. }
  2258. else
  2259. {
  2260. // Remise dispo de type avoir
  2261. if (! $absolute_discount) print '<br>';
  2262. //$form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, $resteapayer);
  2263. $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, 0); // We must allow credit not even if amount is higher
  2264. }
  2265. }
  2266. if (! $absolute_discount && ! $absolute_creditnote)
  2267. {
  2268. print $langs->trans("CompanyHasNoAbsoluteDiscount");
  2269. if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')<br>';
  2270. else print '. ';
  2271. }
  2272. /*if ($object->statut == 0 && $object->type != 2 && $object->type != 3)
  2273. {
  2274. if (! $absolute_discount && ! $absolute_creditnote) print '<br>';
  2275. //print ' &nbsp; - &nbsp; ';
  2276. print $addabsolutediscount;
  2277. //print ' &nbsp; - &nbsp; '.$addcreditnote; // We disbale link to credit note
  2278. }*/
  2279. print '</td></tr>';
  2280. // Date invoice
  2281. print '<tr><td>';
  2282. print '<table class="nobordernopadding" width="100%"><tr><td>';
  2283. print $langs->trans('Date');
  2284. print '</td>';
  2285. if ($object->type != 2 && $action != 'editinvoicedate' && $object->brouillon && $user->rights->facture->creer) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editinvoicedate&amp;facid='.$object->id.'">'.img_edit($langs->trans('SetDate'),1).'</a></td>';
  2286. print '</tr></table>';
  2287. print '</td><td colspan="3">';
  2288. if ($object->type != 2)
  2289. {
  2290. if ($action == 'editinvoicedate')
  2291. {
  2292. $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date,'invoicedate');
  2293. }
  2294. else
  2295. {
  2296. print dol_print_date($object->date,'daytext');
  2297. }
  2298. }
  2299. else
  2300. {
  2301. print dol_print_date($object->date,'daytext');
  2302. }
  2303. print '</td>';
  2304. /*
  2305. * List of payments
  2306. */
  2307. $nbrows=8; $nbcols=2;
  2308. if ($conf->projet->enabled) $nbrows++;
  2309. if ($conf->banque->enabled) $nbcols++;
  2310. //Local taxes
  2311. if ($mysoc->pays_code=='ES')
  2312. {
  2313. if($mysoc->localtax1_assuj=="1") $nbrows++;
  2314. if($mysoc->localtax2_assuj=="1") $nbrows++;
  2315. }
  2316. print '<td rowspan="'.$nbrows.'" colspan="2" valign="top">';
  2317. print '<table class="nobordernopadding" width="100%">';
  2318. // List of payments already done
  2319. print '<tr class="liste_titre">';
  2320. print '<td>'.($object->type == 2 ? $langs->trans("PaymentsBack") : $langs->trans('Payments')).'</td>';
  2321. print '<td>'.$langs->trans('Type').'</td>';
  2322. if ($conf->banque->enabled) print '<td align="right">'.$langs->trans('BankAccount').'</td>';
  2323. print '<td align="right">'.$langs->trans('Amount').'</td>';
  2324. print '<td width="18">&nbsp;</td>';
  2325. print '</tr>';
  2326. $var=true;
  2327. // Payments already done (from payment on this invoice)
  2328. $sql = 'SELECT p.datep as dp, p.num_paiement, p.rowid, p.fk_bank,';
  2329. $sql.= ' c.code as payment_code, c.libelle as payment_label,';
  2330. $sql.= ' pf.amount,';
  2331. $sql.= ' ba.rowid as baid, ba.ref, ba.label';
  2332. $sql.= ' FROM '.MAIN_DB_PREFIX.'c_paiement as c, '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'paiement as p';
  2333. $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid';
  2334. $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid';
  2335. $sql.= ' WHERE pf.fk_facture = '.$object->id.' AND p.fk_paiement = c.id AND pf.fk_paiement = p.rowid';
  2336. $sql.= ' ORDER BY p.datep, p.tms';
  2337. $result = $db->query($sql);
  2338. if ($result)
  2339. {
  2340. $num = $db->num_rows($result);
  2341. $i = 0;
  2342. if ($object->type != 2)
  2343. {
  2344. if ($num > 0)
  2345. {
  2346. while ($i < $num)
  2347. {
  2348. $objp = $db->fetch_object($result);
  2349. $var=!$var;
  2350. print '<tr '.$bc[$var].'><td>';
  2351. print '<a href="'.DOL_URL_ROOT.'/compta/paiement/fiche.php?id='.$objp->rowid.'">'.img_object($langs->trans('ShowPayment'),'payment').' ';
  2352. print dol_print_date($db->jdate($objp->dp),'day').'</a></td>';
  2353. $label=($langs->trans("PaymentType".$objp->payment_code)!=("PaymentType".$objp->payment_code))?$langs->trans("PaymentType".$objp->payment_code):$objp->payment_label;
  2354. print '<td>'.$label.' '.$objp->num_paiement.'</td>';
  2355. if ($conf->banque->enabled)
  2356. {
  2357. $bankaccountstatic->id=$objp->baid;
  2358. $bankaccountstatic->ref=$objp->ref;
  2359. $bankaccountstatic->label=$objp->ref;
  2360. print '<td align="right">';
  2361. if ($bankaccountstatic->id) print $bankaccountstatic->getNomUrl(1,'transactions');
  2362. print '</td>';
  2363. }
  2364. print '<td align="right">'.price($objp->amount).'</td>';
  2365. print '<td>&nbsp;</td>';
  2366. print '</tr>';
  2367. $i++;
  2368. }
  2369. }
  2370. else
  2371. {
  2372. print '<tr '.$bc[$var].'><td colspan="'.$nbcols.'">'.$langs->trans("None").'</td><td></td><td></td></tr>';
  2373. }
  2374. }
  2375. $db->free($result);
  2376. }
  2377. else
  2378. {
  2379. dol_print_error($db);
  2380. }
  2381. if ($object->type != 2)
  2382. {
  2383. // Total already paid
  2384. print '<tr><td colspan="'.$nbcols.'" align="right">';
  2385. if ($object->type != 3) print $langs->trans('AlreadyPaidNoCreditNotesNoDeposits');
  2386. else print $langs->trans('AlreadyPaid');
  2387. print ' :</td><td align="right">'.price($totalpaye).'</td><td>&nbsp;</td></tr>';
  2388. $resteapayeraffiche=$resteapayer;
  2389. // Loop on each credit note or deposit amount applied
  2390. $creditnoteamount=0;
  2391. $depositamount=0;
  2392. $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
  2393. $sql.= " re.description, re.fk_facture_source";
  2394. $sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re";
  2395. $sql.= " WHERE fk_facture = ".$object->id;
  2396. $resql=$db->query($sql);
  2397. if ($resql)
  2398. {
  2399. $num = $db->num_rows($resql);
  2400. $i = 0;
  2401. $invoice=new Facture($db);
  2402. while ($i < $num)
  2403. {
  2404. $obj = $db->fetch_object($resql);
  2405. $invoice->fetch($obj->fk_facture_source);
  2406. print '<tr><td colspan="'.$nbcols.'" align="right">';
  2407. if ($invoice->type == 2) print $langs->trans("CreditNote").' ';
  2408. if ($invoice->type == 3) print $langs->trans("Deposit").' ';
  2409. print $invoice->getNomUrl(0);
  2410. print ' :</td>';
  2411. print '<td align="right">'.price($obj->amount_ttc).'</td>';
  2412. print '<td align="right">';
  2413. print '<a href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=unlinkdiscount&discountid='.$obj->rowid.'">'.img_delete().'</a>';
  2414. print '</td></tr>';
  2415. $i++;
  2416. if ($invoice->type == 2) $creditnoteamount += $obj->amount_ttc;
  2417. if ($invoice->type == 3) $depositamount += $obj->amount_ttc;
  2418. }
  2419. }
  2420. else
  2421. {
  2422. dol_print_error($db);
  2423. }
  2424. // Paye partiellement 'escompte'
  2425. if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'discount_vat')
  2426. {
  2427. print '<tr><td colspan="'.$nbcols.'" align="right" nowrap="1">';
  2428. print $form->textwithpicto($langs->trans("Escompte").':',$langs->trans("HelpEscompte"),-1);
  2429. print '</td><td align="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).'</td><td>&nbsp;</td></tr>';
  2430. $resteapayeraffiche=0;
  2431. }
  2432. // Paye partiellement ou Abandon 'badcustomer'
  2433. if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'badcustomer')
  2434. {
  2435. print '<tr><td colspan="'.$nbcols.'" align="right" nowrap="1">';
  2436. print $form->textwithpicto($langs->trans("Abandoned").':',$langs->trans("HelpAbandonBadCustomer"),-1);
  2437. print '</td><td align="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).'</td><td>&nbsp;</td></tr>';
  2438. //$resteapayeraffiche=0;
  2439. }
  2440. // Paye partiellement ou Abandon 'product_returned'
  2441. if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'product_returned')
  2442. {
  2443. print '<tr><td colspan="'.$nbcols.'" align="right" nowrap="1">';
  2444. print $form->textwithpicto($langs->trans("ProductReturned").':',$langs->trans("HelpAbandonProductReturned"),-1);
  2445. print '</td><td align="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).'</td><td>&nbsp;</td></tr>';
  2446. $resteapayeraffiche=0;
  2447. }
  2448. // Paye partiellement ou Abandon 'abandon'
  2449. if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'abandon')
  2450. {
  2451. print '<tr><td colspan="'.$nbcols.'" align="right" nowrap="1">';
  2452. $text=$langs->trans("HelpAbandonOther");
  2453. if ($object->close_note) $text.='<br><br><b>'.$langs->trans("Reason").'</b>:'.$object->close_note;
  2454. print $form->textwithpicto($langs->trans("Abandoned").':',$text,-1);
  2455. print '</td><td align="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).'</td><td>&nbsp;</td></tr>';
  2456. $resteapayeraffiche=0;
  2457. }
  2458. // Billed
  2459. print '<tr><td colspan="'.$nbcols.'" align="right">'.$langs->trans("Billed").' :</td><td align="right" style="border: 1px solid;">'.price($object->total_ttc).'</td><td>&nbsp;</td></tr>';
  2460. // Remainder to pay
  2461. print '<tr><td colspan="'.$nbcols.'" align="right">';
  2462. if ($resteapayeraffiche >= 0) print $langs->trans('RemainderToPay');
  2463. else print $langs->trans('ExcessReceived');
  2464. print ' :</td>';
  2465. print '<td align="right" style="border: 1px solid;" bgcolor="#f0f0f0"><b>'.price($resteapayeraffiche).'</b></td>';
  2466. print '<td nowrap="nowrap">&nbsp;</td></tr>';
  2467. }
  2468. else
  2469. {
  2470. // Sold credit note
  2471. print '<tr><td colspan="'.$nbcols.'" align="right">'.$langs->trans('TotalTTC').' :</td>';
  2472. print '<td align="right" style="border: 1px solid;" bgcolor="#f0f0f0"><b>'.price(abs($object->total_ttc)).'</b></td><td>&nbsp;</td></tr>';
  2473. }
  2474. print '</table>';
  2475. // Margin Infos
  2476. if (! empty($conf->margin->enabled)) {
  2477. print '<br>';
  2478. $object->displayMarginInfos($object->statut > 0);
  2479. }
  2480. print '</td></tr>';
  2481. // Date payment term
  2482. print '<tr><td>';
  2483. print '<table class="nobordernopadding" width="100%"><tr><td>';
  2484. print $langs->trans('DateMaxPayment');
  2485. print '</td>';
  2486. if ($object->type != 2 && $action != 'editpaymentterm' && $object->brouillon && $user->rights->facture->creer) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editpaymentterm&amp;facid='.$object->id.'">'.img_edit($langs->trans('SetDate'),1).'</a></td>';
  2487. print '</tr></table>';
  2488. print '</td><td colspan="3">';
  2489. if ($object->type != 2)
  2490. {
  2491. if ($action == 'editpaymentterm')
  2492. {
  2493. $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date_lim_reglement,'paymentterm');
  2494. }
  2495. else
  2496. {
  2497. print dol_print_date($object->date_lim_reglement,'daytext');
  2498. if ($object->date_lim_reglement < ($now - $conf->facture->client->warning_delay) && ! $object->paye && $object->statut == 1 && ! $object->am) print img_warning($langs->trans('Late'));
  2499. }
  2500. }
  2501. else
  2502. {
  2503. print '&nbsp;';
  2504. }
  2505. print '</td></tr>';
  2506. // Conditions de reglement
  2507. print '<tr><td>';
  2508. print '<table class="nobordernopadding" width="100%"><tr><td>';
  2509. print $langs->trans('PaymentConditionsShort');
  2510. print '</td>';
  2511. if ($object->type != 2 && $action != 'editconditions' && $object->brouillon && $user->rights->facture->creer) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editconditions&amp;facid='.$object->id.'">'.img_edit($langs->trans('SetConditions'),1).'</a></td>';
  2512. print '</tr></table>';
  2513. print '</td><td colspan="3">';
  2514. if ($object->type != 2)
  2515. {
  2516. if ($action == 'editconditions')
  2517. {
  2518. $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'cond_reglement_id');
  2519. }
  2520. else
  2521. {
  2522. $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'none');
  2523. }
  2524. }
  2525. else
  2526. {
  2527. print '&nbsp;';
  2528. }
  2529. print '</td></tr>';
  2530. // Mode de reglement
  2531. print '<tr><td>';
  2532. print '<table class="nobordernopadding" width="100%"><tr><td>';
  2533. print $langs->trans('PaymentMode');
  2534. print '</td>';
  2535. if ($action != 'editmode' && $object->brouillon && $user->rights->facture->creer) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editmode&amp;facid='.$object->id.'">'.img_edit($langs->trans('SetMode'),1).'</a></td>';
  2536. print '</tr></table>';
  2537. print '</td><td colspan="3">';
  2538. if ($action == 'editmode')
  2539. {
  2540. $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'mode_reglement_id');
  2541. }
  2542. else
  2543. {
  2544. $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'none');
  2545. }
  2546. print '</td></tr>';
  2547. // Amount
  2548. print '<tr><td>'.$langs->trans('AmountHT').'</td>';
  2549. print '<td align="right" colspan="2" nowrap>'.price($object->total_ht).'</td>';
  2550. print '<td>'.$langs->trans('Currency'.$conf->currency).'</td></tr>';
  2551. print '<tr><td>'.$langs->trans('AmountVAT').'</td><td align="right" colspan="2" nowrap>'.price($object->total_tva).'</td>';
  2552. print '<td>'.$langs->trans('Currency'.$conf->currency).'</td>';
  2553. print '</tr>';
  2554. // Amount Local Taxes
  2555. if ($mysoc->pays_code=='ES')
  2556. {
  2557. if ($mysoc->localtax1_assuj=="1") //Localtax1 RE
  2558. {
  2559. print '<tr><td>'.$langs->transcountry("AmountLT1",$mysoc->pays_code).'</td>';
  2560. print '<td align="right" colspan="2" nowrap>'.price($object->total_localtax1).'</td>';
  2561. print '<td>'.$langs->trans("Currency".$conf->currency).'</td></tr>';
  2562. }
  2563. if ($mysoc->localtax2_assuj=="1") //Localtax2 IRPF
  2564. {
  2565. print '<tr><td>'.$langs->transcountry("AmountLT2",$mysoc->pays_code).'</td>';
  2566. print '<td align="right" colspan="2" nowrap>'.price($object->total_localtax2).'</td>';
  2567. print '<td>'.$langs->trans("Currency".$conf->currency).'</td></tr>';
  2568. }
  2569. }
  2570. print '<tr><td>'.$langs->trans('AmountTTC').'</td><td align="right" colspan="2" nowrap>'.price($object->total_ttc).'</td>';
  2571. print '<td>'.$langs->trans('Currency'.$conf->currency).'</td></tr>';
  2572. // Statut
  2573. print '<tr><td>'.$langs->trans('Status').'</td>';
  2574. print '<td align="left" colspan="3">'.($object->getLibStatut(4,$totalpaye)).'</td></tr>';
  2575. // Project
  2576. if ($conf->projet->enabled)
  2577. {
  2578. $langs->load('projects');
  2579. print '<tr>';
  2580. print '<td>';
  2581. print '<table class="nobordernopadding" width="100%"><tr><td>';
  2582. print $langs->trans('Project');
  2583. print '</td>';
  2584. if ($action != 'classify')
  2585. {
  2586. print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=classify&amp;facid='.$object->id.'">';
  2587. print img_edit($langs->trans('SetProject'),1);
  2588. print '</a></td>';
  2589. }
  2590. print '</tr></table>';
  2591. print '</td><td colspan="3">';
  2592. if ($action == 'classify')
  2593. {
  2594. $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'projectid');
  2595. }
  2596. else
  2597. {
  2598. $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'none');
  2599. }
  2600. print '</td>';
  2601. print '</tr>';
  2602. }
  2603. // Other attributes
  2604. $parameters=array('colspan' => ' colspan="3"');
  2605. $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook
  2606. if (empty($reshook) && ! empty($extrafields->attribute_label))
  2607. {
  2608. foreach($extrafields->attribute_label as $key=>$label)
  2609. {
  2610. $value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]);
  2611. print '<tr><td>'.$label.'</td><td colspan="3">';
  2612. print $extrafields->showInputField($key,$value);
  2613. print '</td></tr>'."\n";
  2614. }
  2615. }
  2616. print '</table><br>';
  2617. if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB))
  2618. {
  2619. require_once(DOL_DOCUMENT_ROOT."/contact/class/contact.class.php");
  2620. require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php');
  2621. $formcompany= new FormCompany($db);
  2622. $blocname = 'contacts';
  2623. $title = $langs->trans('ContactsAddresses');
  2624. include(DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php');
  2625. }
  2626. if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB))
  2627. {
  2628. $blocname = 'notes';
  2629. $title = $langs->trans('Notes');
  2630. include(DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php');
  2631. }
  2632. /*
  2633. * Lines
  2634. */
  2635. $result = $object->getLinesArray();
  2636. if ($conf->use_javascript_ajax && $object->statut == 0)
  2637. {
  2638. include(DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php');
  2639. }
  2640. print '<table id="tablelines" class="noborder noshadow" width="100%">';
  2641. // Show object lines
  2642. if (! empty($object->lines)) $object->printObjectLines($action,$mysoc,$soc,$lineid,1,$hookmanager);
  2643. /*
  2644. * Form to add new line
  2645. */
  2646. if ($object->statut == 0 && $user->rights->facture->creer && $action <> 'valid' && $action <> 'editline')
  2647. {
  2648. $var=true;
  2649. $object->formAddFreeProduct(1,$mysoc,$soc,$hookmanager);
  2650. // Add predefined products/services
  2651. if ($conf->product->enabled || $conf->service->enabled)
  2652. {
  2653. $var=!$var;
  2654. $object->formAddPredefinedProduct(1,$mysoc,$soc,$hookmanager);
  2655. }
  2656. $parameters=array();
  2657. $reshook=$hookmanager->executeHooks('formAddObject',$parameters,$object,$action); // Note that $action and $object may have been modified by hook
  2658. }
  2659. print "</table>\n";
  2660. print "</div>\n";
  2661. /*
  2662. * Boutons actions
  2663. */
  2664. if ($action != 'prerelance' && $action != 'presend')
  2665. {
  2666. if ($user->societe_id == 0 && $action <> 'valid' && $action <> 'editline')
  2667. {
  2668. print '<div class="tabsAction">';
  2669. // Editer une facture deja validee, sans paiement effectue et pas exporte en compta
  2670. if ($object->statut == 1)
  2671. {
  2672. // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees
  2673. $ventilExportCompta = $object->getVentilExportCompta();
  2674. if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0)
  2675. {
  2676. if (! $objectidnext)
  2677. {
  2678. if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate)
  2679. {
  2680. print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=modif">'.$langs->trans('Modify').'</a>';
  2681. }
  2682. else
  2683. {
  2684. print '<span class="butActionRefused" title="'.$langs->trans("NotEnoughPermissions").'">'.$langs->trans('Modify').'</span>';
  2685. }
  2686. }
  2687. else
  2688. {
  2689. print '<span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('Modify').'</span>';
  2690. }
  2691. }
  2692. }
  2693. // Reopen a standard paid invoice
  2694. if (($object->type == 0 || $object->type == 1) && ($object->statut == 2 || $object->statut == 3)) // A paid invoice (partially or completely)
  2695. {
  2696. if (! $objectidnext && $object->close_code != 'replaced') // Not replaced by another invoice
  2697. {
  2698. print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=reopen">'.$langs->trans('ReOpen').'</a>';
  2699. }
  2700. else
  2701. {
  2702. print '<span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('ReOpen').'</span>';
  2703. }
  2704. }
  2705. // Validate
  2706. if ($object->statut == 0 && count($object->lines) > 0 &&
  2707. (
  2708. (($object->type == 0 || $object->type == 1 || $object->type == 3 || $object->type == 4) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0))
  2709. || ($object->type == 2 && $object->total_ttc <= 0))
  2710. )
  2711. {
  2712. if ($user->rights->facture->valider)
  2713. {
  2714. print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=valid">'.$langs->trans('Validate').'</a>';
  2715. }
  2716. }
  2717. // Send by mail
  2718. if (($object->statut == 1 || $object->statut == 2))
  2719. {
  2720. if ($objectidnext)
  2721. {
  2722. print '<span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('SendByMail').'</span>';
  2723. }
  2724. else
  2725. {
  2726. if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send)
  2727. {
  2728. print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=presend&amp;mode=init">'.$langs->trans('SendByMail').'</a>';
  2729. }
  2730. else print '<a class="butActionRefused" href="#">'.$langs->trans('SendByMail').'</a>';
  2731. }
  2732. }
  2733. if (! empty($conf->global->FACTURE_SHOW_SEND_REMINDER)) // For backward compatibility
  2734. {
  2735. if (($object->statut == 1 || $object->statut == 2) && $resteapayer > 0)
  2736. {
  2737. if ($objectidnext)
  2738. {
  2739. print '<span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('SendRemindByMail').'</span>';
  2740. }
  2741. else
  2742. {
  2743. if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send)
  2744. {
  2745. print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=prerelance&amp;mode=init">'.$langs->trans('SendRemindByMail').'</a>';
  2746. }
  2747. else print '<a class="butActionRefused" href="#">'.$langs->trans('SendRemindByMail').'</a>';
  2748. }
  2749. }
  2750. }
  2751. // Create payment
  2752. if ($object->type != 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement)
  2753. {
  2754. if ($objectidnext)
  2755. {
  2756. print '<span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('DoPayment').'</span>';
  2757. }
  2758. else
  2759. {
  2760. if ($resteapayer == 0)
  2761. {
  2762. print '<span class="butActionRefused" title="'.$langs->trans("DisabledBecauseRemainderToPayIsZero").'">'.$langs->trans('DoPayment').'</span>';
  2763. }
  2764. else
  2765. {
  2766. print '<a class="butAction" href="paiement.php?facid='.$object->id.'&amp;action=create">'.$langs->trans('DoPayment').'</a>';
  2767. }
  2768. }
  2769. }
  2770. // Reverse back money or convert to reduction
  2771. if ($object->type == 2 || $object->type == 3)
  2772. {
  2773. // For credit note only
  2774. if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement)
  2775. {
  2776. print '<a class="butAction" href="paiement.php?facid='.$object->id.'&amp;action=create">'.$langs->trans('DoPaymentBack').'</a>';
  2777. }
  2778. // For credit note
  2779. if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->creer && $object->getSommePaiement() == 0)
  2780. {
  2781. print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=converttoreduc">'.$langs->trans('ConvertToReduc').'</a>';
  2782. }
  2783. // For deposit invoice
  2784. if ($object->type == 3 && $object->statut == 1 && $resteapayer == 0 && $user->rights->facture->creer)
  2785. {
  2786. print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=converttoreduc">'.$langs->trans('ConvertToReduc').'</a>';
  2787. }
  2788. }
  2789. // Classify paid (if not deposit and not credit note. Such invoice are "converted")
  2790. if ($object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement &&
  2791. (($object->type != 2 && $object->type != 3 && $resteapayer <= 0) || ($object->type == 2 && $resteapayer >= 0)) )
  2792. {
  2793. print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=paid">'.$langs->trans('ClassifyPaid').'</a>';
  2794. }
  2795. // Classify 'closed not completely paid' (possible si validee et pas encore classee payee)
  2796. if ($object->statut == 1 && $object->paye == 0 && $resteapayer > 0
  2797. && $user->rights->facture->paiement)
  2798. {
  2799. if ($totalpaye > 0 || $totalcreditnotes > 0)
  2800. {
  2801. // If one payment or one credit note was linked to this invoice
  2802. print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=paid">'.$langs->trans('ClassifyPaidPartially').'</a>';
  2803. }
  2804. else
  2805. {
  2806. if ($objectidnext)
  2807. {
  2808. print '<span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('ClassifyCanceled').'</span>';
  2809. }
  2810. else
  2811. {
  2812. print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=canceled">'.$langs->trans('ClassifyCanceled').'</a>';
  2813. }
  2814. }
  2815. }
  2816. // Clone
  2817. if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $user->rights->facture->creer)
  2818. {
  2819. print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=clone&amp;object=invoice">'.$langs->trans("ToClone").'</a>';
  2820. }
  2821. // Clone as predefined
  2822. if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $object->statut == 0 && $user->rights->facture->creer)
  2823. {
  2824. if (! $objectidnext)
  2825. {
  2826. print '<a class="butAction" href="facture/fiche-rec.php?facid='.$object->id.'&amp;action=create">'.$langs->trans("ChangeIntoRepeatableInvoice").'</a>';
  2827. }
  2828. }
  2829. // Delete
  2830. if ($user->rights->facture->supprimer)
  2831. {
  2832. if (! $object->is_erasable())
  2833. {
  2834. print '<a class="butActionRefused" href="#" title="'.$langs->trans("DisabledBecauseNotErasable").'">'.$langs->trans('Delete').'</a>';
  2835. }
  2836. else if ($objectidnext)
  2837. {
  2838. print '<a class="butActionRefused" href="#" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('Delete').'</a>';
  2839. }
  2840. elseif ($object->getSommePaiement())
  2841. {
  2842. print '<a class="butActionRefused" href="#" title="'.$langs->trans("DisabledBecausePayments").'">'.$langs->trans('Delete').'</a>';
  2843. }
  2844. else
  2845. {
  2846. print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=delete">'.$langs->trans('Delete').'</a>';
  2847. }
  2848. }
  2849. else
  2850. {
  2851. print '<a class="butActionRefused" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans('Delete').'</a>';
  2852. }
  2853. print '</div>';
  2854. }
  2855. }
  2856. if ($action != 'prerelance' && $action != 'presend')
  2857. {
  2858. print '<table width="100%"><tr><td width="50%" valign="top">';
  2859. print '<a name="builddoc"></a>'; // ancre
  2860. /*
  2861. * Documents generes
  2862. */
  2863. $filename=dol_sanitizeFileName($object->ref);
  2864. $filedir=$conf->facture->dir_output . '/' . dol_sanitizeFileName($object->ref);
  2865. $urlsource=$_SERVER['PHP_SELF'].'?facid='.$object->id;
  2866. $genallowed=$user->rights->facture->creer;
  2867. $delallowed=$user->rights->facture->supprimer;
  2868. print '<br>';
  2869. print $formfile->showdocuments('facture',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang,$hookmanager);
  2870. $somethingshown=$formfile->numoffiles;
  2871. /*
  2872. * Linked object block
  2873. */
  2874. $somethingshown=$object->showLinkedObjectBlock();
  2875. // Link for paypal payment
  2876. if ($conf->paypal->enabled && $object->statut != 0)
  2877. {
  2878. include_once(DOL_DOCUMENT_ROOT.'/paypal/lib/paypal.lib.php');
  2879. print showPaypalPaymentUrl('invoice',$object->ref);
  2880. }
  2881. print '</td><td valign="top" width="50%">';
  2882. print '<br>';
  2883. // List of actions on element
  2884. include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php');
  2885. $formactions=new FormActions($db);
  2886. $somethingshown=$formactions->showactions($object,'invoice',$socid);
  2887. print '</td></tr></table>';
  2888. }
  2889. else
  2890. {
  2891. /*
  2892. * Affiche formulaire mail
  2893. */
  2894. // By default if $action=='presend'
  2895. $titreform='SendBillByMail';
  2896. $topicmail='SendBillRef';
  2897. $action='send';
  2898. $modelmail='facture_send';
  2899. if ($action == 'prerelance') // For backward compatibility
  2900. {
  2901. $titrefrom='SendReminderBillByMail';
  2902. $topicmail='SendReminderBillRef';
  2903. $action='relance';
  2904. $modelmail='facture_relance';
  2905. }
  2906. $ref = dol_sanitizeFileName($object->ref);
  2907. include_once(DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php');
  2908. $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref);
  2909. $file=$fileparams['fullname'];
  2910. // Build document if it not exists
  2911. if (! $file || ! is_readable($file))
  2912. {
  2913. // Define output language
  2914. $outputlangs = $langs;
  2915. $newlang='';
  2916. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
  2917. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
  2918. if (! empty($newlang))
  2919. {
  2920. $outputlangs = new Translate("",$conf);
  2921. $outputlangs->setDefaultLang($newlang);
  2922. }
  2923. $result=facture_pdf_create($db, $object, GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
  2924. if ($result <= 0)
  2925. {
  2926. dol_print_error($db,$result);
  2927. exit;
  2928. }
  2929. $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref);
  2930. $file=$fileparams['fullname'];
  2931. }
  2932. print '<br>';
  2933. print_titre($langs->trans($titreform));
  2934. // Cree l'objet formulaire mail
  2935. include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php');
  2936. $formmail = new FormMail($db);
  2937. $formmail->fromtype = 'user';
  2938. $formmail->fromid = $user->id;
  2939. $formmail->fromname = $user->getFullName($langs);
  2940. $formmail->frommail = $user->email;
  2941. $formmail->withfrom=1;
  2942. $formmail->withto=empty($_POST["sendto"])?1:$_POST["sendto"];
  2943. $formmail->withtosocid=$soc->id;
  2944. $formmail->withtocc=1;
  2945. $formmail->withtoccsocid=0;
  2946. $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC;
  2947. $formmail->withtocccsocid=0;
  2948. $formmail->withtopic=$langs->transnoentities($topicmail,'__FACREF__');
  2949. $formmail->withfile=2;
  2950. $formmail->withbody=1;
  2951. $formmail->withdeliveryreceipt=1;
  2952. $formmail->withcancel=1;
  2953. // Tableau des substitutions
  2954. $formmail->substit['__FACREF__']=$object->ref;
  2955. $formmail->substit['__SIGNATURE__']=$user->signature;
  2956. $formmail->substit['__PERSONALIZED__']='';
  2957. // Tableau des parametres complementaires du post
  2958. $formmail->param['action']=$action;
  2959. $formmail->param['models']=$modelmail;
  2960. $formmail->param['facid']=$object->id;
  2961. $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id;
  2962. // Init list of files
  2963. if (GETPOST("mode")=='init')
  2964. {
  2965. $formmail->clear_attached_files();
  2966. $formmail->add_attached_files($file,basename($file),dol_mimetype($file));
  2967. }
  2968. $formmail->show_form();
  2969. print '<br>';
  2970. }
  2971. }
  2972. else
  2973. {
  2974. dol_print_error($db,$object->error);
  2975. }
  2976. }
  2977. dol_htmloutput_mesg('',$mesgs);
  2978. llxFooter();
  2979. $db->close();
  2980. ?>