28require
'../../main.inc.php';
36require_once DOL_DOCUMENT_ROOT.
'/core/lib/date.lib.php';
37require_once DOL_DOCUMENT_ROOT.
'/core/lib/accounting.lib.php';
38require_once DOL_DOCUMENT_ROOT.
'/core/class/fiscalyear.class.php';
39require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formaccounting.class.php';
40require_once DOL_DOCUMENT_ROOT.
'/accountancy/class/bookkeeping.class.php';
43$langs->loadLangs(array(
"accountancy",
"bills",
"compta",
"exports",
"other"));
45$action =
GETPOST(
'action',
'aZ09');
46$confirm =
GETPOST(
'confirm',
'aZ09');
47$fiscal_period_id =
GETPOSTINT(
'fiscal_period_id');
55if ($user->socid > 0) {
58if (!$user->hasRight(
'accounting',
'fiscalyear',
'write')) {
63$hookmanager->initHooks(array(
'accountancyclosure'));
68$fiscal_periods =
$object->getFiscalPeriods();
69if (!is_array($fiscal_periods)) {
74$active_fiscal_periods = array();
75$first_active_fiscal_period =
null;
76$last_fiscal_period =
null;
77$current_fiscal_period =
null;
78$next_fiscal_period =
null;
79$next_active_fiscal_period =
null;
80if (is_array($fiscal_periods)) {
81 foreach ($fiscal_periods as $fiscal_period) {
82 if (empty($first_active_fiscal_period) && empty($fiscal_period[
'status'])) {
83 $first_active_fiscal_period = $fiscal_period;
85 if (empty($fiscal_period[
'status'])) {
86 $active_fiscal_periods[] = $fiscal_period;
88 if (isset($current_fiscal_period)) {
89 if (!isset($next_fiscal_period)) {
90 $next_fiscal_period = $fiscal_period;
92 if (!isset($next_active_fiscal_period) && empty($fiscal_period[
'status'])) {
93 $next_active_fiscal_period = $fiscal_period;
97 if (!empty($fiscal_period_id) && $fiscal_period_id == $fiscal_period[
'id']) {
98 $current_fiscal_period = $fiscal_period;
100 $last_fiscal_period = $fiscal_period;
107if (empty($current_fiscal_period) && !empty($first_active_fiscal_period)) {
108 $current_fiscal_period = $first_active_fiscal_period;
109 $last_fiscal_period =
null;
110 $foundcurrent =
false;
111 foreach ($fiscal_periods as $fiscal_period) {
113 $next_fiscal_period = $fiscal_period;
116 if ($fiscal_period[
'id'] == $current_fiscal_period[
'id']) {
117 $foundcurrent =
true;
119 if (!$foundcurrent) {
120 $last_fiscal_period = $fiscal_period;
125$accounting_groups_used_for_balance_sheet_account = array_filter(array_map(
'trim', explode(
',',
getDolGlobalString(
'ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_BALANCE_SHEET_ACCOUNT'))),
'strlen');
126$accounting_groups_used_for_income_statement = array_filter(array_map(
'trim', explode(
',',
getDolGlobalString(
'ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_INCOME_STATEMENT'))),
'strlen');
133$parameters = array(
'fiscal_periods' => $fiscal_periods,
'last_fiscal_period' => $last_fiscal_period,
'current_fiscal_period' => $current_fiscal_period,
'next_fiscal_period' => $next_fiscal_period);
134$reshook = $hookmanager->executeHooks(
'doActions', $parameters, $object, $action);
139if (empty($reshook)) {
140 if (isset($current_fiscal_period)) {
141 if ($action ==
'confirm_step_1' && $confirm ==
"yes" && $user->hasRight(
'accounting',
'fiscalyear',
'write')) {
147 setEventMessages($langs->trans(
"AllMovementsWereRecordedAsValidated"),
null,
'mesgs');
149 header(
"Location: " . $_SERVER[
'PHP_SELF'] .
'?fiscal_period_id=' . $current_fiscal_period[
'id']);
152 setEventMessages($langs->trans(
"NotAllMovementsCouldBeRecordedAsValidated"),
null,
'errors');
156 } elseif ($action ==
'confirm_step_2' && $confirm ==
"yes" && $user->hasRight(
'accounting',
'fiscalyear',
'write')) {
157 $new_fiscal_period_id =
GETPOSTINT(
'new_fiscal_period_id');
158 $separate_auxiliary_account = (!empty(
GETPOST(
'separate_auxiliary_account')) ? 1 : 0);
159 $generate_bookkeeping_records = (!empty(
GETPOST(
'generate_bookkeeping_records')) ? 1 : 0);
162 if ($generate_bookkeeping_records) {
163 if (!
getDolGlobalString(
'ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_BALANCE_SHEET_ACCOUNT')) {
165 setEventMessages($langs->trans(
"ErrorAccountingClosureSetupNotComplete"),
null,
'errors');
166 } elseif (!
getDolGlobalString(
'ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_INCOME_STATEMENT')) {
168 setEventMessages($langs->trans(
"ErrorAccountingClosureSetupNotComplete"),
null,
'errors');
173 $result =
$object->closeFiscalPeriod($current_fiscal_period[
'id'], $new_fiscal_period_id, (
bool) $separate_auxiliary_account, (
bool) $generate_bookkeeping_records);
177 setEventMessages($langs->trans(
"AccountancyClosureCloseSuccessfully"),
null,
'mesgs');
179 header(
"Location: " . $_SERVER[
'PHP_SELF'] .
'?fiscal_period_id=' . $current_fiscal_period[
'id']);
183 } elseif ($action ==
'confirm_step_3' && $confirm ==
"yes" && $user->hasRight(
'accounting',
'fiscalyear',
'write')) {
184 $inventory_journal_id =
GETPOSTINT(
'inventory_journal_id');
185 $new_fiscal_period_id =
GETPOSTINT(
'new_fiscal_period_id');
189 $result =
$object->insertAccountingReversal($current_fiscal_period[
'id'], $inventory_journal_id, $new_fiscal_period_id,
$date_start, $date_end);
193 setEventMessages($langs->trans(
"AccountancyClosureInsertAccountingReversalSuccessfully"),
null,
'mesgs');
195 header(
"Location: " . $_SERVER[
'PHP_SELF'] .
'?fiscal_period_id=' . $current_fiscal_period[
'id']);
210$title = $langs->trans(
'Closure');
212$help_url =
'EN:Module_Double_Entry_Accounting|FR:Module_Comptabilité_en_Partie_Double#Cl.C3.B4ture_annuelle';
214llxHeader(
'', $title, $help_url,
'', 0, 0,
'',
'',
'',
'mod-accountancy page-closure-index');
218if (isset($current_fiscal_period)) {
219 if ($action ==
'step_1') {
220 $form_question = array();
222 $form_question[
'date_start'] = array(
223 'name' =>
'date_start',
225 'label' => $langs->trans(
'DateStart'),
226 'value' => $current_fiscal_period[
'date_start']
228 $form_question[
'date_end'] = array(
229 'name' =>
'date_end',
231 'label' => $langs->trans(
'DateEnd'),
232 'value' => $current_fiscal_period[
'date_end']
235 $formconfirm = $form->formconfirm(
236 $_SERVER[
"PHP_SELF"] .
'?fiscal_period_id=' . $current_fiscal_period[
'id'],
237 $langs->trans(
'ValidateMovements'),
238 $langs->trans(
'DescValidateMovements', $langs->transnoentitiesnoconv(
"RegistrationInAccounting")),
246 } elseif ($action ==
'step_2') {
247 $form_question = array();
249 $fiscal_period_arr = array();
250 foreach ($active_fiscal_periods as $info) {
251 $fiscal_period_arr[$info[
'id']] = $info[
'label'];
253 $form_question[
'new_fiscal_period_id'] = array(
254 'name' =>
'new_fiscal_period_id',
256 'label' => $langs->trans(
'AccountancyClosureStep3NewFiscalPeriod'),
257 'values' => $fiscal_period_arr,
258 'default' => isset($next_active_fiscal_period) ? $next_active_fiscal_period[
'id'] :
'',
260 $form_question[
'generate_bookkeeping_records'] = array(
261 'name' =>
'generate_bookkeeping_records',
262 'type' =>
'checkbox',
263 'label' => $langs->trans(
'AccountancyClosureGenerateClosureBookkeepingRecords'),
266 $form_question[
'separate_auxiliary_account'] = array(
267 'name' =>
'separate_auxiliary_account',
268 'type' =>
'checkbox',
269 'label' => $langs->trans(
'AccountancyClosureSeparateAuxiliaryAccounts'),
273 $formconfirm = $form->formconfirm(
274 $_SERVER[
"PHP_SELF"] .
'?fiscal_period_id=' . $current_fiscal_period[
'id'],
275 $langs->trans(
'AccountancyClosureClose'),
276 $langs->trans(
'AccountancyClosureConfirmClose'),
284 } elseif ($action ==
'step_3') {
285 $form_question = array();
287 $form_question[
'inventory_journal_id'] = array(
288 'name' =>
'inventory_journal_id',
290 'label' => $langs->trans(
'InventoryJournal'),
291 'value' => $formaccounting->select_journal(
'0',
"inventory_journal_id", 8, 1, 0, 0)
293 $fiscal_period_arr = array();
294 foreach ($active_fiscal_periods as $info) {
295 $fiscal_period_arr[$info[
'id']] = $info[
'label'];
297 $form_question[
'new_fiscal_period_id'] = array(
298 'name' =>
'new_fiscal_period_id',
300 'label' => $langs->trans(
'AccountancyClosureStep3NewFiscalPeriod'),
301 'values' => $fiscal_period_arr,
302 'default' => isset($next_active_fiscal_period) ? $next_active_fiscal_period[
'id'] :
'',
304 $form_question[
'date_start'] = array(
305 'name' =>
'date_start',
307 'label' => $langs->trans(
'DateStart'),
310 $form_question[
'date_end'] = array(
311 'name' =>
'date_end',
313 'label' => $langs->trans(
'DateEnd'),
314 'value' => $current_fiscal_period[
'date_end']
317 $formconfirm = $form->formconfirm(
318 $_SERVER[
"PHP_SELF"] .
'?fiscal_period_id=' . $current_fiscal_period[
'id'],
319 $langs->trans(
'AccountancyClosureAccountingReversal'),
320 $langs->trans(
'AccountancyClosureConfirmAccountingReversal'),
332$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);
333$reshook = $hookmanager->executeHooks(
'formConfirm', $parameters, $object, $action);
334if (empty($reshook)) {
335 $formconfirm .= $hookmanager->resPrint;
336} elseif ($reshook > 0) {
337 $formconfirm = $hookmanager->resPrint;
343$fiscal_period_nav_text = $langs->trans(
"FiscalPeriod");
345if (!empty($current_fiscal_period)) {
346 $fiscal_period_nav_text .=
' '.$current_fiscal_period[
'label'].
' (' .
dol_print_date($current_fiscal_period[
'date_start'],
'day') .
' - ' . ($current_fiscal_period[
'date_end'] ?
dol_print_date($current_fiscal_period[
'date_end'],
'day') :
'?').
')';
348$fiscal_period_nav_text .=
' ';
349$fiscal_period_nav_text .=
'<a href="' . (isset($last_fiscal_period) ? $_SERVER[
"PHP_SELF"] .
'?fiscal_period_id=' . $last_fiscal_period[
'id'] :
'#" class="disabled') .
'">' .
img_previous() .
'</a>';
350$fiscal_period_nav_text .=
' ';
351$fiscal_period_nav_text .=
'<a href="' . (isset($next_fiscal_period) ? $_SERVER[
"PHP_SELF"] .
'?fiscal_period_id=' . $next_fiscal_period[
'id'] :
'#" class="disabled') .
'">' .
img_next() .
'</a>';
353print
load_fiche_titre($langs->trans(
"Closure") .
" - " . $fiscal_period_nav_text,
'',
'title_accountancy');
355if (empty($current_fiscal_period)) {
356 print $langs->trans(
'ErrorNoFiscalPeriodActiveFound', $langs->transnoentitiesnoconv(
"Accounting"), $langs->transnoentitiesnoconv(
"Setup"), $langs->transnoentitiesnoconv(
"FiscalPeriod"));
361 $head[0][0] = DOL_URL_ROOT .
'/accountancy/closure/index.php?fiscal_period_id=' . $current_fiscal_period[
'id'];
362 $head[0][1] = $langs->trans(
"Step").
' 1 - '.$langs->trans(
"AccountancyClosureStep1");
363 $head[0][2] =
'step1';
368 $count_by_month =
$object->getCountByMonthForFiscalPeriod((
int) $current_fiscal_period[
'date_start'], (
int) $current_fiscal_period[
'date_end']);
370 if (!is_array($count_by_month)) {
374 if (empty($count_by_month[
'total'])) {
375 $buttonvalidate =
'<a class="butActionRefused classfortooltip" href="#">' . $langs->trans(
"ValidateMovements") .
'</a>';
377 $buttonvalidate =
'<a class="butAction" href="' . $_SERVER[
"PHP_SELF"] .
'?action=step_1&token='.newToken().
'&fiscal_period_id=' . $current_fiscal_period[
'id'] .
'">' . $langs->trans(
"ValidateMovements") .
'</a>';
379 print_barre_liste($langs->trans(
"OverviewOfMovementsNotValidated"), 0,
'',
'',
'',
'',
'', -1,
'',
'', 0, $buttonvalidate,
'', 0, 1, 0);
381 print
'<div class="div-table-responsive-no-min">';
382 print
'<table class="noborder centpercent">';
384 print
'<tr class="liste_titre">';
385 $nb_years = is_array($count_by_month[
'list']) ? count($count_by_month[
'list']) : 0;
387 print
'<td class="right">' . $langs->trans(
"Year") .
'</td>';
389 for ($i = 1; $i <= 12; $i++) {
390 print
'<td class="right">' . $langs->trans(
'MonthShort' . str_pad((
string) $i, 2,
'0', STR_PAD_LEFT)) .
'</td>';
392 print
'<td class="right"><b>' . $langs->trans(
"Total") .
'</b></td>';
395 if (is_array($count_by_month[
'list']) && count($count_by_month[
'list']) > 0) {
396 foreach ($count_by_month[
'list'] as $info) {
397 print
'<tr class="oddeven">';
399 print
'<td class="right">' . $info[
'year'] .
'</td>';
401 for ($i = 1; $i <= 12; $i++) {
402 print
'<td class="right">' . ((int) $info[
'count'][$i]) .
'</td>';
404 print
'<td class="right"><b>' . $info[
'total'] .
'</b></td>';
408 print
'<tr class="oddeven"><td colspan="' . (12 + ($nb_years > 1 ? 1 : 0) + 1) .
'">';
409 print
'<span class="opacitymedium">';
410 print $langs->trans(
"None");
423 $head[0][0] = DOL_URL_ROOT .
'/accountancy/closure/index.php?fiscal_period_id=' . $current_fiscal_period[
'id'];
424 $head[0][1] = $langs->trans(
"Step").
' ' . (
getDolGlobalString(
"ACCOUNTANCY_DISABLE_CLOSURE_LINE_BY_LINE") ?
'1' :
'2').
' - '.$langs->trans(
"AccountancyClosureStep2");
425 $head[0][2] =
'step2';
430 if ((empty($count_by_month[
'total']) ||
getDolGlobalString(
"ACCOUNTANCY_DISABLE_CLOSURE_LINE_BY_LINE")) && empty($current_fiscal_period[
'status'])) {
432 $button =
'<a class="butAction" href="' . $_SERVER[
"PHP_SELF"] .
'?action=step_2&token='.newToken().
'&fiscal_period_id=' . $current_fiscal_period[
'id'] .
'">' . $langs->trans(
"AccountancyClosureClose") .
'</a>';
434 if (!empty($current_fiscal_period[
'status'])) {
435 $button =
'<a class="butActionRefused classfortooltip" href="#" title="The period is already closed. Feature disabled.">' . $langs->trans(
"AccountancyClosureClose") .
'</a>';
436 } elseif (!empty($count_by_month[
'total'])) {
437 $button =
'<a class="butActionRefused classfortooltip" href="#" title="There is some lines not yet locked. Feature disabled.">' . $langs->trans(
"AccountancyClosureClose") .
'</a>';
440 print_barre_liste(
'', 0,
'',
'',
'',
'',
'', -1,
'',
'', 0, $button,
'', 0, 1, 0);
446 $head[0][0] = DOL_URL_ROOT .
'/accountancy/closure/index.php?fiscal_period_id=' . $current_fiscal_period[
'id'];
447 $head[0][1] = $langs->trans(
"Step").
' ' . (
getDolGlobalString(
"ACCOUNTANCY_DISABLE_CLOSURE_LINE_BY_LINE") ?
'2' :
'3').
' - '.$langs->trans(
"AccountancyClosureStep3");
448 $head[0][2] =
'step3';
453 if (empty($current_fiscal_period[
'status'])) {
454 $button =
'<a class="butActionRefused classfortooltip" href="#">' . $langs->trans(
"AccountancyClosureAccountingReversal") .
'</a>';
456 $button =
'<a class="butAction" href="' . $_SERVER[
"PHP_SELF"] .
'?action=step_3&token='.newToken().
'&fiscal_period_id=' . $current_fiscal_period[
'id'] .
'">' . $langs->trans(
"AccountancyClosureAccountingReversal") .
'</a>';
458 print_barre_liste(
'', 0,
'',
'',
'',
'',
'', -1,
'',
'', 0, $button,
'', 0, 1, 0);
if(! $sortfield) if(! $sortorder) $object
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
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.
Class to manage Ledger (General Ledger and Subledger)
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
$date_start
Variables from include:
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
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.
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.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
img_next($titlealt='default', $moreatt='')
Show next logo.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.