dolibarr 19.0.3
index.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2019-2023 Open-DSI <support@open-dsi.fr>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
24// Load Dolibarr environment
25require '../../main.inc.php';
26require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
27require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
28require_once DOL_DOCUMENT_ROOT.'/core/class/fiscalyear.class.php';
29require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
30require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
31
32// Load translation files required by the page
33$langs->loadLangs(array("compta", "bills", "other", "accountancy"));
34
35$action = GETPOST('action', 'aZ09');
36$confirm = GETPOST('confirm', 'aZ09');
37$fiscal_period_id = GETPOST('fiscal_period_id', 'int');
38$validatemonth = GETPOST('validatemonth', 'int');
39$validateyear = GETPOST('validateyear', 'int');
40
41// Security check
42if (!isModEnabled('accounting')) {
44}
45if ($user->socid > 0) {
47}
48if (!$user->hasRight('accounting', 'fiscalyear', 'write')) {
50}
51
52// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
53$hookmanager->initHooks(array('accountancyclosure'));
54
55$object = new BookKeeping($db);
56
57$now = dol_now();
58$fiscal_periods = $object->getFiscalPeriods();
59if (!is_array($fiscal_periods)) {
60 setEventMessages($object->error, $object->errors, 'errors');
61}
62
63$active_fiscal_periods = array();
64$last_fiscal_period = null;
65$current_fiscal_period = null;
66$next_fiscal_period = null;
67$next_active_fiscal_period = null;
68if (is_array($fiscal_periods)) {
69 foreach ($fiscal_periods as $fiscal_period) {
70 if (empty($fiscal_period['status'])) {
71 $active_fiscal_periods[] = $fiscal_period;
72 }
73 if (isset($current_fiscal_period)) {
74 if (!isset($next_fiscal_period)) {
75 $next_fiscal_period = $fiscal_period;
76 }
77 if (!isset($next_active_fiscal_period) && empty($fiscal_period['status'])) {
78 $next_active_fiscal_period = $fiscal_period;
79 }
80 } else {
81 if ($fiscal_period_id == $fiscal_period['id'] || (empty($fiscal_period_id) && $fiscal_period['date_start'] <= $now && $now <= $fiscal_period['date_end'])) {
82 $current_fiscal_period = $fiscal_period;
83 } else {
84 $last_fiscal_period = $fiscal_period;
85 }
86 }
87 }
88}
89
90$accounting_groups_used_for_balance_sheet_account = array_filter(array_map('trim', explode(',', getDolGlobalString('ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_BALANCE_SHEET_ACCOUNT'))), 'strlen');
91$accounting_groups_used_for_income_statement = array_filter(array_map('trim', explode(',', getDolGlobalString('ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_INCOME_STATEMENT'))), 'strlen');
92
93
94/*
95 * Actions
96 */
97
98$parameters = array('fiscal_periods' => $fiscal_periods, 'last_fiscal_period' => $last_fiscal_period, 'current_fiscal_period' => $current_fiscal_period, 'next_fiscal_period' => $next_fiscal_period);
99$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
100if ($reshook < 0) {
101 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
102}
103
104if (empty($reshook)) {
105 if (isset($current_fiscal_period) && $user->hasRight('accounting', 'fiscalyear', 'write')) {
106 if ($action == 'confirm_step_1' && $confirm == "yes") {
107 $date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int'));
108 $date_end = dol_mktime(23, 59, 59, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int'));
109
110 $result = $object->validateMovementForFiscalPeriod($date_start, $date_end);
111 if ($result > 0) {
112 setEventMessages($langs->trans("AllMovementsWereRecordedAsValidated"), null, 'mesgs');
113
114 header("Location: " . $_SERVER['PHP_SELF'] . (isset($current_fiscal_period) ? '?fiscal_period_id=' . $current_fiscal_period['id'] : ''));
115 exit;
116 } else {
117 setEventMessages($langs->trans("NotAllMovementsCouldBeRecordedAsValidated"), null, 'errors');
118 setEventMessages($object->error, $object->errors, 'errors');
119 $action = '';
120 }
121 } elseif ($action == 'confirm_step_2' && $confirm == "yes") {
122 $new_fiscal_period_id = GETPOST('new_fiscal_period_id', 'int');
123 $separate_auxiliary_account = GETPOST('separate_auxiliary_account', 'aZ09');
124 $generate_bookkeeping_records = GETPOST('generate_bookkeeping_records', 'aZ09');
125
126 $result = $object->closeFiscalPeriod($current_fiscal_period['id'], $new_fiscal_period_id, $separate_auxiliary_account, $generate_bookkeeping_records);
127 if ($result < 0) {
128 setEventMessages($object->error, $object->errors, 'errors');
129 } else {
130 setEventMessages($langs->trans("AccountancyClosureCloseSuccessfully"), null, 'mesgs');
131
132 header("Location: " . $_SERVER['PHP_SELF'] . (isset($current_fiscal_period) ? '?fiscal_period_id=' . $current_fiscal_period['id'] : ''));
133 exit;
134 }
135 } elseif ($action == 'confirm_step_3' && $confirm == "yes") {
136 $inventory_journal_id = GETPOST('inventory_journal_id', 'int');
137 $new_fiscal_period_id = GETPOST('new_fiscal_period_id', 'int');
138 $date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int'));
139 $date_end = dol_mktime(23, 59, 59, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int'));
140
141 $result = $object->insertAccountingReversal($current_fiscal_period['id'], $inventory_journal_id, $new_fiscal_period_id, $date_start, $date_end);
142 if ($result < 0) {
143 setEventMessages($object->error, $object->errors, 'errors');
144 } else {
145 setEventMessages($langs->trans("AccountancyClosureInsertAccountingReversalSuccessfully"), null, 'mesgs');
146
147 header("Location: " . $_SERVER['PHP_SELF'] . (isset($current_fiscal_period) ? '?fiscal_period_id=' . $current_fiscal_period['id'] : ''));
148 exit;
149 }
150 }
151 }
152}
153
154
155/*
156 * View
157 */
158
159$form = new Form($db);
160$formaccounting = new FormAccounting($db);
161
162$title = $langs->trans('Closure');
163
164$help_url ='EN:Module_Double_Entry_Accounting|FR:Module_Comptabilit&eacute;_en_Partie_Double#Cl.C3.B4ture_annuelle';
165
166llxHeader('', $title, $help_url);
167
168$formconfirm = '';
169
170if (isset($current_fiscal_period)) {
171 if ($action == 'step_1') {
172 $form_question = array();
173
174 $form_question['date_start'] = array(
175 'name' => 'date_start',
176 'type' => 'date',
177 'label' => $langs->trans('DateStart'),
178 'value' => $current_fiscal_period['date_start']
179 );
180 $form_question['date_end'] = array(
181 'name' => 'date_end',
182 'type' => 'date',
183 'label' => $langs->trans('DateEnd'),
184 'value' => $current_fiscal_period['date_end']
185 );
186
187 $formconfirm = $form->formconfirm(
188 $_SERVER["PHP_SELF"] . '?fiscal_period_id=' . $current_fiscal_period['id'],
189 $langs->trans('ValidateMovements'),
190 $langs->trans('DescValidateMovements', $langs->transnoentitiesnoconv("RegistrationInAccounting")),
191 'confirm_step_1',
192 $form_question,
193 '',
194 1,
195 300
196 );
197 } elseif ($action == 'step_2') {
198 $form_question = array();
199
200 $fiscal_period_arr = array();
201 foreach ($active_fiscal_periods as $info) {
202 $fiscal_period_arr[$info['id']] = $info['label'];
203 }
204 $form_question['new_fiscal_period_id'] = array(
205 'name' => 'new_fiscal_period_id',
206 'type' => 'select',
207 'label' => $langs->trans('AccountancyClosureStep3NewFiscalPeriod'),
208 'values' => $fiscal_period_arr,
209 'default' => isset($next_active_fiscal_period) ? $next_active_fiscal_period['id'] : '',
210 );
211 $form_question['generate_bookkeeping_records'] = array(
212 'name' => 'generate_bookkeeping_records',
213 'type' => 'checkbox',
214 'label' => $langs->trans('AccountancyClosureGenerateClosureBookkeepingRecords'),
215 'value' => 1
216 );
217 $form_question['separate_auxiliary_account'] = array(
218 'name' => 'separate_auxiliary_account',
219 'type' => 'checkbox',
220 'label' => $langs->trans('AccountancyClosureSeparateAuxiliaryAccounts'),
221 'value' => 0
222 );
223
224 $formconfirm = $form->formconfirm(
225 $_SERVER["PHP_SELF"] . '?fiscal_period_id=' . $current_fiscal_period['id'],
226 $langs->trans('AccountancyClosureClose'),
227 $langs->trans('AccountancyClosureConfirmClose'),
228 'confirm_step_2',
229 $form_question,
230 '',
231 1,
232 300
233 );
234 } elseif ($action == 'step_3') {
235 $form_question = array();
236
237 $form_question['inventory_journal_id'] = array(
238 'name' => 'inventory_journal_id',
239 'type' => 'other',
240 'label' => $langs->trans('InventoryJournal'),
241 'value' => $formaccounting->select_journal(0, "inventory_journal_id", 8, 1, 0, 0)
242 );
243 $fiscal_period_arr = array();
244 foreach ($active_fiscal_periods as $info) {
245 $fiscal_period_arr[$info['id']] = $info['label'];
246 }
247 $form_question['new_fiscal_period_id'] = array(
248 'name' => 'new_fiscal_period_id',
249 'type' => 'select',
250 'label' => $langs->trans('AccountancyClosureStep3NewFiscalPeriod'),
251 'values' => $fiscal_period_arr,
252 'default' => isset($next_active_fiscal_period) ? $next_active_fiscal_period['id'] : '',
253 );
254 $form_question['date_start'] = array(
255 'name' => 'date_start',
256 'type' => 'date',
257 'label' => $langs->trans('DateStart'),
258 'value' => dol_time_plus_duree($current_fiscal_period['date_end'], -1, 'm')
259 );
260 $form_question['date_end'] = array(
261 'name' => 'date_end',
262 'type' => 'date',
263 'label' => $langs->trans('DateEnd'),
264 'value' => $current_fiscal_period['date_end']
265 );
266
267 $formconfirm = $form->formconfirm(
268 $_SERVER["PHP_SELF"] . '?fiscal_period_id=' . $current_fiscal_period['id'],
269 $langs->trans('AccountancyClosureAccountingReversal'),
270 $langs->trans('AccountancyClosureConfirmAccountingReversal'),
271 'confirm_step_3',
272 $form_question,
273 '',
274 1,
275 300
276 );
277 }
278}
279
280// Call Hook formConfirm
281$parameters = array('formConfirm' => $formconfirm, 'fiscal_periods' => $fiscal_periods, 'last_fiscal_period' => $last_fiscal_period, 'current_fiscal_period' => $current_fiscal_period, 'next_fiscal_period' => $next_fiscal_period);
282$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
283if (empty($reshook)) {
284 $formconfirm .= $hookmanager->resPrint;
285} elseif ($reshook > 0) {
286 $formconfirm = $hookmanager->resPrint;
287}
288
289// Print form confirm
290print $formconfirm;
291
292$fiscal_period_nav_text = $langs->trans("FiscalPeriod");
293
294$fiscal_period_nav_text .= '&nbsp;<a href="' . (isset($last_fiscal_period) ? $_SERVER["PHP_SELF"] . '?fiscal_period_id=' . $last_fiscal_period['id'] : '#" class="disabled') . '">' . img_previous() . '</a>';
295$fiscal_period_nav_text .= '&nbsp;<a href="' . (isset($next_fiscal_period) ? $_SERVER["PHP_SELF"] . '?fiscal_period_id=' . $next_fiscal_period['id'] : '#" class="disabled') . '">' . img_next() . '</a>';
296if (!empty($current_fiscal_period)) {
297 $fiscal_period_nav_text .= $current_fiscal_period['label'].' &nbsp;(' . (isset($current_fiscal_period) ? dol_print_date($current_fiscal_period['date_start'], 'day') . '&nbsp;-&nbsp;' . dol_print_date($current_fiscal_period['date_end'], 'day') . ')' : '');
298}
299
300print load_fiche_titre($langs->trans("Closure") . " - " . $fiscal_period_nav_text, '', 'title_accountancy');
301
302if (empty($current_fiscal_period)) {
303 print $langs->trans('ErrorNoFiscalPeriodActiveFound');
304}
305
306if (isset($current_fiscal_period)) {
307 // Step 1
308 $head = array();
309 $head[0][0] = DOL_URL_ROOT . '/accountancy/closure/index.php?fiscal_period_id=' . $current_fiscal_period['id'];
310 $head[0][1] = $langs->trans("AccountancyClosureStep1");
311 $head[0][2] = 'step1';
312 print dol_get_fiche_head($head, 'step1', '', -1, 'title_accountancy');
313
314 print '<span class="opacitymedium">' . $langs->trans("AccountancyClosureStep1Desc") . '</span><br>';
315
316 $count_by_month = $object->getCountByMonthForFiscalPeriod($current_fiscal_period['date_start'], $current_fiscal_period['date_end']);
317 if (!is_array($count_by_month)) {
318 setEventMessages($object->error, $object->errors, 'errors');
319 }
320
321 if (empty($count_by_month['total'])) {
322 $buttonvalidate = '<a class="butActionRefused classfortooltip" href="#">' . $langs->trans("ValidateMovements") . '</a>';
323 } else {
324 $buttonvalidate = '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?action=step_1&fiscal_period_id=' . $current_fiscal_period['id'] . '">' . $langs->trans("ValidateMovements") . '</a>';
325 }
326 print_barre_liste($langs->trans("OverviewOfMovementsNotValidated"), '', '', '', '', '', '', -1, '', '', 0, $buttonvalidate, '', 0, 1, 0);
327
328 print '<div class="div-table-responsive-no-min">';
329 print '<table class="noborder centpercent">';
330
331 print '<tr class="liste_titre">';
332 $nb_years = is_array($count_by_month['list']) ? count($count_by_month['list']) : 0;
333 if ($nb_years > 1) {
334 print '<td class="right">' . $langs->trans("Year") . '</td>';
335 }
336 for ($i = 1; $i <= 12; $i++) {
337 print '<td class="right">' . $langs->trans('MonthShort' . str_pad($i, 2, '0', STR_PAD_LEFT)) . '</td>';
338 }
339 print '<td class="right"><b>' . $langs->trans("Total") . '</b></td>';
340 print '</tr>';
341
342 if (is_array($count_by_month['list'])) {
343 foreach ($count_by_month['list'] as $info) {
344 print '<tr class="oddeven">';
345 if ($nb_years > 1) {
346 print '<td class="right">' . $info['year'] . '</td>';
347 }
348 for ($i = 1; $i <= 12; $i++) {
349 print '<td class="right">' . ((int) $info['count'][$i]) . '</td>';
350 }
351 print '<td class="right"><b>' . $info['total'] . '</b></td></tr>';
352 }
353 }
354
355 print "</table>\n";
356 print '</div>';
357
358 // Step 2
359 $head = array();
360 $head[0][0] = DOL_URL_ROOT . '/accountancy/closure/index.php?fiscal_period_id=' . $current_fiscal_period['id'];
361 $head[0][1] = $langs->trans("AccountancyClosureStep2");
362 $head[0][2] = 'step2';
363 print dol_get_fiche_head($head, 'step2', '', -1, 'title_accountancy');
364
365 // print '<span class="opacitymedium">' . $langs->trans("AccountancyClosureStep2Desc") . '</span><br>';
366
367 if (empty($count_by_month['total']) && empty($current_fiscal_period['status'])) {
368 $button = '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?action=step_2&fiscal_period_id=' . $current_fiscal_period['id'] . '">' . $langs->trans("AccountancyClosureClose") . '</a>';
369 } else {
370 $button = '<a class="butActionRefused classfortooltip" href="#">' . $langs->trans("AccountancyClosureClose") . '</a>';
371 }
372 print_barre_liste('', '', '', '', '', '', '', -1, '', '', 0, $button, '', 0, 1, 0);
373
374 // Step 3
375 $head = array();
376 $head[0][0] = DOL_URL_ROOT . '/accountancy/closure/index.php?fiscal_period_id=' . $current_fiscal_period['id'];
377 $head[0][1] = $langs->trans("AccountancyClosureStep3");
378 $head[0][2] = 'step3';
379 print dol_get_fiche_head($head, 'step3', '', -1, 'title_accountancy');
380
381 // print '<span class="opacitymedium">' . $langs->trans("AccountancyClosureStep3Desc") . '</span><br>';
382
383 if (empty($current_fiscal_period['status'])) {
384 $button = '<a class="butActionRefused classfortooltip" href="#">' . $langs->trans("AccountancyClosureAccountingReversal") . '</a>';
385 } else {
386 $button = '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?action=step_3&fiscal_period_id=' . $current_fiscal_period['id'] . '">' . $langs->trans("AccountancyClosureAccountingReversal") . '</a>';
387 }
388 print_barre_liste('', '', '', '', '', '', '', -1, '', '', 0, $button, '', 0, 1, 0);
389}
390
391// End of page
392llxFooter();
393$db->close();
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Definition wrapper.php:55
llxFooter()
Empty footer.
Definition wrapper.php:69
Class to manage Ledger (General Ledger and Subledger)
Class to manage generation of HTML components for accounting management.
Class to manage generation of HTML components Only common components must be here.
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition date.lib.php:124
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
load_fiche_titre($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_now($mode='auto')
Return date for now.
img_previous($titlealt='default', $moreatt='')
Show previous logo.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $hideselectlimit=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
img_next($titlealt='default', $moreatt='')
Show next logo.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.