*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/**
* \file htdocs/accountancy/closure/index.php
* \ingroup Accountancy
* \brief Home closure page
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/fiscalyear.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
// Load translation files required by the page
$langs->loadLangs(array("compta", "bills", "other", "accountancy"));
$action = GETPOST('action', 'aZ09');
$confirm = GETPOST('confirm', 'aZ09');
$fiscal_period_id = GETPOST('fiscal_period_id', 'int');
$validatemonth = GETPOST('validatemonth', 'int');
$validateyear = GETPOST('validateyear', 'int');
// Security check
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
accessforbidden();
}
if (!$user->hasRight('accounting', 'fiscalyear', 'write')) {
accessforbidden();
}
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$hookmanager->initHooks(array('accountancyclosure'));
$object = new BookKeeping($db);
$now = dol_now();
$fiscal_periods = $object->getFiscalPeriods();
if (!is_array($fiscal_periods)) {
setEventMessages($object->error, $object->errors, 'errors');
}
$active_fiscal_periods = array();
$last_fiscal_period = null;
$current_fiscal_period = null;
$next_fiscal_period = null;
$next_active_fiscal_period = null;
if (is_array($fiscal_periods)) {
foreach ($fiscal_periods as $fiscal_period) {
if (empty($fiscal_period['status'])) {
$active_fiscal_periods[] = $fiscal_period;
}
if (isset($current_fiscal_period)) {
if (!isset($next_fiscal_period)) {
$next_fiscal_period = $fiscal_period;
}
if (!isset($next_active_fiscal_period) && empty($fiscal_period['status'])) {
$next_active_fiscal_period = $fiscal_period;
}
} else {
if ($fiscal_period_id == $fiscal_period['id'] || (empty($fiscal_period_id) && $fiscal_period['date_start'] <= $now && $now <= $fiscal_period['date_end'])) {
$current_fiscal_period = $fiscal_period;
} else {
$last_fiscal_period = $fiscal_period;
}
}
}
}
$accounting_groups_used_for_balance_sheet_account = array_filter(array_map('trim', explode(',', getDolGlobalString('ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_BALANCE_SHEET_ACCOUNT'))), 'strlen');
$accounting_groups_used_for_income_statement = array_filter(array_map('trim', explode(',', getDolGlobalString('ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_INCOME_STATEMENT'))), 'strlen');
/*
* Actions
*/
$parameters = array('fiscal_periods' => $fiscal_periods, 'last_fiscal_period' => $last_fiscal_period, 'current_fiscal_period' => $current_fiscal_period, 'next_fiscal_period' => $next_fiscal_period);
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
}
if (empty($reshook)) {
if (isset($current_fiscal_period) && $user->hasRight('accounting', 'fiscalyear', 'write')) {
if ($action == 'confirm_step_1' && $confirm == "yes") {
$date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int'));
$date_end = dol_mktime(23, 59, 59, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int'));
$result = $object->validateMovementForFiscalPeriod($date_start, $date_end);
if ($result > 0) {
setEventMessages($langs->trans("AllMovementsWereRecordedAsValidated"), null, 'mesgs');
header("Location: " . $_SERVER['PHP_SELF'] . (isset($current_fiscal_period) ? '?fiscal_period_id=' . $current_fiscal_period['id'] : ''));
exit;
} else {
setEventMessages($langs->trans("NotAllMovementsCouldBeRecordedAsValidated"), null, 'errors');
setEventMessages($object->error, $object->errors, 'errors');
$action = '';
}
} elseif ($action == 'confirm_step_2' && $confirm == "yes") {
$new_fiscal_period_id = GETPOST('new_fiscal_period_id', 'int');
$separate_auxiliary_account = GETPOST('separate_auxiliary_account', 'aZ09');
$generate_bookkeeping_records = GETPOST('generate_bookkeeping_records', 'aZ09');
$result = $object->closeFiscalPeriod($current_fiscal_period['id'], $new_fiscal_period_id, $separate_auxiliary_account, $generate_bookkeeping_records);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
} else {
setEventMessages($langs->trans("AccountancyClosureCloseSuccessfully"), null, 'mesgs');
header("Location: " . $_SERVER['PHP_SELF'] . (isset($current_fiscal_period) ? '?fiscal_period_id=' . $current_fiscal_period['id'] : ''));
exit;
}
} elseif ($action == 'confirm_step_3' && $confirm == "yes") {
$inventory_journal_id = GETPOST('inventory_journal_id', 'int');
$new_fiscal_period_id = GETPOST('new_fiscal_period_id', 'int');
$date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int'));
$date_end = dol_mktime(23, 59, 59, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int'));
$result = $object->insertAccountingReversal($current_fiscal_period['id'], $inventory_journal_id, $new_fiscal_period_id, $date_start, $date_end);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
} else {
setEventMessages($langs->trans("AccountancyClosureInsertAccountingReversalSuccessfully"), null, 'mesgs');
header("Location: " . $_SERVER['PHP_SELF'] . (isset($current_fiscal_period) ? '?fiscal_period_id=' . $current_fiscal_period['id'] : ''));
exit;
}
}
}
}
/*
* View
*/
$form = new Form($db);
$formaccounting = new FormAccounting($db);
$title = $langs->trans('Closure');
$help_url ='EN:Module_Double_Entry_Accounting';
llxHeader('', $title, $help_url);
$formconfirm = '';
if (isset($current_fiscal_period)) {
if ($action == 'step_1') {
$form_question = array();
$form_question['date_start'] = array(
'name' => 'date_start',
'type' => 'date',
'label' => $langs->trans('DateStart'),
'value' => $current_fiscal_period['date_start']
);
$form_question['date_end'] = array(
'name' => 'date_end',
'type' => 'date',
'label' => $langs->trans('DateEnd'),
'value' => $current_fiscal_period['date_end']
);
$formconfirm = $form->formconfirm(
$_SERVER["PHP_SELF"] . '?fiscal_period_id=' . $current_fiscal_period['id'],
$langs->trans('ValidateMovements'),
$langs->trans('DescValidateMovements', $langs->transnoentitiesnoconv("RegistrationInAccounting")),
'confirm_step_1',
$form_question,
'',
1,
300
);
} elseif ($action == 'step_2') {
$form_question = array();
$fiscal_period_arr = array();
foreach ($active_fiscal_periods as $info) {
$fiscal_period_arr[$info['id']] = $info['label'];
}
$form_question['new_fiscal_period_id'] = array(
'name' => 'new_fiscal_period_id',
'type' => 'select',
'label' => $langs->trans('AccountancyClosureStep3NewFiscalPeriod'),
'values' => $fiscal_period_arr,
'default' => isset($next_active_fiscal_period) ? $next_active_fiscal_period['id'] : '',
);
$form_question['generate_bookkeeping_records'] = array(
'name' => 'generate_bookkeeping_records',
'type' => 'checkbox',
'label' => $langs->trans('AccountancyClosureGenerateClosureBookkeepingRecords'),
'value' => 1
);
$form_question['separate_auxiliary_account'] = array(
'name' => 'separate_auxiliary_account',
'type' => 'checkbox',
'label' => $langs->trans('AccountancyClosureSeparateAuxiliaryAccounts'),
'value' => 0
);
$formconfirm = $form->formconfirm(
$_SERVER["PHP_SELF"] . '?fiscal_period_id=' . $current_fiscal_period['id'],
$langs->trans('AccountancyClosureClose'),
$langs->trans('AccountancyClosureConfirmClose'),
'confirm_step_2',
$form_question,
'',
1,
300
);
} elseif ($action == 'step_3') {
$form_question = array();
$form_question['inventory_journal_id'] = array(
'name' => 'inventory_journal_id',
'type' => 'other',
'label' => $langs->trans('InventoryJournal'),
'value' => $formaccounting->select_journal(0, "inventory_journal_id", 8, 1, 0, 0)
);
$fiscal_period_arr = array();
foreach ($active_fiscal_periods as $info) {
$fiscal_period_arr[$info['id']] = $info['label'];
}
$form_question['new_fiscal_period_id'] = array(
'name' => 'new_fiscal_period_id',
'type' => 'select',
'label' => $langs->trans('AccountancyClosureStep3NewFiscalPeriod'),
'values' => $fiscal_period_arr,
'default' => isset($next_active_fiscal_period) ? $next_active_fiscal_period['id'] : '',
);
$form_question['date_start'] = array(
'name' => 'date_start',
'type' => 'date',
'label' => $langs->trans('DateStart'),
'value' => dol_time_plus_duree($current_fiscal_period['date_end'], -1, 'm')
);
$form_question['date_end'] = array(
'name' => 'date_end',
'type' => 'date',
'label' => $langs->trans('DateEnd'),
'value' => $current_fiscal_period['date_end']
);
$formconfirm = $form->formconfirm(
$_SERVER["PHP_SELF"] . '?fiscal_period_id=' . $current_fiscal_period['id'],
$langs->trans('AccountancyClosureAccountingReversal'),
$langs->trans('AccountancyClosureConfirmAccountingReversal'),
'confirm_step_3',
$form_question,
'',
1,
300
);
}
}
// Call Hook formConfirm
$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);
$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
if (empty($reshook)) {
$formconfirm .= $hookmanager->resPrint;
} elseif ($reshook > 0) {
$formconfirm = $hookmanager->resPrint;
}
// Print form confirm
print $formconfirm;
$fiscal_period_nav_text = $langs->trans("FiscalPeriod");
$fiscal_period_nav_text .= ' ' . img_previous() . '';
$fiscal_period_nav_text .= ' ' . img_next() . '';
if (!empty($current_fiscal_period)) {
$fiscal_period_nav_text .= $current_fiscal_period['label'].' (' . (isset($current_fiscal_period) ? dol_print_date($current_fiscal_period['date_start'], 'day') . ' - ' . dol_print_date($current_fiscal_period['date_end'], 'day') . ')' : '');
}
print load_fiche_titre($langs->trans("Closure") . " - " . $fiscal_period_nav_text, '', 'title_accountancy');
if (empty($current_fiscal_period)) {
print $langs->trans('ErrorNoFiscalPeriodActiveFound');
}
if (isset($current_fiscal_period)) {
// Step 1
$head = array();
$head[0][0] = DOL_URL_ROOT . '/accountancy/closure/index.php?fiscal_period_id=' . $current_fiscal_period['id'];
$head[0][1] = $langs->trans("AccountancyClosureStep1");
$head[0][2] = 'step1';
print dol_get_fiche_head($head, 'step1', '', -1, 'title_accountancy');
print '' . $langs->trans("AccountancyClosureStep1Desc") . '
';
$count_by_month = $object->getCountByMonthForFiscalPeriod($current_fiscal_period['date_start'], $current_fiscal_period['date_end']);
if (!is_array($count_by_month)) {
setEventMessages($object->error, $object->errors, 'errors');
}
if (empty($count_by_month['total'])) {
$buttonvalidate = '' . $langs->trans("ValidateMovements") . '';
} else {
$buttonvalidate = '' . $langs->trans("ValidateMovements") . '';
}
print_barre_liste($langs->trans("OverviewOfMovementsNotValidated"), '', '', '', '', '', '', -1, '', '', 0, $buttonvalidate, '', 0, 1, 0);
print '
';
print '
';
print '';
$nb_years = is_array($count_by_month['list']) ? count($count_by_month['list']) : 0;
if ($nb_years > 1) {
print '| ' . $langs->trans("Year") . ' | ';
}
for ($i = 1; $i <= 12; $i++) {
print '' . $langs->trans('MonthShort' . str_pad($i, 2, '0', STR_PAD_LEFT)) . ' | ';
}
print '' . $langs->trans("Total") . ' | ';
print '
';
if (is_array($count_by_month['list'])) {
foreach ($count_by_month['list'] as $info) {
print '';
if ($nb_years > 1) {
print '| ' . $info['year'] . ' | ';
}
for ($i = 1; $i <= 12; $i++) {
print '' . ((int) $info['count'][$i]) . ' | ';
}
print '' . $info['total'] . ' |
';
}
}
print "
\n";
print '
';
// Step 2
$head = array();
$head[0][0] = DOL_URL_ROOT . '/accountancy/closure/index.php?fiscal_period_id=' . $current_fiscal_period['id'];
$head[0][1] = $langs->trans("AccountancyClosureStep2");
$head[0][2] = 'step2';
print dol_get_fiche_head($head, 'step2', '', -1, 'title_accountancy');
// print '' . $langs->trans("AccountancyClosureStep2Desc") . '
';
if (empty($count_by_month['total']) && empty($current_fiscal_period['status'])) {
$button = '' . $langs->trans("AccountancyClosureClose") . '';
} else {
$button = '' . $langs->trans("AccountancyClosureClose") . '';
}
print_barre_liste('', '', '', '', '', '', '', -1, '', '', 0, $button, '', 0, 1, 0);
// Step 3
$head = array();
$head[0][0] = DOL_URL_ROOT . '/accountancy/closure/index.php?fiscal_period_id=' . $current_fiscal_period['id'];
$head[0][1] = $langs->trans("AccountancyClosureStep3");
$head[0][2] = 'step3';
print dol_get_fiche_head($head, 'step3', '', -1, 'title_accountancy');
// print '' . $langs->trans("AccountancyClosureStep3Desc") . '
';
if (empty($current_fiscal_period['status'])) {
$button = '' . $langs->trans("AccountancyClosureAccountingReversal") . '';
} else {
$button = '' . $langs->trans("AccountancyClosureAccountingReversal") . '';
}
print_barre_liste('', '', '', '', '', '', '', -1, '', '', 0, $button, '', 0, 1, 0);
}
// End of page
llxFooter();
$db->close();