card.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. <?php
  2. /* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
  3. * Copyright (C) 2013-2020 Alexandre Spangaro <aspangaro@open-dsi.fr>
  4. * Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. /**
  20. * \file htdocs/accountancy/admin/card.php
  21. * \ingroup Accountancy (Double entries)
  22. * \brief Card of accounting account
  23. */
  24. // Load Dolibarr environment
  25. require '../../main.inc.php';
  26. require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
  27. require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
  28. require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancysystem.class.php';
  29. require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
  30. $error = 0;
  31. // Load translation files required by the page
  32. $langs->loadLangs(array('accountancy', 'bills', 'compta'));
  33. $action = GETPOST('action', 'aZ09');
  34. $backtopage = GETPOST('backtopage', 'alpha');
  35. $id = GETPOST('id', 'int');
  36. $ref = GETPOST('ref', 'alpha');
  37. $rowid = GETPOST('rowid', 'int');
  38. $cancel = GETPOST('cancel', 'alpha');
  39. $account_number = GETPOST('account_number', 'string');
  40. $label = GETPOST('label', 'alpha');
  41. // Security check
  42. if ($user->socid > 0) {
  43. accessforbidden();
  44. }
  45. if (empty($user->rights->accounting->chartofaccount)) {
  46. accessforbidden();
  47. }
  48. $object = new AccountingAccount($db);
  49. /*
  50. * Action
  51. */
  52. if (GETPOST('cancel', 'alpha')) {
  53. $urltogo = $backtopage ? $backtopage : DOL_URL_ROOT.'/accountancy/admin/account.php';
  54. header("Location: ".$urltogo);
  55. exit;
  56. }
  57. if ($action == 'add' && $user->hasRight('accounting', 'chartofaccount')) {
  58. if (!$cancel) {
  59. if (!$account_number) {
  60. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AccountNumber")), null, 'errors');
  61. $action = 'create';
  62. } elseif (!$label) {
  63. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
  64. $action = 'create';
  65. } else {
  66. $sql = "SELECT pcg_version FROM " . MAIN_DB_PREFIX . "accounting_system WHERE rowid = ".((int) $conf->global->CHARTOFACCOUNTS);
  67. dol_syslog('accountancy/admin/card.php:: $sql=' . $sql);
  68. $result = $db->query($sql);
  69. $obj = $db->fetch_object($result);
  70. // Clean code
  71. // To manage zero or not at the end of the accounting account
  72. if ($conf->global->ACCOUNTING_MANAGE_ZERO == 1) {
  73. $account_number = $account_number;
  74. } else {
  75. $account_number = clean_account($account_number);
  76. }
  77. if (GETPOST('account_parent', 'int') <= 0) {
  78. $account_parent = 0;
  79. } else {
  80. $account_parent = GETPOST('account_parent', 'int');
  81. }
  82. $object->fk_pcg_version = $obj->pcg_version;
  83. $object->pcg_type = GETPOST('pcg_type', 'alpha');
  84. $object->account_number = $account_number;
  85. $object->account_parent = $account_parent;
  86. $object->account_category = GETPOST('account_category', 'alpha');
  87. $object->label = $label;
  88. $object->labelshort = GETPOST('labelshort', 'alpha');
  89. $object->active = 1;
  90. $res = $object->create($user);
  91. if ($res == -3) {
  92. $error = 1;
  93. $action = "create";
  94. setEventMessages($object->error, $object->errors, 'errors');
  95. } elseif ($res == -4) {
  96. $error = 2;
  97. $action = "create";
  98. setEventMessages($object->error, $object->errors, 'errors');
  99. } elseif ($res < 0) {
  100. $error++;
  101. setEventMessages($object->error, $object->errors, 'errors');
  102. $action = "create";
  103. }
  104. if (!$error) {
  105. setEventMessages("RecordCreatedSuccessfully", null, 'mesgs');
  106. $urltogo = $backtopage ? $backtopage : DOL_URL_ROOT.'/accountancy/admin/account.php';
  107. header("Location: " . $urltogo);
  108. exit;
  109. }
  110. }
  111. }
  112. } elseif ($action == 'edit' && $user->hasRight('accounting', 'chartofaccount')) {
  113. if (!$cancel) {
  114. if (!$account_number) {
  115. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AccountNumber")), null, 'errors');
  116. $action = 'update';
  117. } elseif (!$label) {
  118. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
  119. $action = 'update';
  120. } else {
  121. $result = $object->fetch($id);
  122. $sql = "SELECT pcg_version FROM ".MAIN_DB_PREFIX."accounting_system WHERE rowid=".((int) $conf->global->CHARTOFACCOUNTS);
  123. dol_syslog('accountancy/admin/card.php:: $sql=' . $sql);
  124. $result2 = $db->query($sql);
  125. $obj = $db->fetch_object($result2);
  126. // Clean code
  127. // To manage zero or not at the end of the accounting account
  128. if (isset($conf->global->ACCOUNTING_MANAGE_ZERO) && $conf->global->ACCOUNTING_MANAGE_ZERO == 1) {
  129. $account_number = $account_number;
  130. } else {
  131. $account_number = clean_account($account_number);
  132. }
  133. if (GETPOST('account_parent', 'int') <= 0) {
  134. $account_parent = 0;
  135. } else {
  136. $account_parent = GETPOST('account_parent', 'int');
  137. }
  138. $object->fk_pcg_version = $obj->pcg_version;
  139. $object->pcg_type = GETPOST('pcg_type', 'alpha');
  140. $object->account_number = $account_number;
  141. $object->account_parent = $account_parent;
  142. $object->account_category = GETPOST('account_category', 'alpha');
  143. $object->label = $label;
  144. $object->labelshort = GETPOST('labelshort', 'alpha');
  145. $result = $object->update($user);
  146. if ($result > 0) {
  147. $urltogo = $backtopage ? $backtopage : ($_SERVER["PHP_SELF"] . "?id=" . $id);
  148. header("Location: " . $urltogo);
  149. exit();
  150. } elseif ($result == -2) {
  151. setEventMessages($langs->trans("ErrorAccountNumberAlreadyExists", $object->account_number), null, 'errors');
  152. } else {
  153. setEventMessages($object->error, null, 'errors');
  154. }
  155. }
  156. } else {
  157. $urltogo = $backtopage ? $backtopage : ($_SERVER["PHP_SELF"]."?id=".$id);
  158. header("Location: ".$urltogo);
  159. exit();
  160. }
  161. } elseif ($action == 'delete' && $user->hasRight('accounting', 'chartofaccount')) {
  162. $result = $object->fetch($id);
  163. if (!empty($object->id)) {
  164. $result = $object->delete($user);
  165. if ($result > 0) {
  166. header("Location: account.php");
  167. exit;
  168. }
  169. }
  170. if ($result < 0) {
  171. setEventMessages($object->error, $object->errors, 'errors');
  172. }
  173. }
  174. /*
  175. * View
  176. */
  177. $form = new Form($db);
  178. $formaccounting = new FormAccounting($db);
  179. $accountsystem = new AccountancySystem($db);
  180. $accountsystem->fetch($conf->global->CHARTOFACCOUNTS);
  181. $title = $langs->trans('AccountAccounting')." - ".$langs->trans('Card');
  182. $help_url = 'EN:Category:Accounting';
  183. llxheader('', $title, $help_url);
  184. // Create mode
  185. if ($action == 'create') {
  186. print load_fiche_titre($langs->trans('NewAccountingAccount'));
  187. print '<form name="add" action="'.$_SERVER["PHP_SELF"].'" method="POST">'."\n";
  188. print '<input type="hidden" name="token" value="'.newToken().'">';
  189. print '<input type="hidden" name="action" value="add">';
  190. print dol_get_fiche_head();
  191. print '<table class="border centpercent">';
  192. // Chart of account
  193. print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("Chartofaccounts").'</span></td>';
  194. print '<td>';
  195. print $accountsystem->ref;
  196. print '</td></tr>';
  197. // Account number
  198. print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("AccountNumber").'</span></td>';
  199. print '<td><input name="account_number" size="30" value="'.$account_number.'"></td></tr>';
  200. // Label
  201. print '<tr><td><span class="fieldrequired">'.$langs->trans("Label").'</span></td>';
  202. print '<td><input name="label" size="70" value="'.$object->label.'"></td></tr>';
  203. // Label short
  204. print '<tr><td>'.$langs->trans("LabelToShow").'</td>';
  205. print '<td><input name="labelshort" size="70" value="'.$object->labelshort.'"></td></tr>';
  206. // Account parent
  207. print '<tr><td>'.$langs->trans("Accountparent").'</td>';
  208. print '<td>';
  209. print $formaccounting->select_account($object->account_parent, 'account_parent', 1, null, 0, 0, 'minwidth200');
  210. print '</td></tr>';
  211. // Chart of accounts type
  212. print '<tr><td>';
  213. print $form->textwithpicto($langs->trans("Pcgtype"), $langs->transnoentitiesnoconv("PcgtypeDesc"));
  214. print '</td>';
  215. print '<td>';
  216. print '<input type="text" name="pcg_type" list="pcg_type_datalist" value="'.dol_escape_htmltag(GETPOSTISSET('pcg_type') ? GETPOST('pcg_type', 'alpha') : $object->pcg_type).'">';
  217. // autosuggest from existing account types if found
  218. print '<datalist id="pcg_type_datalist">';
  219. $sql = "SELECT DISTINCT pcg_type FROM " . MAIN_DB_PREFIX . "accounting_account";
  220. $sql .= " WHERE fk_pcg_version = '" . $db->escape($accountsystem->ref) . "'";
  221. $sql .= ' AND entity in ('.getEntity('accounting_account', 0).')'; // Always limit to current entity. No sharing in accountancy.
  222. $sql .= ' LIMIT 50000'; // just as a sanity check
  223. $resql = $db->query($sql);
  224. if ($resql) {
  225. while ($obj = $db->fetch_object($resql)) {
  226. print '<option value="' . dol_escape_htmltag($obj->pcg_type) . '">';
  227. }
  228. }
  229. print '</datalist>';
  230. print '</td></tr>';
  231. // Category
  232. print '<tr><td>';
  233. print $form->textwithpicto($langs->trans("AccountingCategory"), $langs->transnoentitiesnoconv("AccountingAccountGroupsDesc"));
  234. print '</td>';
  235. print '<td>';
  236. $formaccounting->select_accounting_category($object->account_category, 'account_category', 1, 0, 1);
  237. print '</td></tr>';
  238. print '</table>';
  239. print dol_get_fiche_end();
  240. print '<div class="center">';
  241. print '<input class="button button-save" type="submit" value="'.$langs->trans("Save").'">';
  242. print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
  243. print '<input class="button button-cancel" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
  244. print '</div>';
  245. print '</form>';
  246. } elseif ($id > 0 || $ref) {
  247. $result = $object->fetch($id, $ref, 1);
  248. if ($result > 0) {
  249. $head = accounting_prepare_head($object);
  250. // Edit mode
  251. if ($action == 'update') {
  252. print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), 0, 'accounting_account');
  253. print '<form name="update" action="'.$_SERVER["PHP_SELF"].'" method="POST">'."\n";
  254. print '<input type="hidden" name="token" value="'.newToken().'">';
  255. print '<input type="hidden" name="action" value="edit">';
  256. print '<input type="hidden" name="id" value="'.$id.'">';
  257. print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
  258. print '<table class="border centpercent">';
  259. // Account number
  260. print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("AccountNumber").'</span></td>';
  261. print '<td><input name="account_number" size="30" value="'.$object->account_number.'"</td></tr>';
  262. // Label
  263. print '<tr><td><span class="fieldrequired">'.$langs->trans("Label").'</span></td>';
  264. print '<td><input name="label" size="70" value="'.$object->label.'"</td></tr>';
  265. // Label short
  266. print '<tr><td>'.$langs->trans("LabelToShow").'</td>';
  267. print '<td><input name="labelshort" size="70" value="'.$object->labelshort.'"</td></tr>';
  268. // Account parent
  269. print '<tr><td>'.$langs->trans("Accountparent").'</td>';
  270. print '<td>';
  271. print $formaccounting->select_account($object->account_parent, 'account_parent', 1);
  272. print '</td></tr>';
  273. // Chart of accounts type
  274. print '<tr><td>';
  275. print $form->textwithpicto($langs->trans("Pcgtype"), $langs->transnoentitiesnoconv("PcgtypeDesc"));
  276. print '</td>';
  277. print '<td>';
  278. print '<input type="text" name="pcg_type" list="pcg_type_datalist" value="'.dol_escape_htmltag(GETPOSTISSET('pcg_type') ? GETPOST('pcg_type', 'alpha') : $object->pcg_type).'">';
  279. // autosuggest from existing account types if found
  280. print '<datalist id="pcg_type_datalist">';
  281. $sql = 'SELECT DISTINCT pcg_type FROM ' . MAIN_DB_PREFIX . 'accounting_account';
  282. $sql .= " WHERE fk_pcg_version = '" . $db->escape($accountsystem->ref) . "'";
  283. $sql .= ' AND entity in ('.getEntity('accounting_account', 0).')'; // Always limit to current entity. No sharing in accountancy.
  284. $sql .= ' LIMIT 50000'; // just as a sanity check
  285. $resql = $db->query($sql);
  286. if ($resql) {
  287. while ($obj = $db->fetch_object($resql)) {
  288. print '<option value="' . dol_escape_htmltag($obj->pcg_type) . '">';
  289. }
  290. }
  291. print '</datalist>';
  292. print '</td></tr>';
  293. // Category
  294. print '<tr><td>';
  295. print $form->textwithpicto($langs->trans("AccountingCategory"), $langs->transnoentitiesnoconv("AccountingAccountGroupsDesc"));
  296. print '</td>';
  297. print '<td>';
  298. $formaccounting->select_accounting_category($object->account_category, 'account_category', 1);
  299. print '</td></tr>';
  300. print '</table>';
  301. print dol_get_fiche_end();
  302. print $form->buttonsSaveCancel();
  303. print '</form>';
  304. } else {
  305. // View mode
  306. $linkback = '<a href="'.DOL_URL_ROOT.'/accountancy/admin/account.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
  307. print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), -1, 'accounting_account');
  308. dol_banner_tab($object, 'ref', $linkback, 1, 'account_number', 'ref');
  309. print '<div class="fichecenter">';
  310. print '<div class="underbanner clearboth"></div>';
  311. print '<table class="border centpercent">';
  312. // Label
  313. print '<tr><td class="titlefield">'.$langs->trans("Label").'</td>';
  314. print '<td colspan="2">'.$object->label.'</td></tr>';
  315. // Label to show
  316. print '<tr><td class="titlefield">'.$langs->trans("LabelToShow").'</td>';
  317. print '<td colspan="2">'.$object->labelshort.'</td></tr>';
  318. // Account parent
  319. $accp = new AccountingAccount($db);
  320. if (!empty($object->account_parent)) {
  321. $accp->fetch($object->account_parent, '');
  322. }
  323. print '<tr><td>'.$langs->trans("Accountparent").'</td>';
  324. print '<td colspan="2">'.$accp->account_number.' - '.$accp->label.'</td></tr>';
  325. // Group of accounting account
  326. print '<tr><td>';
  327. print $form->textwithpicto($langs->trans("Pcgtype"), $langs->transnoentitiesnoconv("PcgtypeDesc"));
  328. print '</td>';
  329. print '<td colspan="2">'.$object->pcg_type.'</td></tr>';
  330. // Custom group of accounting account
  331. print "<tr><td>";
  332. print $form->textwithpicto($langs->trans("AccountingCategory"), $langs->transnoentitiesnoconv("AccountingAccountGroupsDesc"));
  333. print "</td><td colspan='2'>".$object->account_category_label."</td>";
  334. print '</table>';
  335. print '</div>';
  336. print dol_get_fiche_end();
  337. /*
  338. * Actions buttons
  339. */
  340. print '<div class="tabsAction">';
  341. if ($user->hasRight('accounting', 'chartofaccount')) {
  342. print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=update&token='.newToken().'&id='.$object->id.'">'.$langs->trans('Modify').'</a>';
  343. } else {
  344. print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans('Modify').'</a>';
  345. }
  346. if ($user->hasRight('accounting', 'chartofaccount')) {
  347. print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id.'">'.$langs->trans('Delete').'</a>';
  348. } else {
  349. print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans('Delete').'</a>';
  350. }
  351. print '</div>';
  352. }
  353. } else {
  354. dol_print_error($db, $object->error, $object->errors);
  355. }
  356. }
  357. // End of page
  358. llxFooter();
  359. $db->close();