PageRenderTime 28ms CodeModel.GetById 16ms 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
  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. $formquestion = array();
  1013. if ($object->type != 3 && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1)) {
  1014. $langs->load("stocks");
  1015. require_once DOL_DOCUMENT_ROOT . '/product/class/html.formproduct.class.php';
  1016. $formproduct = new FormProduct($db);
  1017. $label = $object->type == 2 ? $langs->trans("SelectWarehouseForStockIncrease") : $langs->trans("SelectWarehouseForStockDecrease");
  1018. $formquestion = array(
  1019. //'text' => $langs->trans("ConfirmClone"),
  1020. //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
  1021. //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
  1022. array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'), 'idwarehouse', '', 1)));
  1023. }
  1024. if ($object->type != 2 && $object->total_ttc < 0) { // Can happen only if $conf->global->FACTURE_ENABLE_NEGATIVE is on
  1025. $text.='<br>' . img_warning() . ' ' . $langs->trans("ErrorInvoiceOfThisTypeMustBePositive");
  1026. }
  1027. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('ValidateBill'), $text, 'confirm_valid', $formquestion, (($object->type != 2 && $object->total_ttc < 0) ? "no" : "yes"), ($conf->notification->enabled ? 0 : 2));
  1028. }
  1029. // Confirm back to draft status
  1030. if ($action == 'modif') {
  1031. $text = $langs->trans('ConfirmUnvalidateBill', $object->ref);
  1032. $formquestion = array();
  1033. if ($object->type != 3 && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1)) {
  1034. $langs->load("stocks");
  1035. require_once DOL_DOCUMENT_ROOT . '/product/class/html.formproduct.class.php';
  1036. $formproduct = new FormProduct($db);
  1037. $label = $object->type == 2 ? $langs->trans("SelectWarehouseForStockDecrease") : $langs->trans("SelectWarehouseForStockIncrease");
  1038. $formquestion = array(
  1039. //'text' => $langs->trans("ConfirmClone"),
  1040. //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
  1041. //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
  1042. array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'), 'idwarehouse', '', 1)));
  1043. }
  1044. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('UnvalidateBill'), $text, 'confirm_modif', $formquestion, "yes", 1);
  1045. }
  1046. // Confirmation du classement abandonne
  1047. if ($action == 'canceled') {
  1048. // S'il y a une facture de remplacement pas encore validee (etat brouillon),
  1049. // on ne permet pas de classer abandonner la facture.
  1050. if ($objectidnext) {
  1051. $facturereplacement = new Facture($db);
  1052. $facturereplacement->fetch($objectidnext);
  1053. $statusreplacement = $facturereplacement->statut;
  1054. }
  1055. if ($objectidnext && $statusreplacement == 0) {
  1056. print '<div class="error">' . $langs->trans("ErrorCantCancelIfReplacementInvoiceNotValidated") . '</div>';
  1057. } else {
  1058. // Code
  1059. $close[1]['code'] = 'badcustomer';
  1060. $close[2]['code'] = 'abandon';
  1061. // Help
  1062. $close[1]['label'] = $langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");
  1063. $close[2]['label'] = $langs->trans("ConfirmClassifyAbandonReasonOtherDesc");
  1064. // Texte
  1065. $close[1]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer", $object->ref), $close[1]['label'], 1);
  1066. $close[2]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"), $close[2]['label'], 1);
  1067. // arrayreasons
  1068. $arrayreasons[$close[1]['code']] = $close[1]['reason'];
  1069. $arrayreasons[$close[2]['code']] = $close[2]['reason'];
  1070. // Cree un tableau formulaire
  1071. $formquestion = array(
  1072. 'text' => $langs->trans("ConfirmCancelBillQuestion"),
  1073. array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons),
  1074. array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100')
  1075. );
  1076. $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $langs->trans('CancelBill'), $langs->trans('ConfirmCancelBill', $object->ref), 'confirm_canceled', $formquestion, "yes");
  1077. }
  1078. }
  1079. // Confirmation du classement paye
  1080. $resteapayer = $object->total_ttc - $object->getSommePaiement();
  1081. if ($action == 'paid' && $resteapayer <= 0) {
  1082. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?facid=' . $object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidBill', $object->ref), 'confirm_paid', '', "yes", 1);
  1083. }
  1084. if ($action == 'paid' && $resteapayer > 0) {
  1085. // Code
  1086. $i = 0;
  1087. $close[$i]['code'] = 'discount_vat';
  1088. $i++;
  1089. $close[$i]['code'] = 'badcustomer';
  1090. $i++;
  1091. // Help
  1092. $i = 0;
  1093. $close[$i]['label'] = $langs->trans("HelpEscompte") . '<br><br>' . $langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");
  1094. $i++;
  1095. $close[$i]['label'] = $langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");
  1096. $i++;
  1097. // Texte
  1098. $i = 0;
  1099. $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscountVat", $resteapayer, $langs->trans("Currency" . $conf->currency)), $close[$i]['label'], 1);
  1100. $i++;
  1101. $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer", $resteapayer, $langs->trans("Currency" . $conf->currency)), $close[$i]['label'], 1);
  1102. $i++;
  1103. // arrayreasons[code]=reason
  1104. foreach ($close as $key => $val) {
  1105. $arrayreasons[$close[$key]['code']] = $close[$key]['reason'];
  1106. }
  1107. // Cree un tableau formulaire
  1108. $formquestion = array(
  1109. 'text' => $langs->trans("ConfirmClassifyPaidPartiallyQuestion"),
  1110. array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons),
  1111. array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100')
  1112. );
  1113. // Paiement incomplet. On demande si motif = escompte ou autre
  1114. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?facid=' . $object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidPartially', $object->ref), 'confirm_paid_partially', $formquestion, "yes");
  1115. }
  1116. // Confirmation de la conversion de l'avoir en reduc
  1117. if ($action == 'converttoreduc') {
  1118. $text = $langs->trans('ConfirmConvertToReduc');
  1119. $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $object->id, $langs->trans('ConvertToReduc'), $text, 'confirm_converttoreduc', '', "yes", 2);
  1120. }
  1121. print $formconfirm;
  1122. print '<div class="with-padding" >';
  1123. print '<div class="columns" >';
  1124. // CREATE INVOICE VIEW
  1125. if ($action == 'create' && $user->rights->facture->creer) {
  1126. print '<script type="text/javascript" >
  1127. $(document).ready(function(){
  1128. $("#socid").change(function(){
  1129. window.location = "' . $_SERVER['PHP_SELF'] . '?action=create&socid=" + $(this).val();
  1130. });
  1131. });
  1132. </script>';
  1133. if (GETPOST('origin') && GETPOST('originid')) {
  1134. // Parse element/subelement (ex: project_task)
  1135. $element = $subelement = GETPOST('origin');
  1136. if (preg_match('/^([^_]+)_([^_]+)/i', GETPOST('origin'), $regs)) {
  1137. $element = $regs[1];
  1138. $subelement = $regs[2];
  1139. }
  1140. if ($element == 'project') {
  1141. $projectid = GETPOST('originid');
  1142. } else {
  1143. // For compatibility
  1144. if ($element == 'order' || $element == 'commande') {
  1145. $element = $subelement = 'commande';
  1146. }
  1147. if ($element == 'propal') {
  1148. $element = 'comm/propal';
  1149. $subelement = 'propal';
  1150. }
  1151. if ($element == 'contract') {
  1152. $element = $subelement = 'contrat';
  1153. }
  1154. if ($element == 'shipping') {
  1155. $element = $subelement = 'expedition';
  1156. }
  1157. dol_include_once('/' . $element . '/class/' . $subelement . '.class.php');
  1158. $classname = ucfirst($subelement);
  1159. $objectsrc = new $classname($db);
  1160. $objectsrc->fetch(GETPOST('originid'));
  1161. if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines'))
  1162. $objectsrc->fetch_lines();
  1163. $objectsrc->fetch_thirdparty();
  1164. $projectid = (!empty($objectsrc->fk_project) ? $objectsrc->fk_project : '');
  1165. $ref_client = (!empty($objectsrc->ref_client) ? $objectsrc->ref_client : '');
  1166. $ref_int = (!empty($objectsrc->ref_int) ? $objectsrc->ref_int : '');
  1167. $soc = $objectsrc->client;
  1168. $cond_reglement_code = (!empty($objectsrc->cond_reglement_code) ? $objectsrc->cond_reglement_code : (!empty($soc->cond_reglement_code) ? $soc->cond_reglement_code : 'RECEP'));
  1169. $mode_reglement_code = (!empty($objectsrc->mode_reglement_code) ? $objectsrc->mode_reglement_code : (!empty($soc->mode_reglement_code) ? $soc->mode_reglement_code : 'TIP'));
  1170. $remise_percent = (!empty($objectsrc->remise_percent) ? $objectsrc->remise_percent : (!empty($soc->remise_percent) ? $soc->remise_percent : 0));
  1171. $remise_absolue = (!empty($objectsrc->remise_absolue) ? $objectsrc->remise_absolue : (!empty($soc->remise_absolue) ? $soc->remise_absolue : 0));
  1172. $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE) ? -1 : 0;
  1173. }
  1174. }
  1175. print start_box($title, "twelve", $object->fk_extrafields->ico, false);
  1176. print '<form id="form-add" name="add" action="' . $_SERVER["PHP_SELF"] . '?action=add" method="POST">';
  1177. print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
  1178. print '<input type="hidden" name="action" value="add">';
  1179. print '<input name="facnumber" type="hidden" value="provisoire">';
  1180. print '<input type="hidden" name="origin" value="' . GETPOST('origin') . '">';
  1181. print '<input type="hidden" name="originid" value="' . GETPOST('originid') . '">';
  1182. print '<table class="border" width="100%">';
  1183. // Ref
  1184. print '<tr><td class="fieldrequired">' . $langs->trans('Ref') . '</td><td colspan="2">' . $langs->trans('Draft') . '</td></tr>';
  1185. // Tiers
  1186. print '<tr><td class="fieldrequired">' . $langs->trans('Customer') . '</td><td colspan="2">';
  1187. print $form->select_company($socid, "socid");
  1188. print '</td>';
  1189. print '</tr>' . "\n";
  1190. // Reference client
  1191. print '<tr><td>' . $langs->trans('RefCustomer') . '</td><td colspan="2">';
  1192. print '<input type="text" name="ref_client" value="' . $ref_client . '"></td>';
  1193. print '</tr>';
  1194. // Type de facture
  1195. print '<tr><td valign="top" class="fieldrequired">' . $langs->trans('Type') . '</td><td colspan="2">';
  1196. print '<table class="nobordernopadding">' . "\n";
  1197. // Standard invoice
  1198. print '<tr height="18"><td width="16px" valign="middle">';
  1199. print '<input type="radio" name="type" value="INVOICE_STANDARD" checked="checked" >';
  1200. print '</td><td valign="middle">';
  1201. $desc = $form->textwithpicto($langs->trans("InvoiceStandardAsk"), $langs->transnoentities("InvoiceStandardDesc"), 1);
  1202. print $desc;
  1203. print '</td></tr>' . "\n";
  1204. // Deposit
  1205. // print '<tr height="18"><td width="16px" valign="middle">';
  1206. // print '<input type="radio" name="type" value="INVOICE_DEPOSIT"' . (GETPOST('type') == "INVOICE_DEPOSIT" ? ' checked="checked"' : '') . '>';
  1207. // print '</td><td valign="middle">';
  1208. // $desc = $form->textwithpicto($langs->trans("InvoiceDeposit"), $langs->transnoentities("InvoiceDepositDesc"), 1);
  1209. // print $desc;
  1210. // print '</td></tr>' . "\n";
  1211. //
  1212. // // Proforma
  1213. // if (!empty($conf->global->FACTURE_USE_PROFORMAT)) {
  1214. // print '<tr height="18"><td width="16px" valign="middle">';
  1215. // print '<input type="radio" name="type" value="4"' . (GETPOST('type') == 4 ? ' checked="checked"' : '') . '>';
  1216. // print '</td><td valign="middle">';
  1217. // $desc = $form->textwithpicto($langs->trans("InvoiceProForma"), $langs->transnoentities("InvoiceProFormaDesc"), 1);
  1218. // print $desc;
  1219. // print '</td></tr>' . "\n";
  1220. // }
  1221. //
  1222. // // Replacement
  1223. // $options = $object->selectReplaceableInvoiceOptions($socid);
  1224. // print '<tr height="18"><td valign="middle">';
  1225. // print '<input type="radio" id="fac_replacement_radio" name="type" value="INVOICE_REPLACEMENT"' . (GETPOST('type') == "INVOICE_REPLACEMENT" ? ' checked="checked"' : '');
  1226. // if (!$options)
  1227. // print ' disabled="disabled"';
  1228. // print '>';
  1229. // print '</td><td valign="middle">';
  1230. // $text = $langs->trans("InvoiceReplacementAsk") . ' ';
  1231. // $text.='<select class="flat" name="fac_replacement" id="fac_replacement"';
  1232. // if (!$options)
  1233. // $text.=' disabled="disabled"';
  1234. // $text.='>';
  1235. // if ($options) {
  1236. // $text.='<option value="-1"></option>';
  1237. // $text.=$options;
  1238. // } else {
  1239. // $text.='<option value="-1">' . $langs->trans("NoReplacableInvoice") . '</option>';
  1240. // }
  1241. // $text.='</select>';
  1242. // $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceReplacementDesc"), 1);
  1243. // print $desc;
  1244. // print '</td></tr>' . "\n";
  1245. // Credit note
  1246. $optionsav = $object->selectAvoirableInvoiceOptions($socid);
  1247. print '<tr height="18"><td valign="middle">';
  1248. print '<input type="radio" name="type" value="INVOICE_AVOIR"' . (GETPOST('type') == "INVOICE_AVOIR" ? ' checked=true' : '');
  1249. if (!$optionsav)
  1250. print ' disabled="disabled"';
  1251. print '>';
  1252. print '</td><td valign="middle">';
  1253. $text = $langs->transnoentities("InvoiceAvoirAsk") . ' ';
  1254. // $text.='<input type="text" value="">';
  1255. $text.='<select class="flat" name="fac_avoir" id="fac_avoir"';
  1256. if (!$optionsav)
  1257. $text.=' disabled="disabled"';
  1258. $text.='>';
  1259. if ($optionsav) {
  1260. $text.='<option value="-1"></option>';
  1261. $text.=$optionsav;
  1262. } else {
  1263. $text.='<option value="-1">' . $langs->trans("NoInvoiceToCorrect") . '</option>';
  1264. }
  1265. $text.='</select>';
  1266. $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1);
  1267. print $desc;
  1268. print '</td></tr>' . "\n";
  1269. print '</table>';
  1270. print '</td></tr>';
  1271. // Date invoice
  1272. print '<tr><td class="fieldrequired">' . $langs->trans('Date') . '</td><td colspan="2">';
  1273. $form->select_date($dateinvoice, '', '', '', '', "add", 1, 1);
  1274. print '</td></tr>';
  1275. // Payment term
  1276. print '<tr><td nowrap>' . $langs->trans('PaymentConditionsShort') . '</td><td colspan="2">';
  1277. // $form->select_conditions_paiements(isset($_POST['cond_reglement_id'])?$_POST['cond_reglement_id']:$cond_reglement_id,'cond_reglement_id');
  1278. print $object->select_fk_extrafields('mode_reglement_code', 'mode_reglement_code', $mode_reglement_code);
  1279. print '</td></tr>';
  1280. // Payment mode
  1281. print '<tr><td>' . $langs->trans('PaymentMode') . '</td><td colspan="2">';
  1282. // $form->select_types_paiements(isset($_POST['mode_reglement_id'])?$_POST['mode_reglement_id']:$mode_reglement_id,'mode_reglement_id');
  1283. print $object->select_fk_extrafields('cond_reglement_code', 'cond_reglement_code', $cond_reglement_code);
  1284. print '</td></tr>';
  1285. // Project
  1286. if (!empty($conf->projet->enabled)) {
  1287. $langs->load('projects');
  1288. print '<tr><td>' . $langs->trans('Project') . '</td><td colspan="2">';
  1289. select_projects($soc->id, $projectid, 'projectid');
  1290. print '</td></tr>';
  1291. }
  1292. // Other attributes
  1293. $parameters = array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"');
  1294. $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
  1295. if (empty($reshook) && !empty($extrafields->attribute_label)) {
  1296. foreach ($extrafields->attribute_label as $key => $label) {
  1297. $value = (isset($_POST["options_" . $key]) ? $_POST["options_" . $key] : $object->array_options["options_" . $key]);
  1298. print '<tr><td>' . $label . '</td><td colspan="3">';
  1299. print $extrafields->showInputField($key, $value);
  1300. print '</td></tr>' . "\n";
  1301. }
  1302. }
  1303. // Modele PDF
  1304. print '<tr><td>' . $langs->trans('Model') . '</td>';
  1305. print '<td>';
  1306. include_once DOL_DOCUMENT_ROOT . '/facture/core/modules/facture/modules_facture.php';
  1307. $liste = ModelePDFFactures::liste_modeles($db);
  1308. print $form->selectarray('model', $liste, $conf->global->FACTURE_ADDON_PDF);
  1309. print "</td></tr>";
  1310. // Public note
  1311. print '<tr>';
  1312. print '<td class="border" valign="top">' . $langs->trans('NotePublic') . '</td>';
  1313. print '<td valign="top" colspan="2">';
  1314. print '<textarea name="note_public" wrap="soft" cols="70" rows="' . ROWS_3 . '">';
  1315. if (is_object($objectsrc)) { // Take value from source object
  1316. print $objectsrc->note_public;
  1317. }
  1318. print '</textarea></td></tr>';
  1319. // Private note
  1320. if (empty($user->societe_id)) {
  1321. print '<tr>';
  1322. print '<td class="border" valign="top">' . $langs->trans('NotePrivate') . '</td>';
  1323. print '<td valign="top" colspan="2">';
  1324. print '<textarea name="note" wrap="soft" cols="70" rows="' . ROWS_3 . '">';
  1325. if (!empty($origin) && !empty($originid) && is_object($objectsrc)) { // Take value from source object
  1326. print $objectsrc->note;
  1327. }
  1328. print '</textarea></td></tr>';
  1329. }
  1330. if (is_object($objectsrc)) {
  1331. // TODO for compatibility
  1332. if ($_GET['origin'] == 'contrat') {
  1333. // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva
  1334. $objectsrc->remise_absolue = $remise_absolue;
  1335. $objectsrc->remise_percent = $remise_percent;
  1336. $objectsrc->update_price(1, -1, 1);
  1337. }
  1338. print "\n<!-- " . $classname . " info -->";
  1339. print "\n";
  1340. print '<input type="hidden" name="amount" value="' . $objectsrc->total_ht . '">' . "\n";
  1341. print '<input type="hidden" name="total" value="' . $objectsrc->total_ttc . '">' . "\n";
  1342. print '<input type="hidden" name="tva" value="' . $objectsrc->total_tva . '">' . "\n";
  1343. print '<input type="hidden" name="origin" value="' . $objectsrc->element . '">';
  1344. print '<input type="hidden" name="originid" value="' . $objectsrc->id . '">';
  1345. $newclassname = $classname;
  1346. if ($newclassname == 'Propal')
  1347. $newclassname = 'CommercialProposal';
  1348. print '<tr><td>' . $langs->trans($newclassname) . '</td><td colspan="2">' . $objectsrc->getNomUrl(1) . '</td></tr>';
  1349. print '<tr><td>' . $langs->trans('TotalHT') . '</td><td colspan="2">' . price($objectsrc->total_ht) . '</td></tr>';
  1350. print '<tr><td>' . $langs->trans('TotalVAT') . '</td><td colspan="2">' . price($objectsrc->total_tva) . "</td></tr>";
  1351. if ($mysoc->pays_code == 'ES') {
  1352. if ($mysoc->localtax1_assuj == "1") { //Localtax1 RE
  1353. print '<tr><td>' . $langs->transcountry("AmountLT1", $mysoc->pays_code) . '</td><td colspan="2">' . price($objectsrc->total_localtax1) . "</td></tr>";
  1354. }
  1355. if ($mysoc->localtax2_assuj == "1") { //Localtax2 IRPF
  1356. print '<tr><td>' . $langs->transcountry("AmountLT2", $mysoc->pays_code) . '</td><td colspan="2">' . price($objectsrc->total_localtax2) . "</td></tr>";
  1357. }
  1358. }
  1359. print '<tr><td>' . $langs->trans('TotalTTC') . '</td><td colspan="2">' . price($objectsrc->total_ttc) . "</td></tr>";
  1360. }
  1361. print '</table>';
  1362. // Button "Create Draft"
  1363. print '<br><center><input type="submit" id="submit-form-add" class="button" name="bouton" value="' . $langs->trans('CreateDraft') . '"></center>';
  1364. print "</form>\n";
  1365. print end_box();
  1366. }
  1367. // DETAILS INVOICE
  1368. else {
  1369. /*
  1370. * Boutons actions
  1371. */
  1372. if ($action != 'presend') {
  1373. if ($user->societe_id == 0 && $action <> 'editline') {
  1374. print '<div class="tabsAction">';
  1375. $totalpaye = $object->getSommePaiement();
  1376. $resteapayer = $object->total_ttc - $totalpaye;
  1377. // Editer une facture deja validee, sans paiement effectue et pas exporte en compta
  1378. // if ($object->Status == "NOT_PAID") {
  1379. // // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees
  1380. // $ventilExportCompta = $object->getVentilExportCompta();
  1381. //
  1382. // if ($resteapayer == $object->total_ttc && $ventilExportCompta == 0) {
  1383. // if (!$objectidnext) {
  1384. // if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate) {
  1385. // print '<p class="button-height right">';
  1386. // print '<a class="button icon-pencil" href="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&amp;action=modif">' . $langs->trans('Modify') . '</a>';
  1387. // print "</p>";
  1388. // } else {
  1389. // print '<span class="butActionRefused" title="' . $langs->trans("NotEnoughPermissions") . '">' . $langs->trans('Modify') . '</span>';
  1390. // }
  1391. // } else {
  1392. // print '<span class="butActionRefused" title="' . $langs->trans("DisabledBecauseReplacedInvoice") . '">' . $langs->trans('Modify') . '</span>';
  1393. // }
  1394. // }
  1395. // }
  1396. // Reverse back money or convert to reduction
  1397. if ($object->type == "INVOICE_DEPOSIT" || $object->type == "INVOICE_AVOIR") {
  1398. // For credit note only
  1399. if ($object->type == "INVOICE_AVOIR" && $object->Status != "CONVERTED_TO_REDUC" && $object->getSommePaiement() == 0 && $user->rights->facture->paiement) {
  1400. print '<p class="button-height right">';
  1401. print '<a class="button" href="/compta/paiement.php?id=' . $object->id . '&amp;action=create">' . $langs->trans('DoPaymentBack') . '</a>';
  1402. print '</p>';
  1403. }
  1404. // For credit note
  1405. if ($object->type == "INVOICE_AVOIR" && $object->Status != "CONVERTED_TO_REDUC" && $object->getSommePaiement() == 0 && $user->rights->facture->creer) {
  1406. print '<p class="button-height right">';
  1407. print '<a class="button" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=converttoreduc">' . $langs->trans('ConvertToReduc') . '</a>';
  1408. print '</p>';
  1409. }
  1410. // For deposit invoice
  1411. if ($object->type == "INVOICE_DEPOSIT" /* && $object->Status == "STARTED" */ && $resteapayer == 0 && $user->rights->facture->creer) {
  1412. print '<p class="button-height right">';
  1413. print '<a class="button" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=converttoreduc">' . $langs->trans('ConvertToReduc') . '</a>';
  1414. print '</p>';
  1415. }
  1416. }
  1417. // Classify paid (if not deposit and not credit note. Such invoice are "converted")
  1418. // if ($object->Status == "STARTED" && $user->rights->facture->paiement &&
  1419. // (($object->type != "INVOICE_DEPOSIT" && $object->type != 3 && $resteapayer <= 0) || ($object->type == 2 && $resteapayer >= 0))) {
  1420. // print '<p class="button-height right">';
  1421. // print '<a class="button" href="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&amp;action=paid">' . $langs->trans('ClassifyPaid') . '</a>';
  1422. // print "</p>";
  1423. // }
  1424. // Classify 'closed not completely paid' (possible si validee et pas encore classee payee)
  1425. // if ($object->Status == "STARTED" && $resteapayer > 0
  1426. // && $user->rights->facture->paiement) {
  1427. // if ($totalpaye > 0 || $totalcreditnotes > 0) {
  1428. // // If one payment or one credit note was linked to this invoice
  1429. // print '<p class="button-height right">';
  1430. // print '<a class="button" href="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&amp;action=paid">' . $langs->trans('ClassifyPaidPartially') . '</a>';
  1431. // print "</p>";
  1432. // } else {
  1433. // if ($objectidnext) {
  1434. // print '<span class="butActionRefused" title="' . $langs->trans("DisabledBecauseReplacedInvoice") . '">' . $langs->trans('ClassifyCanceled') . '</span>';
  1435. // } else {
  1436. // print '<p class="button-height right">';
  1437. // print '<a class="button" href="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&amp;action=canceled">' . $langs->trans('ClassifyCanceled') . '</a>';
  1438. // print "</p>";
  1439. // }
  1440. // }
  1441. // }
  1442. // Delete invoice
  1443. if ($user->rights->facture->supprimer) {
  1444. if ($numshipping == 0) {
  1445. print '<p class="button-height right">';
  1446. print '<a class="button icon-cross" href="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=delete">' . $langs->trans("Delete") . '</a>';
  1447. print "</p>";
  1448. } else {
  1449. print '<a class="butActionRefused" href="#" title="' . $langs->trans("ShippingExist") . '">' . $langs->trans("Delete") . '</a>';
  1450. }
  1451. }
  1452. // Clone
  1453. // if (($object->type == "INVOICE_STANDARD" || $object->type == "INVOICE_DEPOSIT" || $object->type == 4) && $user->rights->facture->creer) {
  1454. // print '<p class="button-height right">';
  1455. // print '<a class="button icon-pages" href="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&amp;action=clone&amp;object=invoice">' . $langs->trans("ToClone") . '</a>';
  1456. // print "</p>";
  1457. // }
  1458. // Clone as predefined
  1459. // if (($object->type == "INVOICE_STANDARD" || $object->type == "INVOICE_DEPOSIT" || $object->type == 4) && $object->Status != "PAID" && $object->Status != "NOT_PAID" && $object->Status != "STARTED" && $object->Status != "CANCELED" && $object->Status != "PAID_PARTIALLY" && $user->rights->facture->creer) {
  1460. // if (!$objectidnext) {
  1461. // print '<p class="button-height right">';
  1462. // print '<a class="button icon-page" href="facture/fiche-rec.php?id=' . $object->id . '&amp;action=create">' . $langs->trans("ChangeIntoRepeatableInvoice") . '</a>';
  1463. // print "</p>";
  1464. // }
  1465. // }
  1466. // Reopen a standard paid invoice
  1467. // if (($object->type == "INVOICE_STANDARD" || $object->type == "INVOICE_REPLACEMENT") && ($object->Status == "CANCELED" || $object->Status == "PAID" || $object->Status == "PAID_PARTIALLY")) { // A paid invoice (partially or completely)
  1468. // if (!$objectidnext && $object->close_code != 'replaced') { // Not replaced by another invoice
  1469. // print '<p class="button-height right">';
  1470. // print '<a class="button icon-reply" href="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&amp;action=reopen">' . $langs->trans('ReOpen') . '</a>';
  1471. // print '</p>';
  1472. // }
  1473. // }
  1474. // Send by mail
  1475. // if (($object->Status != "DRAFT")) {
  1476. print '<p class="button-height right">';
  1477. print '<a class="button icon-mail" href="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&amp;action=presend&amp;mode=init">' . $langs->trans('SendByMail') . '</a>';
  1478. print '</p>';
  1479. // }
  1480. // Validate
  1481. // if ($object->Status == "DRAFT" && count($object->lines) > 0 &&
  1482. // (
  1483. // (($object->type == "INVOICE_STANDARD" || $object->type == "INVOICE_DEPOSIT" || $object->type == "INVOICE_REPLACEMENT" ) && (!empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0))
  1484. // || ($object->type == "INVOICE_AVOIR" && $object->total_ttc <= 0))
  1485. // ) {
  1486. // if ($user->rights->facture->valider) {
  1487. // print '<p class="button-height right">';
  1488. // print '<a class="button icon-tick" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=valid">' . $langs->trans('Validate') . '</a>';
  1489. // print "</p>";
  1490. // }
  1491. // }
  1492. // Create payment
  1493. if (/*( $object->Status == "NOT_PAID" || $object->Status == "STARTED") && */ $user->rights->facture->paiement) {
  1494. if ($resteapayer > 0) {
  1495. print '<p class="button-height right">';
  1496. print '<a class="button" href="compta/paiement.php?facid=' . $object->id . '&amp;action=create">' . $langs->trans('DoPayment') . '</a>';
  1497. print "</p>";
  1498. }
  1499. }
  1500. print '</div>';
  1501. }
  1502. }
  1503. print start_box($title, "twelve", $object->fk_extrafields->ico, false);
  1504. dol_fiche_head();
  1505. if ($action == 'edit') {
  1506. print '<form name="edit" action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
  1507. print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
  1508. print '<input type="hidden" name="action" value="update">';
  1509. print '<input type="hidden" name="id" value="' . $id . '">';
  1510. print '<input name="facnumber" type="hidden" value="provisoire">';
  1511. }
  1512. print '<table class="border" width="100%">';
  1513. // Ref
  1514. print '<tr><td width="20%">' . $langs->trans('Ref') . '</td>';
  1515. print '<td>' . $object->ref . '</td></tr>';
  1516. // Client
  1517. print '<tr><td width="20%">' . $langs->trans('Company') . '</td>';
  1518. print '<td>' . $object->client->name . '</td></tr>';
  1519. // Type
  1520. print '<tr><td width="20%">' . $langs->trans('Type') . '</td>';
  1521. print '<td>' . $object->print_fk_extrafields('type');
  1522. if ($object->type == "INVOICE_REPLACEMENT") {
  1523. $facreplaced = new Facture($db);
  1524. $facreplaced->fetch($object->fk_facture_source);
  1525. print ' (' . $langs->transnoentities("ReplaceInvoice", $facreplaced->getNomUrl(1)) . ')';
  1526. }
  1527. else if ($object->type == 'INVOICE_AVOIR') {
  1528. $facinvoiced = new Facture($db);
  1529. $facinvoiced->fetch($object->fk_facture_source);
  1530. print ' (' . $langs->transnoentities("InvoiceAvoirAsk") . $facinvoiced->getNomUrl(1) . ')';
  1531. }
  1532. if (!empty($replacingInvoice)) {
  1533. print ' (' . $langs->transnoentities("ReplacedByInvoice", $replacingInvoice->getNomUrl(1)) . ')';
  1534. }
  1535. print '</td></tr>';
  1536. // Relative and absolute discounts
  1537. // $addrelativediscount = '<a href="' . DOL_URL_ROOT . '/comm/remise.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"]) . '?facid=' . $object->id . '">' . $langs->trans("EditRelativeDiscounts") . '</a>';
  1538. // $addabsolutediscount = '<a href="' . DOL_URL_ROOT . '/comm/remx.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"]) . '?facid=' . $object->id . '">' . $langs->trans("EditGlobalDiscounts") . '</a>';
  1539. // $addcreditnote = '<a href="' . DOL_URL_ROOT . '/facture/fiche.php?action=create&socid=' . $soc->id . '&type=2&backtopage=' . urlencode($_SERVER["PHP_SELF"]) . '?facid=' . $object->id . '">' . $langs->trans("AddCreditNote") . '</a>';
  1540. //
  1541. // print '<tr><td>' . $langs->trans('Discounts');
  1542. // print '</td><td colspan="5">';
  1543. // if ($soc->remise_client)
  1544. // print $langs->trans("CompanyHasRelativeDiscount", $soc->remise_client);
  1545. // else
  1546. // print $langs->trans("CompanyHasNoRelativeDiscount");
  1547. // //print ' ('.$addrelativediscount.')';
  1548. //
  1549. // $object->fetch_thirdparty();
  1550. // $absolute_discount = $object->thirdparty->getAvailableDiscounts();
  1551. // if ($absolute_discount > 0) {
  1552. // print '. ';
  1553. // if ($object->Status != "DRAFT" || $object->type == "INVOICE_DEPOSIT" || $object->type == 3) {
  1554. // if ($object->Status == "DRAFT") {
  1555. // print $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->transnoentities("Currency" . $conf->currency));
  1556. // print '. ';
  1557. // } else {
  1558. // if ($object->Status == "DRAFT" || $object->type == "INVOICE_DEPOSIT" || $object->type == 3) {
  1559. // $text = $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->transnoentities("Currency" . $conf->currency));
  1560. // print '<br>' . $text . '.<br>';
  1561. // } else {
  1562. // $text = $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->transnoentities("Currency" . $conf->currency));
  1563. // $text2 = $langs->trans("AbsoluteDiscountUse");
  1564. // print $form->textwithpicto($text, $text2);
  1565. // }
  1566. // }
  1567. // } else {
  1568. // // Remise dispo de type remise fixe (not credit note)
  1569. // print '<br>';
  1570. // $form->form_remise_dispo($_SERVER["PHP_SELF"] . '?id=' . $object->id, GETPOST('discountid'), 'remise_id', $object->socid, $absolute_discount, $filterabsolutediscount, $resteapayer, ' (' . $addabsolutediscount . ')');
  1571. // }
  1572. // } else {
  1573. // if ($absolute_creditnote > 0) { // If not, link will be added later
  1574. // if ($object->statut == 0 && $object->type != 2 && $object->type != 3)
  1575. // print ' (' . $addabsolutediscount . ')<br>';
  1576. // else
  1577. // print '. ';
  1578. // }
  1579. // else
  1580. // print '. ';
  1581. // }
  1582. // if ($absolute_creditnote > 0) {
  1583. // // If validated, we show link "add credit note to payment"
  1584. // if ($object->statut != 1 || $object->type == 2 || $object->type == 3) {
  1585. // if ($object->statut == 0 && $object->type != 3) {
  1586. // $text = $langs->trans("CompanyHasCreditNote", price($absolute_creditnote), $langs->transnoentities("Currency" . $conf->currency));
  1587. // print $form->textwithpicto($text, $langs->trans("CreditNoteDepositUse"));
  1588. // } else {
  1589. // print $langs->trans("CompanyHasCreditNote", price($absolute_creditnote), $langs->transnoentities("Currency" . $conf->currency)) . '.';
  1590. // }
  1591. // } else {
  1592. // // Remise dispo de type avoir
  1593. // if (!$absolute_discount)
  1594. // print '<br>';
  1595. // //$form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, $resteapayer);
  1596. // $form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, 0); // We must allow credit not even if amount is higher
  1597. // }
  1598. // }
  1599. // if (!$absolute_discount && !$absolute_creditnote) {
  1600. // print $langs->trans("CompanyHasNoAbsoluteDiscount");
  1601. // if ($object->statut == 0 && $object->type != 2 && $object->type != 3)
  1602. // print ' (' . $addabsolutediscount . ')<br>';
  1603. // else
  1604. // print '. ';
  1605. // }
  1606. // /* if ($object->statut == 0 && $object->type != 2 && $object->type != 3)
  1607. // {
  1608. // if (! $absolute_discount && ! $absolute_creditnote) print '<br>';
  1609. // //print ' &nbsp; - &nbsp; ';
  1610. // print $addabsolutediscount;
  1611. // //print ' &nbsp; - &nbsp; '.$addcreditnote; // We disbale link to credit note
  1612. // } */
  1613. // print '</td></tr>';
  1614. // Ref Customer
  1615. print '<tr><td>' . $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->facture->creer && $object->Status == "DRAFT", "text") . '</td>';
  1616. print '<td td colspan="5">';
  1617. print $form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->facture->creer && $object->Status == "DRAFT", "text");
  1618. print '</td>';
  1619. print '</tr>';
  1620. // Date invoice
  1621. // print '<tr><td width="20%">' . $langs->trans('Date') . '</td>';
  1622. // print '<td>';
  1623. // if ($action == 'edit')
  1624. // $form->select_date($object->date, 're', '', '', '', "edit_commande", 1, 1);
  1625. // else
  1626. // print dol_print_date($object->date, 'daytext');
  1627. // print '</td></tr>';
  1628. print '<tr><td>' . $form->editfieldkey("Date", 'date', $object->date, $object, $user->rights->facture->creer && $object->Status == "DRAFT", "datepicker") . '</td>';
  1629. print '<td td colspan="5">';
  1630. print $form->editfieldval("Date", 'date', $object->date, $object, $user->rights->facture->creer && $object->Status == "DRAFT", "datepicker");
  1631. print '</td>';
  1632. print '</tr>';
  1633. // Date payment term
  1634. // print '<tr><td width="20%">' . $langs->trans('DateMaxPayment') . '</td>';
  1635. // print '<td>';
  1636. // if ($action == 'edit')
  1637. // $form->select_date($object->date_lim_reglement, 'li', '', '', '', "edit_commande", 1, 1);
  1638. // else {
  1639. // print dol_print_date($object->date_lim_reglement, 'daytext');
  1640. // if ($object->date_lim_reglement < ($now - $conf->facture->client->warning_delay) && !$object->paye && $object->statut == 1 && !isset($object->am))
  1641. // print img_warning($langs->trans('Late'));
  1642. // }
  1643. // print '</td></tr>';
  1644. print '<tr><td>' . $form->editfieldkey("DateMaxPayment", 'date_lim_reglement', $object->date_lim_reglement, $object, $user->rights->facture->creer && $object->Status == "DRAFT", "datepicker") . '</td>';
  1645. print '<td td colspan="5">';
  1646. print $form->editfieldval("DateMaxPayment", 'date_lim_reglement', $object->date_lim_reglement, $object, $user->rights->facture->creer && $object->Status == "DRAFT", "datepicker");
  1647. print '</td>';
  1648. print '</tr>';
  1649. // Payment terms
  1650. // print '<tr><td width="20%">' . $langs->trans('PaymentConditions') . '</td>';
  1651. // print '<td>';
  1652. // if ($action == 'edit') {
  1653. // print $object->select_fk_extrafields('cond_reglement_code', 'cond_reglement_code', $object->cond_reglement_code);
  1654. // }
  1655. // else
  1656. // print $object->getExtraFieldLabel('cond_reglement_code');
  1657. // print '</td></tr>';
  1658. print '<tr><td>' . $form->editfieldkey("PaymentConditions", 'cond_reglement_code', $object->cond_reglement_code, $object, $user->rights->facture->creer && $object->Status == "DRAFT", "select") . '</td>';
  1659. print '<td td colspan="5">';
  1660. print $form->editfieldval("PaymentConditions", 'cond_reglement_code', $object->cond_reglement_code, $object, $user->rights->facture->creer && $object->Status == "DRAFT", "select");
  1661. print '</td>';
  1662. print '</tr>';
  1663. // Payment mode
  1664. // print '<tr><td width="20%">' . $langs->trans('PaymentMode') . '</td>';
  1665. // print '<td>';
  1666. // if ($action == 'edit')
  1667. // print $object->select_fk_extrafields('mode_reglement_code', 'mode_reglement_code', $object->mode_reglement_code);
  1668. // else
  1669. // print $object->getExtraFieldLabel('mode_reglement_code') . '</td></tr>';
  1670. print '<tr><td>' . $form->editfieldkey("PaymentMode", 'mode_reglement_code', $object->mode_reglement_code, $object, $user->rights->facture->creer && $object->Status == "DRAFT", "select") . '</td>';
  1671. print '<td td colspan="5">';
  1672. print $form->editfieldval("PaymentMode", 'mode_reglement_code', $object->mode_reglement_code, $object, $user->rights->facture->creer && $object->Status == "DRAFT", "select");
  1673. print '</td>';
  1674. print '</tr>';
  1675. // Amount
  1676. print '<tr><td>' . $langs->trans('AmountHT') . '</td>';
  1677. print '<td align="right" colspan="2" nowrap>' . price($object->total_ht) . '</td>';
  1678. print '<td>' . $langs->trans('Currency' . $conf->currency) . '</td></tr>';
  1679. print '<tr><td>' . $langs->trans('AmountVAT') . '</td><td align="right" colspan="2" nowrap>' . price($object->total_tva) . '</td>';
  1680. print '<td>' . $langs->trans('Currency' . $conf->currency) . '</td>';
  1681. print '</tr>';
  1682. // Amount Local Taxes
  1683. if ($mysoc->pays_code == 'ES') {
  1684. if ($mysoc->localtax1_assuj == "1") { //Localtax1 RE
  1685. print '<tr><td>' . $langs->transcountry("AmountLT1", $mysoc->pays_code) . '</td>';
  1686. print '<td align="right" colspan="2" nowrap>' . price($object->total_localtax1) . '</td>';
  1687. print '<td>' . $langs->trans("Currency" . $conf->currency) . '</td></tr>';
  1688. }
  1689. if ($mysoc->localtax2_assuj == "1") { //Localtax2 IRPF
  1690. print '<tr><td>' . $langs->transcountry("AmountLT2", $mysoc->pays_code) . '</td>';
  1691. print '<td align="right" colspan="2" nowrap>' . price($object->total_localtax2) . '</td>';
  1692. print '<td>' . $langs->trans("Currency" . $conf->currency) . '</td></tr>';
  1693. }
  1694. }
  1695. print '<tr><td>' . $langs->trans('AmountTTC') . '</td><td align="right" colspan="2" nowrap>' . price($object->total_ttc) . '</td>';
  1696. print '<td>' . $langs->trans('Currency' . $conf->currency) . '</td></tr>';
  1697. // Status
  1698. // print '<tr><td width="20%">' . $langs->trans('Status') . '</td>';
  1699. // print '<td>' . $object->getExtraFieldLabel('Status') . '</td></tr>';
  1700. print '<tr><td>' . $form->editfieldkey("Status", 'Status', $object->Status, $object, $user->rights->facture->creer, "select") . '</td>';
  1701. print '<td td colspan="5">';
  1702. print $form->editfieldval("Status", 'Status', $object->Status, $object, $user->rights->facture->creer, "select");
  1703. print '</td>';
  1704. print '</tr>';
  1705. print '</table>';
  1706. dol_fiche_end();
  1707. if ($action == 'edit') {
  1708. // Button "Update"
  1709. print '<br><center><input type="submit" class="button" name="bouton" value="' . $langs->trans('Update') . '"></center>';
  1710. print '</form>';
  1711. }
  1712. print end_box();
  1713. // Lines
  1714. $object->showLines();
  1715. // Show list of paymenys
  1716. $object->showPayments();
  1717. // List of linked objects
  1718. // $object->printLinkedObjects();
  1719. $object->showLinkedObjects();
  1720. /*
  1721. * Documents generes
  1722. */
  1723. print start_box($langs->trans('Documents'), "six", $object->fk_extrafields->ico, false);
  1724. $filename = dol_sanitizeFileName($object->ref);
  1725. $filedir = $conf->facture->dir_output . '/' . dol_sanitizeFileName($object->ref);
  1726. $urlsource = $_SERVER['PHP_SELF'] . '?id=' . $object->id;
  1727. $genallowed = $user->rights->facture->creer;
  1728. $delallowed = $user->rights->facture->supprimer;
  1729. print '<br>';
  1730. print $formfile->showdocuments('facture', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', '', '', $soc->default_lang);
  1731. $somethingshown = $formfile->numoffiles;
  1732. print end_box();
  1733. if ($action == 'presend') {
  1734. /*
  1735. * Affiche formulaire mail
  1736. */
  1737. // By default if $action=='presend'
  1738. $titreform = 'SendBillByMail';
  1739. $topicmail = 'SendBillRef';
  1740. $action = 'send';
  1741. $modelmail = 'facture_send';
  1742. if ($action == 'prerelance') { // For backward compatibility
  1743. $titrefrom = 'SendReminderBillByMail';
  1744. $topicmail = 'SendReminderBillRef';
  1745. $action = 'relance';
  1746. $modelmail = 'facture_relance';
  1747. }
  1748. $ref = dol_sanitizeFileName($object->ref);
  1749. include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
  1750. $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref);
  1751. $file = $fileparams['fullname'];
  1752. // Build document if it not exists
  1753. if (!$file || !is_readable($file)) {
  1754. // Define output language
  1755. $outputlangs = $langs;
  1756. $newlang = '';
  1757. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && !empty($_REQUEST['lang_id']))
  1758. $newlang = $_REQUEST['lang_id'];
  1759. if ($conf->global->MAIN_MULTILANGS && empty($newlang))
  1760. $newlang = $object->client->default_lang;
  1761. if (!empty($newlang)) {
  1762. $outputlangs = new Translate();
  1763. $outputlangs->setDefaultLang($newlang);
  1764. }
  1765. $result = facture_pdf_create($db, $object, GETPOST('model') ? GETPOST('model') : $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
  1766. if ($result <= 0) {
  1767. dol_print_error($db, $result);
  1768. exit;
  1769. }
  1770. $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref);
  1771. $file = $fileparams['fullname'];
  1772. }
  1773. print '<br>';
  1774. print_titre($langs->trans($titreform));
  1775. // Cree l'objet formulaire mail
  1776. include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php';
  1777. $formmail = new FormMail($db);
  1778. $formmail->fromtype = 'user';
  1779. $formmail->fromid = $user->id;
  1780. $formmail->fromname = $user->getFullName($langs);
  1781. $formmail->frommail = $user->email;
  1782. $formmail->withfrom = 1;
  1783. $formmail->withto = empty($_POST["sendto"]) ? 1 : $_POST["sendto"];
  1784. $formmail->withtosocid = $soc->id;
  1785. $formmail->withtocc = 1;
  1786. $formmail->withtoccsocid = 0;
  1787. $formmail->withtoccc = $conf->global->MAIN_EMAIL_USECCC;
  1788. $formmail->withtocccsocid = 0;
  1789. $formmail->withtopic = $langs->transnoentities($topicmail, '__FACREF__');
  1790. $formmail->withfile = 2;
  1791. $formmail->withbody = 1;
  1792. $formmail->withdeliveryreceipt = 1;
  1793. $formmail->withcancel = 1;
  1794. // Tableau des substitutions
  1795. $formmail->substit['__FACREF__'] = $object->ref;
  1796. $formmail->substit['__SIGNATURE__'] = $user->signature;
  1797. $formmail->substit['__PERSONALIZED__'] = '';
  1798. // Tableau des parametres complementaires du post
  1799. $formmail->param['action'] = $action;
  1800. $formmail->param['models'] = $modelmail;
  1801. $formmail->param['facid'] = $object->id;
  1802. $formmail->param['returnurl'] = $_SERVER["PHP_SELF"] . '?id=' . $object->id;
  1803. // Init list of files
  1804. if (GETPOST("mode") == 'init') {
  1805. $formmail->clear_attached_files();
  1806. $formmail->add_attached_files($file, basename($file), dol_mimetype($file));
  1807. }
  1808. $formmail->show_form();
  1809. print '<br>';
  1810. }
  1811. }
  1812. print '</div>';
  1813. print '</div>';
  1814. dol_htmloutput_mesg('', $mesgs);
  1815. llxFooter();
  1816. ?>