PageRenderTime 61ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/htdocs/facture/fiche.php

https://bitbucket.org/speedealing/speedealing
PHP | 2112 lines | 1347 code | 296 blank | 469 comment | 509 complexity | 94663e3bcc9c51249c5cacfa1cbffb24 MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1, GPL-3.0, MIT

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.houssin@capnetworks.com>
  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. * Copyright (C) 2011-2012 Herve Prot <herve.prot@symeos.com>
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation; either version 3 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  24. */
  25. require '../main.inc.php';
  26. require DOL_DOCUMENT_ROOT . '/facture/class/facture.class.php';
  27. require DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php';
  28. require DOL_DOCUMENT_ROOT . '/facture/core/modules/facture/modules_facture.php';
  29. require DOL_DOCUMENT_ROOT . '/core/class/discount.class.php';
  30. require DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php';
  31. require DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php';
  32. require DOL_DOCUMENT_ROOT . '/core/lib/invoice.lib.php';
  33. require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php';
  34. require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
  35. /* Loading langs ************************************************************ */
  36. $langs->load('bills');
  37. $langs->load('orders');
  38. $langs->load('companies');
  39. $langs->load('products');
  40. $langs->load('main');
  41. if (!empty($conf->margin->enabled))
  42. $langs->load('margins');
  43. /* Parameters *************************************************************** */
  44. $sall = trim(GETPOST('sall'));
  45. $projectid = (GETPOST('projectid') ? GETPOST('projectid', 'int') : 0);
  46. $id = (GETPOST('id', 'alpha') ? GETPOST('id', 'alpha') : GETPOST('facid', 'alpha')); // For backward compatibility
  47. $ref = GETPOST('ref', 'alpha');
  48. $socid = GETPOST('socid', 'alpha');
  49. $action = GETPOST('action', 'alpha');
  50. $confirm = GETPOST('confirm', 'alpha');
  51. $lineid = GETPOST('lineid', 'alpha');
  52. $userid = GETPOST('userid', 'alpha');
  53. $search_ref = GETPOST('sf_ref') ? GETPOST('sf_ref', 'alpha') : GETPOST('search_ref', 'alpha');
  54. $search_societe = GETPOST('search_societe', 'alpha');
  55. $search_montant_ht = GETPOST('search_montant_ht', 'alpha');
  56. $search_montant_ttc = GETPOST('search_montant_ttc', 'alpha');
  57. $origin = GETPOST('origin', 'alpha');
  58. $originid = (GETPOST('originid', 'alpha') ? GETPOST('originid', 'alpha') : GETPOST('origin_id', 'alpha')); // For backward compatibility
  59. //PDF
  60. $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0));
  61. $hidedesc = (GETPOST('hidedesc', 'int') ? GETPOST('hidedesc', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0));
  62. $hideref = (GETPOST('hideref', 'int') ? GETPOST('hideref', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0));
  63. $object = new Facture($db);
  64. $replacingInvoice = null;
  65. $societe = new Societe($db);
  66. if (!empty($socid)) {
  67. $societe->fetch($socid);
  68. } else {
  69. $result = $societe->getView('list');
  70. if (!empty($result->rows))
  71. $socid = $result->rows[0]->value->_id;
  72. }
  73. $title = $langs->trans("Bill");
  74. // Load object
  75. if (!empty($id)) {
  76. $object->fetch($id);
  77. $replacingInvoice = $object->getReplacingInvoice();
  78. }
  79. // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array
  80. $hookmanager->initHooks(array('invoicecard'));
  81. if (!empty($_GET['json'])) {
  82. $output = array(
  83. "sEcho" => intval($_GET['sEcho']),
  84. "iTotalRecords" => 0,
  85. "iTotalDisplayRecords" => 0,
  86. "aaData" => array()
  87. );
  88. // $keystart[0] = $user->id;
  89. // $keyend[0] = $user->id;
  90. // $keyend[1] = new stdClass();
  91. /* $params = array('startkey' => array($user->id, mktime(0, 0, 0, date("m") - 1, date("d"), date("Y"))),
  92. 'endkey' => array($user->id, mktime(0, 0, 0, date("m") + 1, date("d"), date("Y")))); */
  93. try {
  94. $result = $object->getView($_GET["json"], array('key' => $id));
  95. } catch (Exception $exc) {
  96. print $exc->getMessage();
  97. }
  98. $iTotal = count($result->rows);
  99. $output["iTotalRecords"] = $iTotal;
  100. $output["iTotalDisplayRecords"] = $iTotal;
  101. $i = 0;
  102. foreach ($result->rows as $aRow) {
  103. $output["aaData"][] = $aRow->value;
  104. }
  105. header('Content-type: application/json');
  106. echo json_encode($output);
  107. exit;
  108. }
  109. /* Actions ****************************************************************** */
  110. if ($action == 'create') {
  111. $title = $langs->trans('NewBill');
  112. } else if ($action == 'add' && $user->rights->facture->creer) {
  113. // If creation from another object of another module (Example: origin=commande, originid=1)
  114. if ($_POST['origin'] && $_POST['originid']) {
  115. // Parse element/subelement (ex: project_task)
  116. $element = $subelement = $_POST['origin'];
  117. if (preg_match('/^([^_]+)_([^_]+)/i', $_POST['origin'], $regs)) {
  118. $element = $regs[1];
  119. $subelement = $regs[2];
  120. }
  121. // For compatibility
  122. if ($element == 'order') {
  123. $element = $subelement = 'commande';
  124. }
  125. if ($element == 'commande') {
  126. $element = 'commande';
  127. $subelement = 'commande';
  128. }
  129. if ($element == 'contract') {
  130. $element = $subelement = 'contrat';
  131. }
  132. $object->origin = $_POST['origin'];
  133. $object->origin_id = $_POST['originid'];
  134. // Possibility to add external linked objects with hooks
  135. // $object->linked_objects[$object->origin] = $object->origin_id;
  136. $object->linked_objects[] = array('type' => $object->origin, 'id' => $object->origin_id);
  137. if (is_array($_POST['other_linked_objects']) && !empty($_POST['other_linked_objects'])) {
  138. $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']);
  139. }
  140. }
  141. // Replacement invoice
  142. if ($_POST['type'] == "INVOICE_REPLACEMENT") {
  143. $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
  144. if (empty($datefacture)) {
  145. $error++;
  146. $mesgs[] = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("Date")) . '</div>';
  147. }
  148. if (empty($_POST['fac_replacement'])) {
  149. $error++;
  150. $mesgs[] = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("ReplaceInvoice")) . '</div>';
  151. }
  152. if (!$error) {
  153. // This is a replacement invoice
  154. $result = $object->fetch($_POST['fac_replacement']);
  155. $object->fetch_thirdparty();
  156. $object->date = $datefacture;
  157. $object->note_public = trim($_POST['note_public']);
  158. $object->note = trim($_POST['note']);
  159. $object->ref_client = $_POST['ref_client'];
  160. $object->ref_int = $_POST['ref_int'];
  161. $object->modelpdf = $_POST['model'];
  162. $object->fk_project = $_POST['projectid'];
  163. $object->cond_reglement_code = $_POST['cond_reglement_code'];
  164. $object->mode_reglement_code = $_POST['mode_reglement_code'];
  165. $object->remise_absolue = $_POST['remise_absolue'];
  166. $object->remise_percent = $_POST['remise_percent'];
  167. // Proprietes particulieres a facture de remplacement
  168. $object->fk_facture_source = $_POST['fac_replacement'];
  169. $object->type = "INVOICE_REPLACEMENT";
  170. $id = $object->createFromCurrent($user);
  171. if (empty($id))
  172. $mesgs[] = $object->error;
  173. }
  174. }
  175. // Credit note invoice
  176. if ($_POST['type'] == "INVOICE_AVOIR") {
  177. if (empty($_POST['fac_avoir'])) {
  178. $error++;
  179. $mesgs[] = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("CorrectInvoice")) . '</div>';
  180. }
  181. $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
  182. if (empty($datefacture)) {
  183. $error++;
  184. $mesgs[] = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("Date")) . '</div>';
  185. }
  186. if (!$error) {
  187. // Si facture avoir
  188. $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
  189. //$result=$object->fetch($_POST['fac_avoir']);
  190. $object->socid = $_POST['socid'];
  191. $object->number = $_POST['facnumber'];
  192. $object->date = $datefacture;
  193. $object->note_public = trim($_POST['note_public']);
  194. $object->note = trim($_POST['note']);
  195. $object->ref_client = $_POST['ref_client'];
  196. $object->ref_int = $_POST['ref_int'];
  197. $object->modelpdf = $_POST['model'];
  198. $object->fk_project = $_POST['projectid'];
  199. $object->cond_reglement_code = null;
  200. $object->mode_reglement_code = $_POST['mode_reglement_code'];
  201. $object->remise_absolue = $_POST['remise_absolue'];
  202. $object->remise_percent = $_POST['remise_percent'];
  203. // Proprietes particulieres a facture avoir
  204. $object->fk_facture_source = $_POST['fac_avoir'];
  205. $object->type = "INVOICE_AVOIR";
  206. $id = $object->create($user);
  207. // Add predefined lines
  208. // for ($i = 1; $i <= $NBLINES; $i++) {
  209. // if ($_POST['idprod' . $i]) {
  210. // $product = new Product($db);
  211. // $product->fetch($_POST['idprod' . $i]);
  212. // $startday = dol_mktime(12, 0, 0, $_POST['date_start' . $i . 'month'], $_POST['date_start' . $i . 'day'], $_POST['date_start' . $i . 'year']);
  213. // $endday = dol_mktime(12, 0, 0, $_POST['date_end' . $i . 'month'], $_POST['date_end' . $i . 'day'], $_POST['date_end' . $i . 'year']);
  214. // $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);
  215. // }
  216. // }
  217. }
  218. }
  219. // Standard or deposit or proforma invoice
  220. if (($_POST['type'] == "INVOICE_STANDARD" || $_POST['type'] == "INVOICE_DEPOSIT" || $_POST['type'] == 4) && $_POST['fac_rec'] <= 0) {
  221. $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
  222. if (empty($datefacture)) {
  223. $error++;
  224. $mesgs[] = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("Date")) . '</div>';
  225. }
  226. if (!$error) {
  227. // Si facture standard
  228. $object->socid = $_POST['socid'];
  229. $object->type = $_POST['type'];
  230. $object->number = $_POST['facnumber'];
  231. $object->date = $datefacture;
  232. $object->note_public = trim($_POST['note_public']);
  233. $object->note = trim($_POST['note']);
  234. $object->ref_client = $_POST['ref_client'];
  235. $object->ref_int = $_POST['ref_int'];
  236. $object->modelpdf = $_POST['model'];
  237. $object->fk_project = $_POST['projectid'];
  238. $object->cond_reglement_code = $_POST["cond_reglement_code"]; //($_POST['type'] == 3?1:$_POST['cond_reglement_id']);
  239. $object->mode_reglement_code = $_POST['mode_reglement_code'];
  240. $object->amount = $_POST['amount'];
  241. $object->remise_absolue = $_POST['remise_absolue'];
  242. $object->remise_percent = $_POST['remise_percent'];
  243. $id = $object->createStandardInvoice($user);
  244. } else
  245. $action = 'create';
  246. }
  247. if (!empty($id)) {
  248. // If creation from an order, copying lines
  249. if (!empty($_POST['origin'])) {
  250. dol_include_once('/' . $element . '/class/' . $subelement . '.class.php');
  251. $classname = ucfirst($subelement);
  252. $srcobject = new $classname($db);
  253. dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines");
  254. $result = $srcobject->fetch($object->origin_id);
  255. if (!empty($result)) {
  256. $lines = $srcobject->lines;
  257. if (empty($lines) && method_exists($srcobject, 'fetch_lines'))
  258. $lines = $srcobject->fetch_lines();
  259. $fk_parent_line = 0;
  260. $num = count($lines);
  261. for ($i = 0; $i < $num; $i++) {
  262. $desc = ($lines[$i]->description ? $lines[$i]->description : $lines[$i]->libelle);
  263. $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0);
  264. // Dates
  265. // TODO mutualiser
  266. $date_start = $lines[$i]->date_debut_prevue;
  267. if ($lines[$i]->date_debut_reel)
  268. $date_start = $lines[$i]->date_debut_reel;
  269. if ($lines[$i]->date_start)
  270. $date_start = $lines[$i]->date_start;
  271. $date_end = $lines[$i]->date_fin_prevue;
  272. if ($lines[$i]->date_fin_reel)
  273. $date_end = $lines[$i]->date_fin_reel;
  274. if ($lines[$i]->date_end)
  275. $date_end = $lines[$i]->date_end;
  276. // Reset fk_parent_line for no child products and special product
  277. if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) {
  278. $fk_parent_line = 0;
  279. }
  280. $result = $object->addline(
  281. $id, $desc, $lines[$i]->subprice, $lines[$i]->qty, $lines[$i]->tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, $datestart, $dateend, 0, $lines[$i]->info_bits, $lines[$i]->fk_remise_except, 'HT', 0, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $fk_parent_line
  282. );
  283. if ($result < 0) {
  284. $error++;
  285. break;
  286. }
  287. // Defined the new fk_parent_line
  288. if ($result > 0 && $lines[$i]->product_type == 9) {
  289. $fk_parent_line = $result;
  290. }
  291. }
  292. // Hooks
  293. $parameters = array('objFrom' => $srcobject);
  294. $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
  295. if ($reshook < 0)
  296. $error++;
  297. }
  298. else {
  299. $mesg = $srcobject->error;
  300. $error++;
  301. }
  302. }
  303. if ($error == 0)
  304. header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id);
  305. exit;
  306. }
  307. }
  308. else if ($action == 'update' && $user->rights->facture->creer) {
  309. $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
  310. $datelimite = dol_mktime(12, 0, 0, $_POST['limonth'], $_POST['liday'], $_POST['liyear']);
  311. if (empty($datefacture)) {
  312. $error++;
  313. $mesgs[] = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("Date")) . '</div>';
  314. }
  315. $object->date = $datefacture;
  316. if (!empty($object->date_lim_reglement))
  317. $object->date_lim_reglement = $datelimite;
  318. $object->cond_reglement_code = GETPOST('cond_reglement_code');
  319. $object->mode_reglement_code = GETPOST('mode_reglement_code');
  320. $res = $object->update($user);
  321. if ($res > 0) {
  322. header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $id);
  323. exit;
  324. }
  325. }
  326. // Add a new line
  327. else if (($action == 'addline' || $action == 'addline_predef') && $user->rights->facture->creer) {
  328. $langs->load('errors');
  329. $error = false;
  330. $idprod = GETPOST('idprod', 'alpha');
  331. $product_desc = (GETPOST('product_desc') ? GETPOST('product_desc') : (GETPOST('np_desc') ? GETPOST('np_desc') : (GETPOST('dp_desc') ? GETPOST('dp_desc') : '')));
  332. $price_ht = GETPOST('price_ht');
  333. $tva_tx = GETPOST('tva_tx');
  334. if ((empty($idprod) || GETPOST('usenewaddlineform')) && ($price_ht < 0) && (GETPOST('qty') < 0)) {
  335. setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors');
  336. $error = true;
  337. }
  338. if (empty($idprod) && GETPOST('type') < 0) {
  339. setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors');
  340. $error = true;
  341. }
  342. if ((empty($idprod) || GETPOST('usenewaddlineform')) && (!($price_ht >= 0) || $price_ht == '')) { // Unit price can be 0 but not ''
  343. setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors');
  344. $error = true;
  345. }
  346. if (!GETPOST('qty') && GETPOST('qty') == '') {
  347. setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors');
  348. $error = true;
  349. }
  350. if (empty($idprod) && empty($product_desc)) {
  351. setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors');
  352. $error = true;
  353. }
  354. if (!$error && (GETPOST('qty') >= 0) && (!empty($product_desc) || !empty($idprod))) {
  355. $ret = $object->fetch_thirdparty();
  356. // Clean parameters
  357. $predef = ((!empty($idprod) && $conf->global->MAIN_FEATURES_LEVEL < 2) ? '_predef' : '');
  358. $date_start = dol_mktime(GETPOST('date_start' . $predef . 'hour'), GETPOST('date_start' . $predef . 'min'), GETPOST('date_start' . $predef . 'sec'), GETPOST('date_start' . $predef . 'month'), GETPOST('date_start' . $predef . 'day'), GETPOST('date_start' . $predef . 'year'));
  359. $date_end = dol_mktime(GETPOST('date_end' . $predef . 'hour'), GETPOST('date_end' . $predef . 'min'), GETPOST('date_end' . $predef . 'sec'), GETPOST('date_end' . $predef . 'month'), GETPOST('date_end' . $predef . 'day'), GETPOST('date_end' . $predef . 'year'));
  360. $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT');
  361. // Define special_code for special lines
  362. $special_code = 0;
  363. //if (empty($_POST['qty'])) $special_code=3; // Options should not exists on invoices
  364. // Ecrase $pu par celui du produit
  365. // Ecrase $desc par celui du produit
  366. // Ecrase $txtva par celui du produit
  367. // Ecrase $base_price_type par celui du produit
  368. if (!empty($idprod)) {
  369. $prod = new Product($db);
  370. $prod->fetch($idprod);
  371. $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : '');
  372. // Update if prices fields are defined
  373. if (GETPOST('usenewaddlineform')) {
  374. $pu_ht = price2num($price_ht, 'MU');
  375. $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
  376. $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
  377. $tva_tx = str_replace('*', '', $tva_tx);
  378. $desc = $product_desc;
  379. } else {
  380. $tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id);
  381. $tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id);
  382. // We define price for product
  383. if (!empty($conf->global->PRODUIT_MULTIPRICES) && !empty($object->thirdparty->price_level)) {
  384. $pu_ht = $prod->multiprices[$object->thirdparty->price_level];
  385. $pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level];
  386. $price_min = $prod->multiprices_min[$object->thirdparty->price_level];
  387. $price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level];
  388. } else {
  389. $pu_ht = $prod->price->price;
  390. $pu_ttc = $prod->price->price_ttc;
  391. $price_min = $prod->price->price_min;
  392. $price_base_type = $prod->price->price_base_type;
  393. }
  394. // On reevalue prix selon taux tva car taux tva transaction peut etre different
  395. // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur).
  396. if ($tva_tx != $prod->tva_tx) {
  397. if ($price_base_type != 'HT') {
  398. $pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU');
  399. } else {
  400. $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU');
  401. }
  402. }
  403. $desc = '';
  404. // Define output language
  405. if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) {
  406. $outputlangs = $langs;
  407. $newlang = '';
  408. if (empty($newlang) && GETPOST('lang_id'))
  409. $newlang = GETPOST('lang_id');
  410. if (empty($newlang))
  411. $newlang = $object->client->default_lang;
  412. if (!empty($newlang)) {
  413. $outputlangs = new Translate();
  414. $outputlangs->setDefaultLang($newlang);
  415. }
  416. $desc = (!empty($prod->multilangs[$outputlangs->defaultlang]["description"])) ? $prod->multilangs[$outputlangs->defaultlang]["description"] : $prod->description;
  417. } else {
  418. $desc = $prod->description;
  419. }
  420. $desc = dol_concatdesc($desc, $product_desc);
  421. }
  422. if (!empty($prod->customcode) || !empty($prod->country_id)) {
  423. $tmptxt = '(';
  424. if (!empty($prod->customcode))
  425. $tmptxt.=$langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode;
  426. if (!empty($prod->customcode) && !empty($prod->country_id))
  427. $tmptxt.=' - ';
  428. if (!empty($prod->country_id))
  429. $tmptxt.=$langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_id, 0, $db, $langs, 0);
  430. $tmptxt.=')';
  431. $desc.= (dol_textishtml($desc) ? "<br>\n" : "\n") . $tmptxt;
  432. }
  433. $type = $prod->type;
  434. }
  435. else {
  436. $pu_ht = price2num($price_ht, 'MU');
  437. $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
  438. $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
  439. $tva_tx = str_replace('*', '', $tva_tx);
  440. $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
  441. $desc = $product_desc;
  442. $type = GETPOST('type');
  443. }
  444. // Margin
  445. $fournprice = (GETPOST('fournprice') ? GETPOST('fournprice') : '');
  446. $buyingprice = (GETPOST('buying_price') ? GETPOST('buying_price') : '');
  447. // Local Taxes
  448. $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty);
  449. $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty);
  450. $info_bits = 0;
  451. if ($tva_npr)
  452. $info_bits |= 0x01;
  453. if (!empty($price_min) && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) {
  454. $mesg = $langs->trans("CantBeLessThanMinPrice", price2num($price_min, 'MU') . $langs->getCurrencySymbol($conf->currency));
  455. setEventMessage($mesg, 'errors');
  456. } else {
  457. // Insert line
  458. $result = $object->addline(
  459. $id, $desc, $pu_ht, GETPOST('qty'), $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, GETPOST('remise_percent'), $date_start, $date_end, 0, $info_bits, '', $price_base_type, $pu_ttc, $type, -1, $special_code, '', 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label
  460. );
  461. if ($result > 0) {
  462. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
  463. // Define output language
  464. $outputlangs = $langs;
  465. $newlang = GETPOST('lang_id', 'alpha');
  466. if (!empty($conf->global->MAIN_MULTILANGS) && empty($newlang))
  467. $newlang = $object->client->default_lang;
  468. if (!empty($newlang)) {
  469. $outputlangs = new Translate();
  470. $outputlangs->setDefaultLang($newlang);
  471. }
  472. $ret = $object->fetch($id); // Reload to get new records
  473. facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
  474. }
  475. unset($_POST['qty']);
  476. unset($_POST['type']);
  477. unset($_POST['idprod']);
  478. unset($_POST['remise_percent']);
  479. unset($_POST['price_ht']);
  480. unset($_POST['price_ttc']);
  481. unset($_POST['tva_tx']);
  482. unset($_POST['product_ref']);
  483. unset($_POST['product_label']);
  484. unset($_POST['product_desc']);
  485. unset($_POST['fournprice']);
  486. unset($_POST['buying_price']);
  487. // old method
  488. unset($_POST['np_desc']);
  489. unset($_POST['dp_desc']);
  490. } else {
  491. setEventMessage($object->error, 'errors');
  492. }
  493. $action = '';
  494. }
  495. }
  496. } else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['save'] == $langs->trans('Save')) {
  497. if (!$object->fetch($id) > 0)
  498. dol_print_error($db);
  499. $object->fetch_thirdparty();
  500. // Clean parameters
  501. $date_start = '';
  502. $date_end = '';
  503. $date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear'));
  504. $date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear'));
  505. $description = dol_htmlcleanlastbr(GETPOST('product_desc'));
  506. $pu_ht = GETPOST('price_ht');
  507. // Define info_bits
  508. $info_bits = 0;
  509. if (preg_match('/\*/', GETPOST('tva_tx')))
  510. $info_bits |= 0x01;
  511. // Define vat_rate
  512. $vat_rate = $_POST['tva_tx'];
  513. $vat_rate = str_replace('*', '', $vat_rate);
  514. $localtax1_rate = get_localtax($vat_rate, 1, $object->client);
  515. $localtax2_rate = get_localtax($vat_rate, 2, $object->client);
  516. // Add buying price
  517. $fournprice = (GETPOST('fournprice') ? GETPOST('fournprice') : '');
  518. $buyingprice = (GETPOST('buying_price') ? GETPOST('buying_price') : '');
  519. // Check minimum price
  520. $productid = GETPOST('productid', 'int');
  521. if (!empty($productid)) {
  522. $product = new Product($db);
  523. $product->fetch($productid);
  524. $type = $product->type;
  525. $price_min = $product->price_min;
  526. if (!empty($conf->global->PRODUIT_MULTIPRICES) && !empty($object->client->price_level))
  527. $price_min = $product->multiprices_min[$object->client->price_level];
  528. $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
  529. if ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) {
  530. setEventMessage($langs->trans("CantBeLessThanMinPrice", price2num($price_min, 'MU')) . $langs->getCurrencySymbol($conf->currency), 'errors');
  531. $error++;
  532. }
  533. } else {
  534. $type = GETPOST('type');
  535. $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
  536. // Check parameters
  537. if (GETPOST('type') < 0) {
  538. setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors');
  539. $error++;
  540. }
  541. }
  542. // Update line
  543. if (!$error) {
  544. $result = $object->updateline(
  545. GETPOST('lineid'), $description, $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $date_start, $date_end, $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label
  546. );
  547. if ($result >= 0) {
  548. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
  549. // Define output language
  550. $outputlangs = $langs;
  551. $newlang = '';
  552. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id'))
  553. $newlang = GETPOST('lang_id');
  554. if ($conf->global->MAIN_MULTILANGS && empty($newlang))
  555. $newlang = $object->client->default_lang;
  556. if (!empty($newlang)) {
  557. $outputlangs = new Translate();
  558. $outputlangs->setDefaultLang($newlang);
  559. }
  560. $ret = $object->fetch($id); // Reload to get new records
  561. facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
  562. }
  563. unset($_POST['qty']);
  564. unset($_POST['type']);
  565. unset($_POST['productid']);
  566. unset($_POST['remise_percent']);
  567. unset($_POST['price_ht']);
  568. unset($_POST['price_ttc']);
  569. unset($_POST['tva_tx']);
  570. unset($_POST['product_ref']);
  571. unset($_POST['product_label']);
  572. unset($_POST['product_desc']);
  573. unset($_POST['fournprice']);
  574. unset($_POST['buying_price']);
  575. } else {
  576. setEventMessage($object->error, 'errors');
  577. }
  578. }
  579. } else if ($action == 'confirm_delete' && $user->rights->facture->supprimer) {
  580. $res = $object->delete();
  581. if ($res > 0) {
  582. header('Location: list.php');
  583. exit;
  584. }
  585. }
  586. // Delete line
  587. else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->facture->creer) {
  588. // $object->fetch($id);
  589. // $object->fetch_thirdparty();
  590. $result = $object->deleteline($_GET['lineid'], $user);
  591. if ($result > 0) {
  592. // Define output language
  593. $outputlangs = $langs;
  594. $newlang = '';
  595. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && !empty($_REQUEST['lang_id']))
  596. $newlang = $_REQUEST['lang_id'];
  597. if ($conf->global->MAIN_MULTILANGS && empty($newlang))
  598. $newlang = $object->client->default_lang;
  599. if (!empty($newlang)) {
  600. $outputlangs = new Translate();
  601. $outputlangs->setDefaultLang($newlang);
  602. }
  603. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
  604. $ret = $object->fetch($id); // Reload to get new records
  605. $result = facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
  606. }
  607. if ($result >= 0) {
  608. header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id);
  609. exit;
  610. }
  611. } else {
  612. $mesgs[] = '<div clas="error">' . $object->error . '</div>';
  613. $action = '';
  614. }
  615. }
  616. // Classify to validated
  617. else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->facture->valider) {
  618. $idwarehouse = GETPOST('idwarehouse');
  619. $object->fetch($id);
  620. $object->fetch_thirdparty();
  621. // Check parameters
  622. if ($object->type != 3 && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1)) {
  623. if (!$idwarehouse || $idwarehouse == -1) {
  624. $error++;
  625. $mesgs[] = $langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse"));
  626. $action = '';
  627. }
  628. }
  629. if (!$error) {
  630. $result = $object->validate($user, '', $idwarehouse);
  631. if ($result >= 0) {
  632. // Define output language
  633. $outputlangs = $langs;
  634. $newlang = '';
  635. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && !empty($_REQUEST['lang_id']))
  636. $newlang = $_REQUEST['lang_id'];
  637. if ($conf->global->MAIN_MULTILANGS && empty($newlang))
  638. $newlang = $object->client->default_lang;
  639. if (!empty($newlang)) {
  640. $outputlangs = new Translate();
  641. $outputlangs->setDefaultLang($newlang);
  642. }
  643. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
  644. $ret = $object->fetch($id); // Reload to get new records
  645. facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
  646. }
  647. } else {
  648. $mesgs[] = '<div class="error">' . $object->error . '</div>';
  649. }
  650. }
  651. }
  652. /*
  653. * Generate document
  654. */ else if ($action == 'builddoc') { // En get ou en post
  655. $object->fetch_thirdparty();
  656. if (GETPOST('model')) {
  657. $object->setDocModel($user, GETPOST('model'));
  658. }
  659. // Define output language
  660. $outputlangs = $langs;
  661. $newlang = '';
  662. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id'))
  663. $newlang = GETPOST('lang_id');
  664. if ($conf->global->MAIN_MULTILANGS && empty($newlang))
  665. $newlang = $object->client->default_lang;
  666. if (!empty($newlang)) {
  667. $outputlangs = new Translate();
  668. $outputlangs->setDefaultLang($newlang);
  669. }
  670. $result = facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
  671. if ($result <= 0) {
  672. dol_print_error($db, $result);
  673. exit;
  674. } else {
  675. header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . (empty($conf->global->MAIN_JUMP_TAG) ? '' : '#builddoc'));
  676. exit;
  677. }
  678. } else if ($action == 'confirm_modif' && ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate)) {
  679. $idwarehouse = GETPOST('idwarehouse');
  680. $object->fetch($id);
  681. $object->fetch_thirdparty();
  682. // Check parameters
  683. if ($object->type != 3 && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1)) {
  684. if (!$idwarehouse || $idwarehouse == -1) {
  685. $error++;
  686. $mesgs[] = $langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse"));
  687. $action = '';
  688. }
  689. }
  690. if (!$error) {
  691. // On verifie si aucun paiement n'a ete effectue
  692. if ($object->getSommePaiement() == 0 && $ventilExportCompta == 0) {
  693. $res = $object->set_draft($user, $idwarehouse);
  694. // Define output language
  695. $outputlangs = $langs;
  696. $newlang = '';
  697. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && !empty($_REQUEST['lang_id']))
  698. $newlang = $_REQUEST['lang_id'];
  699. if ($conf->global->MAIN_MULTILANGS && empty($newlang))
  700. $newlang = $object->client->default_lang;
  701. if (!empty($newlang)) {
  702. $outputlangs = new Translate();
  703. $outputlangs->setDefaultLang($newlang);
  704. }
  705. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
  706. $ret = $object->fetch($id); // Reload to get new records
  707. facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
  708. }
  709. }
  710. }
  711. }
  712. // Classify "abandoned"
  713. else if ($action == 'confirm_canceled' && $confirm == 'yes') {
  714. $object->fetch($id);
  715. $close_code = $_POST["close_code"];
  716. $close_note = $_POST["close_note"];
  717. if ($close_code) {
  718. $result = $object->set_canceled($user, $close_code, $close_note);
  719. } else {
  720. $mesgs[] = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("Reason")) . '</div>';
  721. }
  722. }
  723. // Change status of invoice
  724. else if ($action == 'reopen' && $user->rights->facture->creer) {
  725. $result = $object->fetch($id);
  726. if ($object->Status == "PAID" || $object->Status == "PAID_PARTIALLY" ||  ($object->Status == "CANCELED" && $object->close_code != 'replaced')) {
  727. $result = $object->set_unpaid($user);
  728. if ($result > 0) {
  729. header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id);
  730. exit;
  731. } else {
  732. $mesgs[] = '<div class="error">' . $object->error . '</div>';
  733. }
  734. }
  735. }
  736. // Classify "paid"
  737. else if ($action == 'confirm_paid' && $confirm == 'yes' && $user->rights->facture->paiement) {
  738. $object->fetch($id);
  739. $result = $object->set_paid($user);
  740. }
  741. // Classif "paid partialy"
  742. else if ($action == 'confirm_paid_partially' && $confirm == 'yes' && $user->rights->facture->paiement) {
  743. $object->fetch($id);
  744. $close_code = $_POST["close_code"];
  745. $close_note = $_POST["close_note"];
  746. if ($close_code) {
  747. $result = $object->set_paid($user, $close_code, $close_note);
  748. } else {
  749. $mesgs[] = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("Reason")) . '</div>';
  750. }
  751. }
  752. // Convertir en reduc
  753. else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->facture->creer) {
  754. $object->fetch($id);
  755. $object->fetch_thirdparty();
  756. $object->getLinesArray();
  757. if ($object->Status != "PAID") { // protection against multiple submit
  758. // Boucle sur chaque taux de tva
  759. $i = 0;
  760. foreach ($object->lines as $line) {
  761. $amount_ht[$line->tva_tx]+=$line->total_ht;
  762. $amount_tva[$line->tva_tx]+=$line->total_tva;
  763. $amount_ttc[$line->tva_tx]+=$line->total_ttc;
  764. $i++;
  765. }
  766. // Insert one discount by VAT rate category
  767. $discount = new DiscountAbsolute($db);
  768. if ($object->type == "INVOICE_AVOIR")
  769. $discount->description = '(CREDIT_NOTE)';
  770. elseif ($object->type == "INVOICE_DEPOSIT")
  771. $discount->description = '(DEPOSIT)';
  772. else {
  773. $this->error = "CantConvertToReducAnInvoiceOfThisType";
  774. return -1;
  775. }
  776. $discount->tva_tx = abs($object->total_ttc);
  777. $discount->fk_soc = $object->client->id;
  778. $discount->fk_facture_source = $object->id;
  779. $error = 0;
  780. foreach ($amount_ht as $tva_tx => $xxx) {
  781. $discount->amount_ht = abs($amount_ht[$tva_tx]);
  782. $discount->amount_tva = abs($amount_tva[$tva_tx]);
  783. $discount->amount_ttc = abs($amount_ttc[$tva_tx]);
  784. $discount->tva_tx = abs($tva_tx);
  785. $result = $discount->create($user);
  786. if ($result < 0) {
  787. $error++;
  788. break;
  789. }
  790. }
  791. if (!$error) {
  792. // Classe facture
  793. //$result = $object->set_paid($user);
  794. $object->Status = 'CONVERTED_TO_REDUC';
  795. $object->record();
  796. } else {
  797. $mesgs[] = '<div class="error">' . $discount->error . '</div>';
  798. }
  799. }
  800. } else if ($action == "setabsolutediscount" && $user->rights->facture->creer) {
  801. // POST[remise_id] ou POST[remise_id_for_payment]
  802. if (!empty($_POST["remise_id"])) {
  803. $ret = $object->fetch($id);
  804. if (!empty($ret)) {
  805. $result = $object->insert_discount($_POST["remise_id"]);
  806. if ($result < 0) {
  807. $mesgs[] = '<div class="error">' . $object->error . '</div>';
  808. }
  809. } else {
  810. dol_print_error($db, $object->error);
  811. }
  812. }
  813. if (!empty($_POST["remise_id_for_payment"])) {
  814. require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php';
  815. $discount = new DiscountAbsolute($db);
  816. $discount->fetch($_POST["remise_id_for_payment"]);
  817. $result = $discount->link_to_invoice(0, $id);
  818. if ($result < 0) {
  819. $mesgs[] = '<div class="error">' . $discount->error . '</div>';
  820. }
  821. }
  822. }
  823. /*
  824. * Add file in email form
  825. */
  826. if (GETPOST('addfile')) {
  827. require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
  828. // Set tmp user directory
  829. $vardir = $conf->user->dir_output . "/" . $user->id;
  830. $upload_dir_tmp = $vardir . '/temp';
  831. dol_add_file_process($upload_dir_tmp, 0, 0);
  832. $action = 'presend';
  833. }
  834. /*
  835. * Remove file in email form
  836. */
  837. if (!empty($_POST['removedfile'])) {
  838. require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
  839. // Set tmp user directory
  840. $vardir = $conf->user->dir_output . "/" . $user->id;
  841. $upload_dir_tmp = $vardir . '/temp';
  842. // TODO Delete only files that was uploaded from email form
  843. dol_remove_file_process($_POST['removedfile'], 0);
  844. $action = 'presend';
  845. }
  846. /*
  847. * Send mail
  848. */
  849. if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST['removedfile'] && !$_POST['cancel']) {
  850. $langs->load('mails');
  851. $actiontypecode = '';
  852. $subject = '';
  853. $actionmsg = '';
  854. $actionmsg2 = '';
  855. $result = $object->fetch($id);
  856. $result = $object->fetch_thirdparty();
  857. if ($result > 0) {
  858. // $ref = dol_sanitizeFileName($object->ref);
  859. // $file = $conf->facture->dir_output . '/' . $ref . '/' . $ref . '.pdf';
  860. // if (is_readable($file))
  861. // {
  862. if ($_POST['sendto']) {
  863. // Le destinataire a ete fourni via le champ libre
  864. $sendto = $_POST['sendto'];
  865. $sendtoid = 0;
  866. } elseif ($_POST['receiver'] != '-1') {
  867. // Recipient was provided from combo list
  868. if ($_POST['receiver'] == 'thirdparty') { // Id of third party
  869. $sendto = $object->client->email;
  870. $sendtoid = 0;
  871. } else { // Id du contact
  872. $sendto = $object->client->contact_get_property($_POST['receiver'], 'email');
  873. $sendtoid = $_POST['receiver'];
  874. }
  875. }
  876. if (dol_strlen($sendto)) {
  877. $langs->load("commercial");
  878. $from = $_POST['fromname'] . ' <' . $_POST['frommail'] . '>';
  879. $replyto = $_POST['replytoname'] . ' <' . $_POST['replytomail'] . '>';
  880. $message = $_POST['message'];
  881. $sendtocc = $_POST['sendtocc'];
  882. $deliveryreceipt = $_POST['deliveryreceipt'];
  883. if ($action == 'send') {
  884. if (dol_strlen($_POST['subject']))
  885. $subject = $_POST['subject'];
  886. else
  887. $subject = $langs->transnoentities('Bill') . ' ' . $object->ref;
  888. $actiontypecode = 'AC_FAC';
  889. $actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto . ".\n";
  890. if ($message) {
  891. $actionmsg.=$langs->transnoentities('MailTopic') . ": " . $subject . "\n";
  892. $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody') . ":\n";
  893. $actionmsg.=$message;
  894. }
  895. //$actionmsg2=$langs->transnoentities('Action'.$actiontypecode);
  896. }
  897. if ($action == 'relance') {
  898. if (dol_strlen($_POST['subject']))
  899. $subject = $_POST['subject'];
  900. else
  901. $subject = $langs->transnoentities('Relance facture ' . $object->ref);
  902. $actiontypecode = 'AC_FAC';
  903. $actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto . ".\n";
  904. if ($message) {
  905. $actionmsg.=$langs->transnoentities('MailTopic') . ": " . $subject . "\n";
  906. $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody') . ":\n";
  907. $actionmsg.=$message;
  908. }
  909. //$actionmsg2=$langs->transnoentities('Action'.$actiontypecode);
  910. }
  911. // Create form object
  912. include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php';
  913. $formmail = new FormMail($db);
  914. $attachedfiles = $formmail->get_attached_files();
  915. $filepath = $attachedfiles['paths'];
  916. $filename = $attachedfiles['names'];
  917. $mimetype = $attachedfiles['mimes'];
  918. // Send mail
  919. require_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
  920. $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1);
  921. if ($mailfile->error) {
  922. $mesgs[] = '<div class="error">' . $mailfile->error . '</div>';
  923. } else {
  924. $result = $mailfile->sendfile();
  925. if ($result) {
  926. $error = 0;
  927. // Initialisation donnees
  928. $object->sendtoid = $sendtoid;
  929. $object->actiontypecode = $actiontypecode;
  930. $object->actionmsg = $actionmsg; // Long text
  931. $object->actionmsg2 = $actionmsg2; // Short text
  932. $object->fk_element = $object->id;
  933. $object->elementtype = $object->element;
  934. // Appel des triggers
  935. include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
  936. $interface = new Interfaces($db);
  937. $result = $interface->run_triggers('BILL_SENTBYMAIL', $object, $user, $langs, $conf);
  938. if ($result < 0) {
  939. $error++;
  940. $this->errors = $interface->errors;
  941. }
  942. // Fin appel triggers
  943. if ($error) {
  944. dol_print_error($db);
  945. } else {
  946. // Redirect here
  947. // This avoid sending mail twice if going out and then back to page
  948. $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($from, 2), $mailfile->getValidAddress($sendto, 2));
  949. setEventMessage($mesg);
  950. header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id);
  951. exit;
  952. }
  953. } else {
  954. $langs->load("other");
  955. $mesg = '<div class="error">';
  956. if ($mailfile->error) {
  957. $mesg.=$langs->trans('ErrorFailedToSendMail', $from, $sendto);
  958. $mesg.='<br>' . $mailfile->error;
  959. } else {
  960. $mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS';
  961. }
  962. $mesg.='</div>';
  963. $mesgs[] = $mesg;
  964. }
  965. }
  966. /* }
  967. else
  968. {
  969. $langs->load("other");
  970. $mesgs[]='<div class="error">'.$langs->trans('ErrorMailRecipientIsEmpty').'</div>';
  971. dol_syslog('Recipient email is empty');
  972. } */
  973. } else {
  974. $langs->load("errors");
  975. $mesgs[] = '<div class="error">' . $langs->trans('ErrorCantReadFile', $file) . '</div>';
  976. dol_syslog('Failed to read file: ' . $file);
  977. }
  978. } else {
  979. $langs->load("other");
  980. $mesgs[] = '<div class="error">' . $langs->trans('ErrorFailedToReadEntity', $langs->trans("Invoice")) . '</div>';
  981. dol_syslog('Impossible de lire les donnees de la facture. Le fichier facture n\'a peut-etre pas ete genere.');
  982. }
  983. $action = 'presend';
  984. }
  985. /* View ********************************************************************* */
  986. $form = new Form($db);
  987. $htmlother = new FormOther($db);
  988. $formfile = new FormFile($db);
  989. $bankaccountstatic = new Account($db);
  990. $now = dol_now();
  991. llxHeader('', $langs->trans('Bill'), 'EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes');
  992. print_fiche_titre($title);
  993. $formconfirm = '';
  994. // Confirmation to delete invoice
  995. if ($action == 'delete') {
  996. $text = $langs->trans('ConfirmDeleteBill');
  997. $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $object->id, $langs->trans('DeleteBill'), $text, 'confirm_delete', '', 0, 1);
  998. }
  999. // Confirmation de la suppression d'une ligne produit
  1000. if ($action == 'ask_deleteline') {
  1001. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?facid=' . $object->id . '&lineid=' . $lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1);
  1002. }
  1003. // Confirmation de la validation
  1004. if ($action == 'valid') {
  1005. $text = $langs->trans('ConfirmValidateBill', $numref);
  1006. if (!empty($conf->notification->enabled)) {
  1007. require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php';
  1008. $notify = new Notify($db);
  1009. $text.='<br>';
  1010. $text.=$notify->confirmMessage('NOTIFY_VAL_FAC', $object->socid);
  1011. }
  1012. $formq

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