PageRenderTime 62ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/htdocs/compta/facture.php

https://github.com/zeert/dolibarr
PHP | 3331 lines | 2653 code | 351 blank | 327 comment | 929 complexity | 0e6934c45d5b9ad7898c0d41c0ccc530 MD5 | raw file
Possible License(s): LGPL-2.0

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-2012 Laurent Destailleur <eldy@users.sourceforge.net>
  5. * Copyright (C) 2005 Marc Barilley / Ocebo <marc@ocebo.com>
  6. * Copyright (C) 2005-2012 Regis Houssin <regis@dolibarr.fr>
  7. * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
  8. * Copyright (C) 2010-2012 Juanjo Menent <jmenent@2byte.es>
  9. * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. */
  24. /**
  25. * \file htdocs/compta/facture.php
  26. * \ingroup facture
  27. * \brief Page to create/see an invoice
  28. */
  29. require('../main.inc.php');
  30. require_once(DOL_DOCUMENT_ROOT."/core/class/html.formfile.class.php");
  31. require_once(DOL_DOCUMENT_ROOT."/core/class/html.formother.class.php");
  32. require_once(DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php');
  33. require_once(DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php');
  34. require_once(DOL_DOCUMENT_ROOT.'/core/class/discount.class.php');
  35. require_once(DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php');
  36. require_once(DOL_DOCUMENT_ROOT."/core/lib/functions2.lib.php");
  37. require_once(DOL_DOCUMENT_ROOT.'/core/lib/invoice.lib.php');
  38. require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php");
  39. if (! empty($conf->commande->enabled)) require_once(DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php');
  40. if (! empty($conf->projet->enabled))
  41. {
  42. require_once(DOL_DOCUMENT_ROOT.'/projet/class/project.class.php');
  43. require_once(DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php');
  44. }
  45. $langs->load('bills');
  46. //print 'ee'.$langs->trans('BillsCustomer');exit;
  47. $langs->load('companies');
  48. $langs->load('products');
  49. $langs->load('main');
  50. if (! empty($conf->margin->enabled))
  51. $langs->load('margins');
  52. $sall=trim(GETPOST('sall'));
  53. $projectid=(GETPOST('projectid')?GETPOST('projectid','int'):0);
  54. $id=(GETPOST('id','int')?GETPOST('id','int'):GETPOST('facid','int')); // For backward compatibility
  55. $ref=GETPOST('ref','alpha');
  56. $socid=GETPOST('socid','int');
  57. $action=GETPOST('action','alpha');
  58. $confirm=GETPOST('confirm','alpha');
  59. $lineid=GETPOST('lineid','int');
  60. $userid=GETPOST('userid','int');
  61. $search_ref=GETPOST('sf_ref')?GETPOST('sf_ref','alpha'):GETPOST('search_ref','alpha');
  62. $search_societe=GETPOST('search_societe','alpha');
  63. $search_montant_ht=GETPOST('search_montant_ht','alpha');
  64. $search_montant_ttc=GETPOST('search_montant_ttc','alpha');
  65. //PDF
  66. $hidedetails = (GETPOST('hidedetails','int') ? GETPOST('hidedetails','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0));
  67. $hidedesc = (GETPOST('hidedesc','int') ? GETPOST('hidedesc','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0));
  68. $hideref = (GETPOST('hideref','int') ? GETPOST('hideref','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0));
  69. // Security check
  70. $fieldid = (! empty($ref)?'facnumber':'rowid');
  71. if ($user->societe_id) $socid=$user->societe_id;
  72. $result = restrictedArea($user, 'facture', $id,'','','fk_soc',$fieldid);
  73. // Nombre de ligne pour choix de produit/service predefinis
  74. $NBLINES=4;
  75. $usehm=(! empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE)?$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE:0);
  76. $object=new Facture($db);
  77. // Load object
  78. if ($id > 0 || ! empty($ref))
  79. {
  80. $ret=$object->fetch($id, $ref);
  81. }
  82. // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array
  83. include_once(DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php');
  84. $hookmanager=new HookManager($db);
  85. $hookmanager->initHooks(array('invoicecard'));
  86. /*
  87. * Actions
  88. */
  89. $parameters=array('socid'=>$socid);
  90. $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks
  91. // Action clone object
  92. if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->facture->creer)
  93. {
  94. if (1==0 && empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"]))
  95. {
  96. $mesgs[]='<div class="error">'.$langs->trans("NoCloneOptionsSpecified").'</div>';
  97. }
  98. else
  99. {
  100. if ($object->fetch($id) > 0)
  101. {
  102. $result=$object->createFromClone($socid, $hookmanager);
  103. if ($result > 0)
  104. {
  105. header("Location: ".$_SERVER['PHP_SELF'].'?facid='.$result);
  106. exit;
  107. }
  108. else
  109. {
  110. $mesgs[]=$object->error;
  111. $action='';
  112. }
  113. }
  114. }
  115. }
  116. // Change status of invoice
  117. else if ($action == 'reopen' && $user->rights->facture->creer)
  118. {
  119. $result = $object->fetch($id);
  120. if ($object->statut == 2
  121. || ($object->statut == 3 && $object->close_code != 'replaced'))
  122. {
  123. $result = $object->set_unpaid($user);
  124. if ($result > 0)
  125. {
  126. Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id);
  127. exit;
  128. }
  129. else
  130. {
  131. $mesgs[]='<div class="error">'.$object->error.'</div>';
  132. }
  133. }
  134. }
  135. // Delete invoice
  136. else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->facture->supprimer)
  137. {
  138. $result = $object->fetch($id);
  139. $object->fetch_thirdparty();
  140. $result = $object->delete();
  141. if ($result > 0)
  142. {
  143. Header('Location: '.DOL_URL_ROOT.'/compta/facture/list.php');
  144. exit;
  145. }
  146. else
  147. {
  148. $mesgs[]='<div class="error">'.$object->error.'</div>';
  149. }
  150. }
  151. // Delete line
  152. else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->facture->creer)
  153. {
  154. $object->fetch($id);
  155. $object->fetch_thirdparty();
  156. $result = $object->deleteline($_GET['lineid'], $user);
  157. if ($result > 0)
  158. {
  159. // Define output language
  160. $outputlangs = $langs;
  161. $newlang='';
  162. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
  163. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
  164. if (! empty($newlang))
  165. {
  166. $outputlangs = new Translate("",$conf);
  167. $outputlangs->setDefaultLang($newlang);
  168. }
  169. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
  170. {
  171. $ret=$object->fetch($id); // Reload to get new records
  172. $result=facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
  173. }
  174. if ($result >= 0)
  175. {
  176. Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id);
  177. exit;
  178. }
  179. }
  180. else
  181. {
  182. $mesgs[]='<div clas="error">'.$object->error.'</div>';
  183. $action='';
  184. }
  185. }
  186. // Delete link of credit note to invoice
  187. else if ($action == 'unlinkdiscount' && $user->rights->facture->creer)
  188. {
  189. $discount=new DiscountAbsolute($db);
  190. $result=$discount->fetch($_GET["discountid"]);
  191. $discount->unlink_invoice();
  192. }
  193. // Validation
  194. else if ($action == 'valid' && $user->rights->facture->creer)
  195. {
  196. $object->fetch($id);
  197. // On verifie signe facture
  198. if ($object->type == 2)
  199. {
  200. // Si avoir, le signe doit etre negatif
  201. if ($object->total_ht >= 0)
  202. {
  203. $mesgs[]='<div class="error">'.$langs->trans("ErrorInvoiceAvoirMustBeNegative").'</div>';
  204. $action='';
  205. }
  206. }
  207. else
  208. {
  209. // Si non avoir, le signe doit etre positif
  210. if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ht < 0)
  211. {
  212. $mesgs[]='<div class="error">'.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive").'</div>';
  213. $action='';
  214. }
  215. }
  216. }
  217. else if ($action == 'set_thirdparty' && $user->rights->facture->creer)
  218. {
  219. $object->fetch($id);
  220. $object->setValueFrom('fk_soc',$socid);
  221. Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id);
  222. exit;
  223. }
  224. else if ($action == 'classin' && $user->rights->facture->creer)
  225. {
  226. $object->fetch($id);
  227. $object->setProject($_POST['projectid']);
  228. }
  229. else if ($action == 'setmode' && $user->rights->facture->creer)
  230. {
  231. $object->fetch($id);
  232. $result = $object->setPaymentMethods(GETPOST('mode_reglement_id','int'));
  233. if ($result < 0) dol_print_error($db,$object->error);
  234. }
  235. else if ($action == 'setinvoicedate' && $user->rights->facture->creer)
  236. {
  237. $object->fetch($id);
  238. $object->date=dol_mktime(12,0,0,$_POST['invoicedatemonth'],$_POST['invoicedateday'],$_POST['invoicedateyear']);
  239. if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement=$object->date;
  240. $result=$object->update($user);
  241. if ($result < 0) dol_print_error($db,$object->error);
  242. }
  243. else if ($action == 'setpaymentterm' && $user->rights->facture->creer)
  244. {
  245. $object->fetch($id);
  246. $object->date_lim_reglement=dol_mktime(12,0,0,$_POST['paymenttermmonth'],$_POST['paymenttermday'],$_POST['paymenttermyear']);
  247. if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement=$object->date;
  248. $result=$object->update($user);
  249. if ($result < 0) dol_print_error($db,$object->error);
  250. }
  251. else if ($action == 'setconditions' && $user->rights->facture->creer)
  252. {
  253. $object->fetch($id);
  254. $result=$object->setPaymentTerms(GETPOST('cond_reglement_id','int'));
  255. if ($result < 0) dol_print_error($db,$object->error);
  256. }
  257. else if ($action == 'setremisepercent' && $user->rights->facture->creer)
  258. {
  259. $object->fetch($id);
  260. $result = $object->set_remise($user, $_POST['remise_percent']);
  261. }
  262. else if ($action == "setabsolutediscount" && $user->rights->facture->creer)
  263. {
  264. // POST[remise_id] ou POST[remise_id_for_payment]
  265. if (! empty($_POST["remise_id"]))
  266. {
  267. $ret=$object->fetch($id);
  268. if ($ret > 0)
  269. {
  270. $result=$object->insert_discount($_POST["remise_id"]);
  271. if ($result < 0)
  272. {
  273. $mesgs[]='<div class="error">'.$object->error.'</div>';
  274. }
  275. }
  276. else
  277. {
  278. dol_print_error($db,$object->error);
  279. }
  280. }
  281. if (! empty($_POST["remise_id_for_payment"]))
  282. {
  283. require_once(DOL_DOCUMENT_ROOT.'/core/class/discount.class.php');
  284. $discount = new DiscountAbsolute($db);
  285. $discount->fetch($_POST["remise_id_for_payment"]);
  286. $result=$discount->link_to_invoice(0,$id);
  287. if ($result < 0)
  288. {
  289. $mesgs[]='<div class="error">'.$discount->error.'</div>';
  290. }
  291. }
  292. }
  293. else if ($action == 'set_ref_client' && $user->rights->facture->creer)
  294. {
  295. $object->fetch($id);
  296. $object->set_ref_client($_POST['ref_client']);
  297. }
  298. else if ($action == 'setnote_public' && $user->rights->facture->creer)
  299. {
  300. $object->fetch($id);
  301. $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES));
  302. if ($result < 0) dol_print_error($db,$object->error);
  303. }
  304. else if ($action == 'setnote' && $user->rights->facture->creer)
  305. {
  306. $object->fetch($id);
  307. $result=$object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES));
  308. if ($result < 0) dol_print_error($db,$object->error);
  309. }
  310. // Classify to validated
  311. else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->facture->valider)
  312. {
  313. $idwarehouse=GETPOST('idwarehouse');
  314. $object->fetch($id);
  315. $object->fetch_thirdparty();
  316. // Check parameters
  317. if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1))
  318. {
  319. if (! $idwarehouse || $idwarehouse == -1)
  320. {
  321. $error++;
  322. $mesgs[]=$langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse"));
  323. $action='';
  324. }
  325. }
  326. if (! $error)
  327. {
  328. $result = $object->validate($user,'',$idwarehouse);
  329. if ($result >= 0)
  330. {
  331. // Define output language
  332. $outputlangs = $langs;
  333. $newlang='';
  334. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
  335. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
  336. if (! empty($newlang))
  337. {
  338. $outputlangs = new Translate("",$conf);
  339. $outputlangs->setDefaultLang($newlang);
  340. }
  341. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
  342. {
  343. $ret=$object->fetch($id); // Reload to get new records
  344. facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
  345. }
  346. }
  347. else
  348. {
  349. $mesgs[]='<div class="error">'.$object->error.'</div>';
  350. }
  351. }
  352. }
  353. // Go back to draft status (unvalidate)
  354. else if ($action == 'confirm_modif' && ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate))
  355. {
  356. $idwarehouse=GETPOST('idwarehouse');
  357. $object->fetch($id);
  358. $object->fetch_thirdparty();
  359. // Check parameters
  360. if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1))
  361. {
  362. if (! $idwarehouse || $idwarehouse == -1)
  363. {
  364. $error++;
  365. $mesgs[]=$langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse"));
  366. $action='';
  367. }
  368. }
  369. if (! $error)
  370. {
  371. // On verifie si la facture a des paiements
  372. $sql = 'SELECT pf.amount';
  373. $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf';
  374. $sql.= ' WHERE pf.fk_facture = '.$object->id;
  375. $result = $db->query($sql);
  376. if ($result)
  377. {
  378. $i = 0;
  379. $num = $db->num_rows($result);
  380. while ($i < $num)
  381. {
  382. $objp = $db->fetch_object($result);
  383. $totalpaye += $objp->amount;
  384. $i++;
  385. }
  386. }
  387. else
  388. {
  389. dol_print_error($db,'');
  390. }
  391. $resteapayer = $object->total_ttc - $totalpaye;
  392. // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees
  393. $ventilExportCompta = $object->getVentilExportCompta();
  394. // On verifie si aucun paiement n'a ete effectue
  395. if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0)
  396. {
  397. $object->set_draft($user, $idwarehouse);
  398. // Define output language
  399. $outputlangs = $langs;
  400. $newlang='';
  401. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
  402. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
  403. if (! empty($newlang))
  404. {
  405. $outputlangs = new Translate("",$conf);
  406. $outputlangs->setDefaultLang($newlang);
  407. }
  408. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
  409. {
  410. $ret=$object->fetch($id); // Reload to get new records
  411. facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
  412. }
  413. }
  414. }
  415. }
  416. // Classify "paid"
  417. else if ($action == 'confirm_paid' && $confirm == 'yes' && $user->rights->facture->paiement)
  418. {
  419. $object->fetch($id);
  420. $result = $object->set_paid($user);
  421. }
  422. // Classif "paid partialy"
  423. else if ($action == 'confirm_paid_partially' && $confirm == 'yes' && $user->rights->facture->paiement)
  424. {
  425. $object->fetch($id);
  426. $close_code=$_POST["close_code"];
  427. $close_note=$_POST["close_note"];
  428. if ($close_code)
  429. {
  430. $result = $object->set_paid($user,$close_code,$close_note);
  431. }
  432. else
  433. {
  434. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("Reason")).'</div>';
  435. }
  436. }
  437. // Classify "abandoned"
  438. else if ($action == 'confirm_canceled' && $confirm == 'yes')
  439. {
  440. $object->fetch($id);
  441. $close_code=$_POST["close_code"];
  442. $close_note=$_POST["close_note"];
  443. if ($close_code)
  444. {
  445. $result = $object->set_canceled($user,$close_code,$close_note);
  446. }
  447. else
  448. {
  449. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("Reason")).'</div>';
  450. }
  451. }
  452. // Convertir en reduc
  453. else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->facture->creer)
  454. {
  455. $db->begin();
  456. $object->fetch($id);
  457. $object->fetch_thirdparty();
  458. $object->fetch_lines();
  459. if (! $object->paye) // protection against multiple submit
  460. {
  461. // Boucle sur chaque taux de tva
  462. $i=0;
  463. foreach($object->lines as $line)
  464. {
  465. $amount_ht[$line->tva_tx]+=$line->total_ht;
  466. $amount_tva[$line->tva_tx]+=$line->total_tva;
  467. $amount_ttc[$line->tva_tx]+=$line->total_ttc;
  468. $i++;
  469. }
  470. // Insert one discount by VAT rate category
  471. $discount = new DiscountAbsolute($db);
  472. if ($object->type == 2) $discount->description='(CREDIT_NOTE)';
  473. elseif ($object->type == 3) $discount->description='(DEPOSIT)';
  474. else {
  475. $this->error="CantConvertToReducAnInvoiceOfThisType";
  476. return -1;
  477. }
  478. $discount->tva_tx=abs($object->total_ttc);
  479. $discount->fk_soc=$object->socid;
  480. $discount->fk_facture_source=$object->id;
  481. $error=0;
  482. foreach($amount_ht as $tva_tx => $xxx)
  483. {
  484. $discount->amount_ht=abs($amount_ht[$tva_tx]);
  485. $discount->amount_tva=abs($amount_tva[$tva_tx]);
  486. $discount->amount_ttc=abs($amount_ttc[$tva_tx]);
  487. $discount->tva_tx=abs($tva_tx);
  488. $result=$discount->create($user);
  489. if ($result < 0)
  490. {
  491. $error++;
  492. break;
  493. }
  494. }
  495. if (! $error)
  496. {
  497. // Classe facture
  498. $result=$object->set_paid($user);
  499. if ($result > 0)
  500. {
  501. //$mesgs[]='OK'.$discount->id;
  502. $db->commit();
  503. }
  504. else
  505. {
  506. $mesgs[]='<div class="error">'.$object->error.'</div>';
  507. $db->rollback();
  508. }
  509. }
  510. else
  511. {
  512. $mesgs[]='<div class="error">'.$discount->error.'</div>';
  513. $db->rollback();
  514. }
  515. }
  516. }
  517. /*
  518. * Insert new invoice in database
  519. */
  520. else if ($action == 'add' && $user->rights->facture->creer)
  521. {
  522. $object->socid=GETPOST('socid','int');
  523. $db->begin();
  524. $error=0;
  525. // Replacement invoice
  526. if ($_POST['type'] == 1)
  527. {
  528. $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
  529. if (empty($datefacture))
  530. {
  531. $error++;
  532. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("Date")).'</div>';
  533. }
  534. if (! ($_POST['fac_replacement'] > 0))
  535. {
  536. $error++;
  537. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("ReplaceInvoice")).'</div>';
  538. }
  539. if (! $error)
  540. {
  541. // This is a replacement invoice
  542. $result=$object->fetch($_POST['fac_replacement']);
  543. $object->fetch_thirdparty();
  544. $object->date = $datefacture;
  545. $object->note_public = trim($_POST['note_public']);
  546. $object->note = trim($_POST['note']);
  547. $object->ref_client = $_POST['ref_client'];
  548. $object->ref_int = $_POST['ref_int'];
  549. $object->modelpdf = $_POST['model'];
  550. $object->fk_project = $_POST['projectid'];
  551. $object->cond_reglement_id = $_POST['cond_reglement_id'];
  552. $object->mode_reglement_id = $_POST['mode_reglement_id'];
  553. $object->remise_absolue = $_POST['remise_absolue'];
  554. $object->remise_percent = $_POST['remise_percent'];
  555. // Proprietes particulieres a facture de remplacement
  556. $object->fk_facture_source = $_POST['fac_replacement'];
  557. $object->type = 1;
  558. $id=$object->createFromCurrent($user);
  559. if ($id <= 0) $mesgs[]=$object->error;
  560. }
  561. }
  562. // Credit note invoice
  563. if ($_POST['type'] == 2)
  564. {
  565. if (! $_POST['fac_avoir'] > 0)
  566. {
  567. $error++;
  568. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("CorrectInvoice")).'</div>';
  569. }
  570. $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
  571. if (empty($datefacture))
  572. {
  573. $error++;
  574. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("Date")).'</div>';
  575. }
  576. if (! $error)
  577. {
  578. // Si facture avoir
  579. $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
  580. //$result=$object->fetch($_POST['fac_avoir']);
  581. $object->socid = $_POST['socid'];
  582. $object->number = $_POST['facnumber'];
  583. $object->date = $datefacture;
  584. $object->note_public = trim($_POST['note_public']);
  585. $object->note = trim($_POST['note']);
  586. $object->ref_client = $_POST['ref_client'];
  587. $object->ref_int = $_POST['ref_int'];
  588. $object->modelpdf = $_POST['model'];
  589. $object->fk_project = $_POST['projectid'];
  590. $object->cond_reglement_id = 0;
  591. $object->mode_reglement_id = $_POST['mode_reglement_id'];
  592. $object->remise_absolue = $_POST['remise_absolue'];
  593. $object->remise_percent = $_POST['remise_percent'];
  594. // Proprietes particulieres a facture avoir
  595. $object->fk_facture_source = $_POST['fac_avoir'];
  596. $object->type = 2;
  597. $id = $object->create($user);
  598. // Add predefined lines
  599. for ($i = 1; $i <= $NBLINES; $i++)
  600. {
  601. if ($_POST['idprod'.$i])
  602. {
  603. $product=new Product($db);
  604. $product->fetch($_POST['idprod'.$i]);
  605. $startday=dol_mktime(12, 0, 0, $_POST['date_start'.$i.'month'], $_POST['date_start'.$i.'day'], $_POST['date_start'.$i.'year']);
  606. $endday=dol_mktime(12, 0, 0, $_POST['date_end'.$i.'month'], $_POST['date_end'.$i.'day'], $_POST['date_end'.$i.'year']);
  607. $result=$object->addline($id,$product->description,$product->price, $_POST['qty'.$i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod'.$i], $_POST['remise_percent'.$i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type);
  608. }
  609. }
  610. }
  611. }
  612. // Standard invoice or Deposit invoice created from a Predefined invoice
  613. if (($_POST['type'] == 0 || $_POST['type'] == 3) && $_POST['fac_rec'] > 0)
  614. {
  615. $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
  616. if (empty($datefacture))
  617. {
  618. $error++;
  619. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("Date")).'</div>';
  620. }
  621. if (! $error)
  622. {
  623. $object->socid = $_POST['socid'];
  624. $object->type = $_POST['type'];
  625. $object->number = $_POST['facnumber'];
  626. $object->date = $datefacture;
  627. $object->note_public = trim($_POST['note_public']);
  628. $object->note = trim($_POST['note']);
  629. $object->ref_client = $_POST['ref_client'];
  630. $object->ref_int = $_POST['ref_int'];
  631. $object->modelpdf = $_POST['model'];
  632. // Source facture
  633. $object->fac_rec = $_POST['fac_rec'];
  634. $id = $object->create($user);
  635. }
  636. }
  637. // Standard or deposit or proforma invoice
  638. if (($_POST['type'] == 0 || $_POST['type'] == 3 || $_POST['type'] == 4) && $_POST['fac_rec'] <= 0)
  639. {
  640. $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
  641. if (empty($datefacture))
  642. {
  643. $error++;
  644. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("Date")).'</div>';
  645. }
  646. if (! $error)
  647. {
  648. // Si facture standard
  649. $object->socid = $_POST['socid'];
  650. $object->type = $_POST['type'];
  651. $object->number = $_POST['facnumber'];
  652. $object->date = $datefacture;
  653. $object->note_public = trim($_POST['note_public']);
  654. $object->note = trim($_POST['note']);
  655. $object->ref_client = $_POST['ref_client'];
  656. $object->ref_int = $_POST['ref_int'];
  657. $object->modelpdf = $_POST['model'];
  658. $object->fk_project = $_POST['projectid'];
  659. $object->cond_reglement_id = ($_POST['type'] == 3?1:$_POST['cond_reglement_id']);
  660. $object->mode_reglement_id = $_POST['mode_reglement_id'];
  661. $object->amount = $_POST['amount'];
  662. $object->remise_absolue = $_POST['remise_absolue'];
  663. $object->remise_percent = $_POST['remise_percent'];
  664. // If creation from another object of another module (Example: origin=propal, originid=1)
  665. if ($_POST['origin'] && $_POST['originid'])
  666. {
  667. // Parse element/subelement (ex: project_task)
  668. $element = $subelement = $_POST['origin'];
  669. if (preg_match('/^([^_]+)_([^_]+)/i',$_POST['origin'],$regs))
  670. {
  671. $element = $regs[1];
  672. $subelement = $regs[2];
  673. }
  674. // For compatibility
  675. if ($element == 'order') { $element = $subelement = 'commande'; }
  676. if ($element == 'propal') { $element = 'comm/propal'; $subelement = 'propal'; }
  677. if ($element == 'contract') { $element = $subelement = 'contrat'; }
  678. if ($element == 'inter') { $element = $subelement = 'ficheinter'; }
  679. if ($element == 'shipping') {$element = $subelement = 'expedition'; }
  680. $object->origin = $_POST['origin'];
  681. $object->origin_id = $_POST['originid'];
  682. // Possibility to add external linked objects with hooks
  683. $object->linked_objects[$object->origin] = $object->origin_id;
  684. if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects']))
  685. {
  686. $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']);
  687. }
  688. $id = $object->create($user);
  689. if ($id > 0)
  690. {
  691. dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
  692. $classname = ucfirst($subelement);
  693. $srcobject = new $classname($db);
  694. dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines");
  695. $result=$srcobject->fetch($object->origin_id);
  696. if ($result > 0)
  697. {
  698. $lines = $srcobject->lines;
  699. if (empty($lines) && method_exists($srcobject,'fetch_lines')) $lines = $srcobject->fetch_lines();
  700. $fk_parent_line=0;
  701. $num=count($lines);
  702. for ($i=0;$i<$num;$i++)
  703. {
  704. $desc=($lines[$i]->desc?$lines[$i]->desc:$lines[$i]->libelle);
  705. if ($lines[$i]->subprice < 0)
  706. {
  707. // Negative line, we create a discount line
  708. $discount = new DiscountAbsolute($db);
  709. $discount->fk_soc=$object->socid;
  710. $discount->amount_ht=abs($lines[$i]->total_ht);
  711. $discount->amount_tva=abs($lines[$i]->total_tva);
  712. $discount->amount_ttc=abs($lines[$i]->total_ttc);
  713. $discount->tva_tx=$lines[$i]->tva_tx;
  714. $discount->fk_user=$user->id;
  715. $discount->description=$desc;
  716. $discountid=$discount->create($user);
  717. if ($discountid > 0)
  718. {
  719. $result=$object->insert_discount($discountid); // This include link_to_invoice
  720. }
  721. else
  722. {
  723. $mesgs[]=$discount->error;
  724. $error++;
  725. break;
  726. }
  727. }
  728. else
  729. {
  730. // Positive line
  731. $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0);
  732. // Date start
  733. $date_start=false;
  734. if ($lines[$i]->date_debut_prevue) $date_start=$lines[$i]->date_debut_prevue;
  735. if ($lines[$i]->date_debut_reel) $date_start=$lines[$i]->date_debut_reel;
  736. if ($lines[$i]->date_start) $date_start=$lines[$i]->date_start;
  737. //Date end
  738. $date_end=false;
  739. if ($lines[$i]->date_fin_prevue) $date_end=$lines[$i]->date_fin_prevue;
  740. if ($lines[$i]->date_fin_reel) $date_end=$lines[$i]->date_fin_reel;
  741. if ($lines[$i]->date_end) $date_end=$lines[$i]->date_end;
  742. // Reset fk_parent_line for no child products and special product
  743. if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) {
  744. $fk_parent_line = 0;
  745. }
  746. $result = $object->addline(
  747. $id,
  748. $desc,
  749. $lines[$i]->subprice,
  750. $lines[$i]->qty,
  751. $lines[$i]->tva_tx,
  752. $lines[$i]->localtax1_tx,
  753. $lines[$i]->localtax2_tx,
  754. $lines[$i]->fk_product,
  755. $lines[$i]->remise_percent,
  756. $date_start,
  757. $date_end,
  758. 0,
  759. $lines[$i]->info_bits,
  760. $lines[$i]->fk_remise_except,
  761. 'HT',
  762. 0,
  763. $product_type,
  764. $lines[$i]->rang,
  765. $lines[$i]->special_code,
  766. $object->origin,
  767. $lines[$i]->rowid,
  768. $fk_parent_line,
  769. $lines[$i]->fk_fournprice,
  770. $lines[$i]->pa_ht
  771. );
  772. if ($result > 0)
  773. {
  774. $lineid=$result;
  775. }
  776. else
  777. {
  778. $lineid=0;
  779. $error++;
  780. break;
  781. }
  782. // Defined the new fk_parent_line
  783. if ($result > 0 && $lines[$i]->product_type == 9) {
  784. $fk_parent_line = $result;
  785. }
  786. }
  787. }
  788. // Hooks
  789. $parameters=array('objFrom'=>$srcobject);
  790. $reshook=$hookmanager->executeHooks('createFrom',$parameters,$object,$action); // Note that $action and $object may have been modified by hook
  791. if ($reshook < 0) $error++;
  792. }
  793. else
  794. {
  795. $mesgs[]=$srcobject->error;
  796. $error++;
  797. }
  798. }
  799. else
  800. {
  801. $mesgs[]=$object->error;
  802. $error++;
  803. }
  804. }
  805. // If some invoice's lines already known
  806. else
  807. {
  808. $id = $object->create($user);
  809. for ($i = 1; $i <= $NBLINES; $i++)
  810. {
  811. if ($_POST['idprod'.$i])
  812. {
  813. $product=new Product($db);
  814. $product->fetch($_POST['idprod'.$i]);
  815. $startday=dol_mktime(12, 0, 0, $_POST['date_start'.$i.'month'], $_POST['date_start'.$i.'day'], $_POST['date_start'.$i.'year']);
  816. $endday=dol_mktime(12, 0, 0, $_POST['date_end'.$i.'month'], $_POST['date_end'.$i.'day'], $_POST['date_end'.$i.'year']);
  817. $result=$object->addline($id,$product->description,$product->price, $_POST['qty'.$i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod'.$i], $_POST['remise_percent'.$i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type);
  818. }
  819. }
  820. }
  821. }
  822. }
  823. // End of object creation, we show it
  824. if ($id > 0 && ! $error)
  825. {
  826. $db->commit();
  827. Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id);
  828. exit;
  829. }
  830. else
  831. {
  832. $db->rollback();
  833. $action='create';
  834. $_GET["origin"]=$_POST["origin"];
  835. $_GET["originid"]=$_POST["originid"];
  836. $mesgs[]='<div class="error">'.$object->error.'</div>';
  837. }
  838. }
  839. // Add a new line
  840. else if (($action == 'addline' || $action == 'addline_predef') && $user->rights->facture->creer)
  841. {
  842. $result=0;
  843. if ($_POST['np_price'] < 0 && $_POST["qty"] < 0)
  844. {
  845. $langs->load("errors");
  846. $mesgs[]='<div class="error">'.$langs->trans("ErrorBothFieldCantBeNegative",$langs->transnoentitiesnoconv("UnitPriceHT"),$langs->transnoentitiesnoconv("Qty")).'</div>';
  847. $result = -1 ;
  848. }
  849. if (empty($_POST['idprod']) && $_POST["type"] < 0)
  850. {
  851. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")).'</div>';
  852. $result = -1 ;
  853. }
  854. if (empty($_POST['idprod']) && (! isset($_POST["np_price"]) || $_POST["np_price"]=='')) // Unit price can be 0 but not ''
  855. {
  856. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("UnitPriceHT")).'</div>';
  857. $result = -1 ;
  858. }
  859. if (empty($_POST['idprod']) && empty($_POST["np_desc"]) && empty($_POST["dp_desc"]))
  860. {
  861. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Description")).'</div>';
  862. $result = -1 ;
  863. }
  864. if (! isset($_POST['qty']) || $_POST['qty']=='')
  865. {
  866. $mesgs[]='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv('Qty')).'</div>';
  867. $result = -1 ;
  868. }
  869. if ($result >= 0 && ( ($_POST['np_price']!='' && ($_POST['np_desc'] || $_POST['dp_desc'])) || $_POST['idprod'] ) )
  870. {
  871. $ret=$object->fetch($id);
  872. if ($ret < 0)
  873. {
  874. dol_print_error($db,$object->error);
  875. exit;
  876. }
  877. $ret=$object->fetch_thirdparty();
  878. $suffixe = $_POST['idprod'] ? '_predef' : '';
  879. $date_start=dol_mktime($_POST['date_start'.$suffixe.'hour'],$_POST['date_start'.$suffixe.'min'],$_POST['date_start'.$suffixe.'sec'],$_POST['date_start'.$suffixe.'month'],$_POST['date_start'.$suffixe.'day'],$_POST['date_start'.$suffixe.'year']);
  880. $date_end=dol_mktime($_POST['date_end'.$suffixe.'hour'],$_POST['date_end'.$suffixe.'min'],$_POST['date_end'.$suffixe.'sec'],$_POST['date_end'.$suffixe.'month'],$_POST['date_end'.$suffixe.'day'],$_POST['date_end'.$suffixe.'year']);
  881. $price_base_type = 'HT';
  882. // Ecrase $pu par celui du produit
  883. // Ecrase $desc par celui du produit
  884. // Ecrase $txtva par celui du produit
  885. // Ecrase $base_price_type par celui du produit
  886. if ($_POST['idprod'])
  887. {
  888. $prod = new Product($db);
  889. $prod->fetch($_POST['idprod']);
  890. $tva_tx = get_default_tva($mysoc,$object->client,$prod->id);
  891. $tva_npr = get_default_npr($mysoc,$object->client,$prod->id);
  892. // We define price for product
  893. if ($conf->global->PRODUIT_MULTIPRICES && $object->client->price_level)
  894. {
  895. $pu_ht = $prod->multiprices[$object->client->price_level];
  896. $pu_ttc = $prod->multiprices_ttc[$object->client->price_level];
  897. $price_min = $prod->multiprices_min[$object->client->price_level];
  898. $price_base_type = $prod->multiprices_base_type[$object->client->price_level];
  899. }
  900. else
  901. {
  902. $pu_ht = $prod->price;
  903. $pu_ttc = $prod->price_ttc;
  904. $price_min = $prod->price_min;
  905. $price_base_type = $prod->price_base_type;
  906. }
  907. // On reevalue prix selon taux tva car taux tva transaction peut etre different
  908. // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur).
  909. if ($tva_tx != $prod->tva_tx)
  910. {
  911. if ($price_base_type != 'HT')
  912. {
  913. $pu_ht = price2num($pu_ttc / (1 + ($tva_tx/100)), 'MU');
  914. }
  915. else
  916. {
  917. $pu_ttc = price2num($pu_ht * (1 + ($tva_tx/100)), 'MU');
  918. }
  919. }
  920. // Define output language
  921. if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE))
  922. {
  923. $outputlangs = $langs;
  924. $newlang='';
  925. if (empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id');
  926. if (empty($newlang)) $newlang=$object->client->default_lang;
  927. if (! empty($newlang))
  928. {
  929. $outputlangs = new Translate("",$conf);
  930. $outputlangs->setDefaultLang($newlang);
  931. }
  932. $desc = (! empty($prod->multilangs[$outputlangs->defaultlang]["description"])) ? $prod->multilangs[$outputlangs->defaultlang]["description"] : $prod->description;
  933. }
  934. else
  935. {
  936. $desc = $prod->description;
  937. }
  938. $desc.= ($desc && $_POST['np_desc']) ? ((dol_textishtml($desc) || dol_textishtml($_POST['np_desc']))?"<br>\n":"\n") : "";
  939. $desc.= $_POST['np_desc'];
  940. if (! empty($prod->customcode) || ! empty($prod->country_code))
  941. {
  942. $tmptxt='(';
  943. if (! empty($prod->customcode)) $tmptxt.=$langs->transnoentitiesnoconv("CustomCode").': '.$prod->customcode;
  944. if (! empty($prod->customcode) && ! empty($prod->country_code)) $tmptxt.=' - ';
  945. if (! empty($prod->country_code)) $tmptxt.=$langs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code,0,$db,$langs,0);
  946. $tmptxt.=')';
  947. $desc.= (dol_textishtml($desc)?"<br>\n":"\n").$tmptxt;
  948. }
  949. $type = $prod->type;
  950. }
  951. else
  952. {
  953. $pu_ht=$_POST['np_price'];
  954. $tva_tx=str_replace('*','',$_POST['np_tva_tx']);
  955. $tva_npr=preg_match('/\*/',$_POST['np_tva_tx'])?1:0;
  956. $desc=$_POST['dp_desc'];
  957. $type=$_POST["type"];
  958. }
  959. $localtax1_tx=get_localtax($tva_tx,1,$object->client);
  960. $localtax2_tx=get_localtax($tva_tx,2,$object->client);
  961. // ajout prix achat
  962. $fk_fournprice = $_POST['np_fournprice'];
  963. if ( ! empty($_POST['np_buying_price']) )
  964. $pa_ht = $_POST['np_buying_price'];
  965. else
  966. $pa_ht = null;
  967. $info_bits=0;
  968. if ($tva_npr) $info_bits |= 0x01;
  969. if ($result >= 0)
  970. {
  971. if($price_min && (price2num($pu_ht)*(1-price2num($_POST['remise_percent'])/100) < price2num($price_min)))
  972. {
  973. $object->error = $langs->trans("CantBeLessThanMinPrice",price2num($price_min,'MU').' '.$langs->trans("Currency".$conf->currency));
  974. $result = -1 ;
  975. }
  976. else
  977. {
  978. // Insert line
  979. $result = $object->addline(
  980. $id,
  981. $desc,
  982. $pu_ht,
  983. $_POST['qty'],
  984. $tva_tx,
  985. $localtax1_tx,
  986. $localtax2_tx,
  987. $_POST['idprod'],
  988. $_POST['remise_percent'],
  989. $date_start,
  990. $date_end,
  991. 0,
  992. $info_bits,
  993. '',
  994. $price_base_type,
  995. $pu_ttc,
  996. $type,
  997. -1,
  998. 0,
  999. '',
  1000. 0,
  1001. GETPOST('fk_parent_line'),
  1002. $fk_fournprice,
  1003. $pa_ht
  1004. );
  1005. }
  1006. }
  1007. }
  1008. if ($result > 0)
  1009. {
  1010. // Define output language
  1011. $outputlangs = $langs;
  1012. $newlang='';
  1013. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
  1014. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
  1015. if (! empty($newlang))
  1016. {
  1017. $outputlangs = new Translate("",$conf);
  1018. $outputlangs->setDefaultLang($newlang);
  1019. }
  1020. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
  1021. {
  1022. $ret=$object->fetch($id); // Reload to get new records
  1023. facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
  1024. }
  1025. unset($_POST['qty']);
  1026. unset($_POST['type']);
  1027. unset($_POST['idprod']);
  1028. unset($_POST['remise_percent']);
  1029. unset($_POST['dp_desc']);
  1030. unset($_POST['np_desc']);
  1031. unset($_POST['np_price']);
  1032. unset($_POST['np_tva_tx']);
  1033. unset($_POST['np_buying_price']);
  1034. }
  1035. else
  1036. {
  1037. $mesgs[]='<div class="error">'.$object->error.'</div>';
  1038. }
  1039. $action='';
  1040. }
  1041. else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['save'] == $langs->trans('Save'))
  1042. {
  1043. if (! $object->fetch($id) > 0) dol_print_error($db);
  1044. $object->fetch_thirdparty();
  1045. // Clean parameters
  1046. $date_start='';
  1047. $date_end='';
  1048. $date_start=dol_mktime($_POST['date_start'.$suffixe.'hour'],$_POST['date_start'.$suffixe.'min'],$_POST['date_start'.$suffixe.'sec'],$_POST['date_start'.$suffixe.'month'],$_POST['date_start'.$suffixe.'day'],$_POST['date_start'.$suffixe.'year']);
  1049. $date_end=dol_mktime($_POST['date_end'.$suffixe.'hour'],$_POST['date_end'.$suffixe.'min'],$_POST['date_end'.$suffixe.'sec'],$_POST['date_end'.$suffixe.'month'],$_POST['date_end'.$suffixe.'day'],$_POST['date_end'.$suffixe.'year']);
  1050. $description=dol_htmlcleanlastbr($_POST['desc']);
  1051. $up_ht=GETPOST('pu')?GETPOST('pu'):GETPOST('subprice');
  1052. // Define info_bits
  1053. $info_bits=0;
  1054. if (preg_match('/\*/',$_POST['tva_tx'])) $info_bits |= 0x01;
  1055. // Define vat_rate
  1056. $vat_rate=$_POST['tva_tx'];
  1057. $vat_rate=str_replace('*','',$vat_rate);
  1058. $localtax1_rate=get_localtax($vat_rate,1,$object->client);
  1059. $localtax2_rate=get_localtax($vat_rate,2,$object->client);
  1060. // ajout prix d'achat
  1061. $fk_fournprice = $_POST['fournprice'];
  1062. if ( ! empty($_POST['buying_price']) )
  1063. $pa_ht = $_POST['buying_price'];
  1064. else
  1065. $pa_ht = null;
  1066. // Check parameters
  1067. if (! GETPOST('productid') && GETPOST("type") < 0)
  1068. {
  1069. $mesgs[] = '<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")).'</div>';
  1070. $result = -1 ;
  1071. }
  1072. // Check minimum price
  1073. if (GETPOST('productid'))
  1074. {
  1075. $productid = GETPOST('productid');
  1076. $product = new Product($db);
  1077. $product->fetch($productid);
  1078. $type=$product->type;
  1079. $price_min = $product->price_min;
  1080. if ($conf->global->PRODUIT_MULTIPRICES && $object->client->price_level) $price_min = $product->multiprices_min[$object->client->price_level];
  1081. }
  1082. if ($object->type!=2 && $price_min && GETPOST('productid') && (price2num($up_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min)))
  1083. {
  1084. //print "CantBeLessThanMinPrice ".$up_ht." - ".GETPOST('remise_percent')." - ".$product->price_min;
  1085. $mesgs[] = '<div class="error">'.$langs->trans("CantBeLessThanMinPrice",price2num($price_min,'MU').' '.$langs->trans("Currency".$conf->currency)).'</div>';
  1086. $result=-1;
  1087. }
  1088. // Define params
  1089. if (GETPOST('productid')) $type=$product->type;
  1090. else $type=GETPOST("type");
  1091. // Update line
  1092. if ($result >= 0)
  1093. {
  1094. $result = $object->updateline(
  1095. GETPOST('lineid'),
  1096. $description,
  1097. $up_ht,
  1098. GETPOST('qty'),
  1099. GETPOST('remise_percent'),
  1100. $date_start,
  1101. $date_end,
  1102. $vat_rate,
  1103. $localtax1_rate,
  1104. $localtax2_rate,
  1105. 'HT',
  1106. $info_bits,
  1107. $type,
  1108. GETPOST('fk_parent_line'),
  1109. 0,
  1110. $fk_fournprice,
  1111. $pa_ht
  1112. );
  1113. // Define output language
  1114. $outputlangs = $langs;
  1115. $newlang='';
  1116. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id');
  1117. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
  1118. if (! empty($newlang))
  1119. {
  1120. $outputlangs = new Translate("",$conf);
  1121. $outputlangs->setDefaultLang($newlang);
  1122. }
  1123. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
  1124. {
  1125. $ret=$object->fetch($id); // Reload to get new records
  1126. facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
  1127. unset($_POST['qty']);
  1128. unset($_POST['type']);
  1129. unset($_POST['np_price']);
  1130. unset($_POST['dp_desc']);
  1131. unset($_POST['np_tva_tx']);
  1132. unset($_POST['np_buying_price']);
  1133. }
  1134. }
  1135. }
  1136. else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['cancel'] == $langs->trans('Cancel'))
  1137. {
  1138. Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); // Pour reaffichage de la fiche en cours d'edition
  1139. exit;
  1140. }
  1141. // Modify line position (up)
  1142. else if ($action == 'up' && $user->rights->facture->creer)
  1143. {
  1144. $object->fetch($id);
  1145. $object->fetch_thirdparty();
  1146. $object->line_up($_GET['rowid']);
  1147. // Define output language
  1148. $outputlangs = $langs;
  1149. $newlang='';
  1150. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
  1151. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
  1152. if (! empty($newlang))
  1153. {
  1154. $outputlangs = new Translate("",$conf);
  1155. $outputlangs->setDefaultLang($newlang);
  1156. }
  1157. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
  1158. Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.'#'.$_GET['rowid']);
  1159. exit;
  1160. }
  1161. // Modify line position (down)
  1162. else if ($action == 'down' && $user->rights->facture->creer)
  1163. {
  1164. $object->fetch($id);
  1165. $object->fetch_thirdparty();
  1166. $object->line_down($_GET['rowid']);
  1167. // Define output language
  1168. $outputlangs = $langs;
  1169. $newlang='';
  1170. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
  1171. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
  1172. if (! empty($newlang))
  1173. {
  1174. $outputlangs = new Translate("",$conf);
  1175. $outputlangs->setDefaultLang($newlang);
  1176. }
  1177. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
  1178. Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.'#'.$_GET['rowid']);
  1179. exit;
  1180. }
  1181. /*
  1182. * Add file in email form
  1183. */
  1184. if

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