PageRenderTime 69ms CodeModel.GetById 24ms 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

Large files files are truncated, but you can click here to view the full file

  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. // C…

Large files files are truncated, but you can click here to view the full file