PageRenderTime 41ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/htdocs/compta/facture.php

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