dolibarr 22.0.5
card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
3 * Copyright (C) 2013-2024 Alexandre Spangaro <aspangaro@easya.solutions>
4 * Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro>
5 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
6 * Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
28// Load Dolibarr environment
29require '../../main.inc.php';
30require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
31require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
32require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancysystem.class.php';
33require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
34
43$error = 0;
44
45// Load translation files required by the page
46$langs->loadLangs(array('accountancy', 'bills', 'compta'));
47
48$action = GETPOST('action', 'aZ09');
49$backtopage = GETPOST('backtopage', 'alpha');
50$id = GETPOSTINT('id');
51$ref = GETPOST('ref', 'alpha');
52$rowid = GETPOSTINT('rowid');
53$cancel = GETPOST('cancel', 'alpha');
54
55$account_number = GETPOST('account_number', 'alphanohtml');
56$label = GETPOST('label', 'alpha');
57
58// Security check
59if ($user->socid > 0) {
61}
62if (!$user->hasRight('accounting', 'chartofaccount')) {
64}
65
66
68
69
70/*
71 * Action
72 */
73
74if (GETPOST('cancel', 'alpha')) {
75 $urltogo = $backtopage ? $backtopage : DOL_URL_ROOT.'/accountancy/admin/account.php';
76 header("Location: ".$urltogo);
77 exit;
78}
79
80if ($action == 'add' && $user->hasRight('accounting', 'chartofaccount')) {
81 if (!$cancel) {
82 if (!$account_number) {
83 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AccountNumber")), null, 'errors');
84 $action = 'create';
85 } elseif (!$label) {
86 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
87 $action = 'create';
88 } else {
89 $sql = "SELECT pcg_version FROM " . MAIN_DB_PREFIX . "accounting_system WHERE rowid = ".((int) getDolGlobalInt('CHARTOFACCOUNTS'));
90
91 dol_syslog('accountancy/admin/card.php:: $sql=' . $sql);
92 $result = $db->query($sql);
93 $obj = $db->fetch_object($result);
94
95 // Clean code
96
97 // To manage zero or not at the end of the accounting account
98 if (!getDolGlobalString('ACCOUNTING_MANAGE_ZERO')) {
99 $account_number = clean_account($account_number);
100 }
101
102 $account_parent = (GETPOSTINT('account_parent') > 0) ? GETPOSTINT('account_parent') : 0;
103
104 $object->fk_pcg_version = $obj->pcg_version;
105 $object->pcg_type = GETPOST('pcg_type', 'alpha');
106 $object->account_number = $account_number;
107 $object->account_parent = $account_parent;
108 $object->account_category = GETPOSTINT('account_category');
109 $object->label = $label;
110 $object->labelshort = GETPOST('labelshort', 'alpha');
111 $object->active = 1;
112
113 $res = $object->create($user);
114 if ($res == -3) {
115 $error = 1;
116 $action = "create";
117 setEventMessages($object->error, $object->errors, 'errors');
118 } elseif ($res == -4) {
119 $error = 2;
120 $action = "create";
121 setEventMessages($object->error, $object->errors, 'errors');
122 } elseif ($res < 0) {
123 $error++;
124 setEventMessages($object->error, $object->errors, 'errors');
125 $action = "create";
126 }
127 if (!$error) {
128 setEventMessages("RecordCreatedSuccessfully", null, 'mesgs');
129 $urltogo = $backtopage ? $backtopage : DOL_URL_ROOT.'/accountancy/admin/account.php';
130 header("Location: " . $urltogo);
131 exit;
132 }
133 }
134 }
135} elseif ($action == 'edit' && $user->hasRight('accounting', 'chartofaccount')) {
136 if (!$cancel) {
137 if (!$account_number) {
138 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AccountNumber")), null, 'errors');
139 $action = 'update';
140 } elseif (!$label) {
141 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
142 $action = 'update';
143 } else {
144 $result = $object->fetch($id);
145
146 $sql = "SELECT pcg_version FROM ".MAIN_DB_PREFIX."accounting_system WHERE rowid=".((int) getDolGlobalInt('CHARTOFACCOUNTS'));
147
148 dol_syslog('accountancy/admin/card.php:: $sql=' . $sql);
149 $result2 = $db->query($sql);
150 $obj = $db->fetch_object($result2);
151
152 // Clean code
153
154 // To manage zero or not at the end of the accounting account
155 if (!getDolGlobalString('ACCOUNTING_MANAGE_ZERO')) {
156 $account_number = clean_account($account_number);
157 }
158
159 $account_parent = (GETPOSTINT('account_parent') > 0) ? GETPOSTINT('account_parent') : 0;
160
161 $object->fk_pcg_version = $obj->pcg_version;
162 $object->pcg_type = GETPOST('pcg_type', 'alpha');
163 $object->account_number = $account_number;
164 $object->account_parent = $account_parent;
165 $object->account_category = GETPOSTINT('account_category');
166 $object->label = $label;
167 $object->labelshort = GETPOST('labelshort', 'alpha');
168
169 $result = $object->update($user);
170
171 if ($result > 0) {
172 $urltogo = $backtopage ? $backtopage : ($_SERVER["PHP_SELF"] . "?id=" . $id);
173 header("Location: " . $urltogo);
174 exit();
175 } elseif ($result == -2) {
176 setEventMessages($langs->trans("ErrorAccountNumberAlreadyExists", $object->account_number), null, 'errors');
177 } else {
178 setEventMessages($object->error, null, 'errors');
179 }
180 }
181 } else {
182 $urltogo = $backtopage ? $backtopage : ($_SERVER["PHP_SELF"]."?id=".$id);
183 header("Location: ".$urltogo);
184 exit();
185 }
186} elseif ($action == 'delete' && $user->hasRight('accounting', 'chartofaccount')) {
187 $result = $object->fetch($id);
188
189 if (!empty($object->id)) {
190 $result = $object->delete($user);
191
192 if ($result > 0) {
193 header("Location: account.php");
194 exit;
195 }
196 }
197
198 if ($result < 0) {
199 setEventMessages($object->error, $object->errors, 'errors');
200 }
201}
202
203
204/*
205 * View
206 */
207
208$form = new Form($db);
209$formaccounting = new FormAccounting($db);
210
211$accountsystem = new AccountancySystem($db);
212$accountsystem->fetch(getDolGlobalInt('CHARTOFACCOUNTS'));
213
214$title = $langs->trans('AccountAccounting')." - ".$langs->trans('Card');
215
216$help_url = 'EN:Module_Double_Entry_Accounting#Setup|FR:Module_Comptabilit&eacute;_en_Partie_Double#Configuration';
217
218llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-accountancy page-admin_card');
219
220
221// Create mode
222if ($action == 'create') {
223 print load_fiche_titre($langs->trans('NewAccountingAccount'));
224
225 print '<form name="add" action="'.$_SERVER["PHP_SELF"].'" method="POST">'."\n";
226 print '<input type="hidden" name="token" value="'.newToken().'">';
227 print '<input type="hidden" name="action" value="add">';
228
229 print dol_get_fiche_head();
230
231 print '<table class="border centpercent">';
232
233 // Chart of account
234 print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("Chartofaccounts").'</span></td>';
235 print '<td>';
236 print $accountsystem->ref;
237 print '</td></tr>';
238
239 // Account number
240 print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("AccountNumber").'</span></td>';
241 print '<td><input name="account_number" size="30" value="'.$account_number.'"></td></tr>';
242
243 // Label
244 print '<tr><td><span class="fieldrequired">'.$langs->trans("Label").'</span></td>';
245 print '<td><input name="label" size="70" value="'.$object->label.'"></td></tr>';
246
247 // Label short
248 print '<tr><td>'.$langs->trans("LabelToShow").'</td>';
249 print '<td><input name="labelshort" size="70" value="'.$object->labelshort.'"></td></tr>';
250
251 // Account parent
252 print '<tr><td>'.$langs->trans("Accountparent").'</td>';
253 print '<td>';
254 print $formaccounting->select_account((string) $object->account_parent, 'account_parent', 1, [], 0, 0, 'minwidth200');
255 print '</td></tr>';
256
257 // Chart of accounts type
258 print '<tr><td>';
259 print $form->textwithpicto($langs->trans("Pcgtype"), $langs->transnoentitiesnoconv("PcgtypeDesc"));
260 print '</td>';
261 print '<td>';
262 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).'">';
263 // autosuggest from existing account types if found
264 print '<datalist id="pcg_type_datalist">';
265 $sql = "SELECT DISTINCT pcg_type FROM " . MAIN_DB_PREFIX . "accounting_account";
266 $sql .= " WHERE fk_pcg_version = '" . $db->escape($accountsystem->ref) . "'";
267 $sql .= ' AND entity in ('.getEntity('accounting_account', 0).')'; // Always limit to current entity. No sharing in accountancy.
268 $sql .= ' LIMIT 50000'; // just as a sanity check
269 $resql = $db->query($sql);
270 if ($resql) {
271 while ($obj = $db->fetch_object($resql)) {
272 print '<option value="' . dol_escape_htmltag($obj->pcg_type) . '">';
273 }
274 }
275 print '</datalist>';
276 print '</td></tr>';
277
278 // Category
279 print '<tr><td>';
280 print $form->textwithpicto($langs->trans("AccountingCategory"), $langs->transnoentitiesnoconv("AccountingAccountGroupsDesc"));
281 print '</td>';
282 print '<td>';
283 print $formaccounting->select_accounting_category($object->account_category, 'account_category', 1, 0, 1);
284 print '</td></tr>';
285
286 print '</table>';
287
288 print dol_get_fiche_end();
289
290 print '<div class="center">';
291 print '<input class="button button-save" type="submit" value="'.$langs->trans("Save").'">';
292 print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
293 print '<input class="button button-cancel" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
294 print '</div>';
295
296 print '</form>';
297} elseif ($id > 0 || $ref) {
298 $result = $object->fetch($id, $ref, 1);
299
300 if ($result > 0) {
302
303 // Edit mode
304 if ($action == 'update') {
305 print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), 0, 'accounting_account');
306
307 print '<form name="update" action="'.$_SERVER["PHP_SELF"].'" method="POST">'."\n";
308 print '<input type="hidden" name="token" value="'.newToken().'">';
309 print '<input type="hidden" name="action" value="edit">';
310 print '<input type="hidden" name="id" value="'.$id.'">';
311 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
312
313 print '<table class="border centpercent">';
314
315 // Account number
316 print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("AccountNumber").'</span></td>';
317 print '<td><input name="account_number" size="30" value="'.$object->account_number.'"></td></tr>';
318
319 // Label
320 print '<tr><td><span class="fieldrequired">'.$langs->trans("Label").'</span></td>';
321 print '<td><input name="label" size="70" value="'.$object->label.'"></td></tr>';
322
323 // Label short
324 print '<tr><td>'.$langs->trans("LabelToShow").'</td>';
325 print '<td><input name="labelshort" size="70" value="'.$object->labelshort.'"></td></tr>';
326
327 // Account parent
328 print '<tr><td>'.$langs->trans("Accountparent").'</td>';
329 print '<td>';
330 // Note: We accept disabled account as parent account so we can build a hierarchy and use only children
331 print $formaccounting->select_account((string) $object->account_parent, 'account_parent', 1, array(), 0, 0, 'minwidth100 maxwidth300 maxwidthonsmartphone', '1', '');
332 print '</td></tr>';
333
334 // Chart of accounts type
335 print '<tr><td>';
336 print $form->textwithpicto($langs->trans("Pcgtype"), $langs->transnoentitiesnoconv("PcgtypeDesc"));
337 print '</td>';
338 print '<td>';
339 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).'">';
340 // autosuggest from existing account types if found
341 print '<datalist id="pcg_type_datalist">';
342 $sql = 'SELECT DISTINCT pcg_type FROM ' . MAIN_DB_PREFIX . 'accounting_account';
343 $sql .= " WHERE fk_pcg_version = '" . $db->escape($accountsystem->ref) . "'";
344 $sql .= ' AND entity in ('.getEntity('accounting_account', 0).')'; // Always limit to current entity. No sharing in accountancy.
345 $sql .= ' LIMIT 50000'; // just as a sanity check
346 $resql = $db->query($sql);
347 if ($resql) {
348 while ($obj = $db->fetch_object($resql)) {
349 print '<option value="' . dol_escape_htmltag($obj->pcg_type) . '">';
350 }
351 }
352 print '</datalist>';
353 print '</td></tr>';
354
355 // Category
356 print '<tr><td>';
357 print $form->textwithpicto($langs->trans("AccountingCategory"), $langs->transnoentitiesnoconv("AccountingAccountGroupsDesc"));
358 print '</td>';
359 print '<td>';
360 print $formaccounting->select_accounting_category($object->account_category, 'account_category', 1);
361 print '</td></tr>';
362
363 print '</table>';
364
365 print dol_get_fiche_end();
366
367 print $form->buttonsSaveCancel();
368
369 print '</form>';
370 } else {
371 // View mode
372 $linkback = '<a href="'.DOL_URL_ROOT.'/accountancy/admin/account.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
373
374 print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), -1, 'accounting_account');
375
376 dol_banner_tab($object, 'ref', $linkback, 1, 'account_number', 'ref');
377
378
379 print '<div class="fichecenter">';
380 print '<div class="underbanner clearboth"></div>';
381
382 print '<table class="border centpercent tableforfield">';
383
384 // Label
385 print '<tr><td class="titlefield">'.$langs->trans("Label").'</td>';
386 print '<td colspan="2">'.$object->label.'</td></tr>';
387
388 // Label to show
389 print '<tr><td class="titlefield">'.$langs->trans("LabelToShow").'</td>';
390 print '<td colspan="2">'.$object->labelshort.'</td></tr>';
391
392 // Account parent
393 $accp = new AccountingAccount($db);
394 if (!empty($object->account_parent)) {
395 $accp->fetch($object->account_parent, '');
396 }
397 print '<tr><td>'.$langs->trans("Accountparent").'</td>';
398 print '<td colspan="2">'.$accp->account_number.' - '.$accp->label.'</td></tr>';
399
400 // Group of accounting account
401 print '<tr><td>';
402 print $form->textwithpicto($langs->trans("Pcgtype"), $langs->transnoentitiesnoconv("PcgtypeDesc"));
403 print '</td>';
404 print '<td colspan="2">'.$object->pcg_type.'</td></tr>';
405
406 // Custom group of accounting account
407 print "<tr><td>";
408 print $form->textwithpicto($langs->trans("AccountingCategory"), $langs->transnoentitiesnoconv("AccountingAccountGroupsDesc"));
409 print "</td><td colspan='2'>".$object->account_category_label."</td>";
410
411 print '</table>';
412
413 print '</div>';
414
415 print dol_get_fiche_end();
416
417 /*
418 * Actions buttons
419 */
420 print '<div class="tabsAction">';
421
422 if ($user->hasRight('accounting', 'chartofaccount')) {
423 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=update&token='.newToken().'&id='.$object->id.'">'.$langs->trans('Modify').'</a>';
424 } else {
425 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans('Modify').'</a>';
426 }
427
428 // Delete
429 $permissiontodelete = $user->hasRight('accounting', 'chartofaccount');
430 print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), 'delete', $permissiontodelete);
431
432 print '</div>';
433 }
434 } else {
435 dol_print_error($db, $object->error, $object->errors);
436 }
437}
438
439// End of page
440llxFooter();
441$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:48
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
accounting_prepare_head(AccountingAccount $object)
Prepare array with list of tabs.
clean_account($account)
Return accounting account without zero on the right.
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
Class to manage accountancy systems.
Class to manage accounting accounts.
Class to manage generation of HTML components for accounting management.
Class to manage generation of HTML components Only common components must be here.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
dolGetButtonAction($label, $text='', $actionType='default', $url='', $id='', $userRight=1, $params=array())
Function dolGetButtonAction.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.