diff --git a/htdocs/accountancy/closure/index.html b/htdocs/accountancy/closure/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/accountancy/closure/index.php b/htdocs/accountancy/closure/index.php new file mode 100644 index 00000000000..9786734ab82 --- /dev/null +++ b/htdocs/accountancy/closure/index.php @@ -0,0 +1,416 @@ + + * + * 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/customer/index.php + * \ingroup Accountancy + * \brief Home closure page + */ + +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 . '/accountancy/class/bookkeeping.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("compta","bills","other","main","accountancy")); + +// Security check +if (empty($conf->accounting->enabled)) { + accessforbidden(); +} +if ($user->societe_id > 0) + accessforbidden(); +if (! $user->rights->accounting->closure->read) + accessforbidden(); + + +$month_start= ($conf->global->SOCIETE_FISCAL_MONTH_START?($conf->global->SOCIETE_FISCAL_MONTH_START):1); +if (GETPOST("year", 'int')) $year_start = GETPOST("year", 'int'); +else +{ + $year_start = dol_print_date(dol_now(), '%Y'); + if (dol_print_date(dol_now(), '%m') < $month_start) $year_start--; // If current month is lower that starting fiscal month, we start last year +} +$year_end = $year_start + 1; +$month_end = $month_start - 1; +if ($month_end < 1) +{ + $month_end = 12; + $year_end--; +} +$search_date_start = dol_mktime(0, 0, 0, $month_start, 1, $year_start); +$search_date_end = dol_get_last_day($year_end, $month_end); +$year_current = $year_start; + +// Validate History +$action = GETPOST('action', 'aZ09'); + + +/* + * Actions + */ + +if ($action == 'clean' || $action == 'validatehistory') +{ + // Clean database + $db->begin(); + $sql1 = "UPDATE " . MAIN_DB_PREFIX . "facturedet as fd"; + $sql1 .= " SET fk_code_ventilation = 0"; + $sql1 .= ' WHERE fd.fk_code_ventilation NOT IN'; + $sql1 .= ' (SELECT accnt.rowid '; + $sql1 .= ' FROM ' . MAIN_DB_PREFIX . 'accounting_account as accnt'; + $sql1 .= ' INNER JOIN ' . MAIN_DB_PREFIX . 'accounting_system as syst'; + $sql1 .= ' ON accnt.fk_pcg_version = syst.pcg_version AND syst.rowid=' . $conf->global->CHARTOFACCOUNTS . ' AND accnt.entity = '.$conf->entity.')'; + $sql1 .= ' AND fd.fk_facture IN (SELECT rowid FROM ' . MAIN_DB_PREFIX . 'facture WHERE entity = '.$conf->entity.')'; + $sql1 .= ' AND fk_code_ventilation <> 0'; + + dol_syslog("htdocs/accountancy/customer/index.php fixaccountancycode", LOG_DEBUG); + $resql1 = $db->query($sql1); + if (! $resql1) { + $error ++; + $db->rollback(); + setEventMessages($db->lasterror(), null, 'errors'); + } else { + $db->commit(); + } + // End clean database +} + +if ($action == 'validatehistory') { + + $error = 0; + $db->begin(); + + // Now make the binding. Bind automatically only for product with a dedicated account that exists into chart of account, others need a manual bind + if ($db->type == 'pgsql') { + $sql1 = "UPDATE " . MAIN_DB_PREFIX . "facturedet"; + $sql1 .= " SET fk_code_ventilation = accnt.rowid"; + $sql1 .= " FROM " . MAIN_DB_PREFIX . "product as p, " . MAIN_DB_PREFIX . "accounting_account as accnt , " . MAIN_DB_PREFIX . "accounting_system as syst"; + $sql1 .= " WHERE " . MAIN_DB_PREFIX . "facturedet.fk_product = p.rowid AND accnt.fk_pcg_version = syst.pcg_version AND syst.rowid=" . $conf->global->CHARTOFACCOUNTS.' AND accnt.entity = '.$conf->entity; + $sql1 .= " AND accnt.active = 1 AND p.accountancy_code_sell=accnt.account_number"; + $sql1 .= " AND " . MAIN_DB_PREFIX . "facturedet.fk_code_ventilation = 0"; + } else { + $sql1 = "UPDATE " . MAIN_DB_PREFIX . "facturedet as fd, " . MAIN_DB_PREFIX . "product as p, " . MAIN_DB_PREFIX . "accounting_account as accnt , " . MAIN_DB_PREFIX . "accounting_system as syst"; + $sql1 .= " SET fk_code_ventilation = accnt.rowid"; + $sql1 .= " WHERE fd.fk_product = p.rowid AND accnt.fk_pcg_version = syst.pcg_version AND syst.rowid=" . $conf->global->CHARTOFACCOUNTS.' AND accnt.entity = '.$conf->entity; + $sql1 .= " AND accnt.active = 1 AND p.accountancy_code_sell=accnt.account_number"; + $sql1 .= " AND fd.fk_code_ventilation = 0"; + } + + dol_syslog('htdocs/accountancy/customer/index.php'); + + $resql1 = $db->query($sql1); + if (! $resql1) { + $error ++; + $db->rollback(); + setEventMessages($db->lasterror(), null, 'errors'); + } else { + $db->commit(); + setEventMessages($langs->trans('AutomaticBindingDone'), null, 'mesgs'); + } +} + + +/* + * View + */ + +llxHeader('', $langs->trans("CustomersVentilation")); + +$textprevyear = '' . img_previous() . ''; +$textnextyear = ' ' . img_next() . ''; + + +print load_fiche_titre($langs->trans("CustomersVentilation") . " " . $textprevyear . " " . $langs->trans("Year") . " " . $year_start . " " . $textnextyear, '', 'title_accountancy'); + +print $langs->trans("DescVentilCustomer") . '
'; +print $langs->trans("DescVentilMore", $langs->transnoentitiesnoconv("ValidateHistory"), $langs->transnoentitiesnoconv("ToBind")) . '
'; +print '
'; + + +$y = $year_current; + +$buttonbind = '' . $langs->trans("ValidateHistory") . ''; + +print_barre_liste($langs->trans("OverviewOfAmountOfLinesNotBound"), '', '', '', '', '', '', -1, '', '', 0, $buttonbind, '', 0, 1, 1); +//print load_fiche_titre($langs->trans("OverviewOfAmountOfLinesNotBound"), $buttonbind, ''); + +print '
'; +print ''; +print ''; +print ''; +for($i = 1; $i <= 12; $i ++) { + $j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START?$conf->global->SOCIETE_FISCAL_MONTH_START:1) - 1; + if ($j > 12) $j-=12; + print ''; +} +print ''; + +$sql = "SELECT " . $db->ifsql('aa.account_number IS NULL', "'tobind'", 'aa.account_number') . " AS codecomptable,"; +$sql .= " " . $db->ifsql('aa.label IS NULL', "'tobind'", 'aa.label') . " AS intitule,"; +for($i = 1; $i <= 12; $i ++) { + $j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START?$conf->global->SOCIETE_FISCAL_MONTH_START:1) - 1; + if ($j > 12) $j-=12; + $sql .= " SUM(" . $db->ifsql('MONTH(f.datef)=' . $j, 'fd.total_ht', '0') . ") AS month" . str_pad($j, 2, '0', STR_PAD_LEFT) . ","; +} +$sql .= " SUM(fd.total_ht) as total"; +$sql .= " FROM " . MAIN_DB_PREFIX . "facturedet as fd"; +$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "facture as f ON f.rowid = fd.fk_facture"; +$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.rowid = fd.fk_code_ventilation"; +$sql .= " WHERE f.datef >= '" . $db->idate($search_date_start) . "'"; +$sql .= " AND f.datef <= '" . $db->idate($search_date_end) . "'"; +$sql .= " AND f.fk_statut > 0"; +$sql .= " AND f.entity IN (" . getEntity('invoice', 0) . ")"; // We don't share object for accountancy +$sql .= " AND aa.account_number IS NULL"; +if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_REPLACEMENT . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_SITUATION . ")"; +} else { + $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_REPLACEMENT . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_DEPOSIT . "," . Facture::TYPE_SITUATION . ")"; +} +$sql .= " GROUP BY fd.fk_code_ventilation,aa.account_number,aa.label"; + +dol_syslog('htdocs/accountancy/customer/index.php sql=' . $sql, LOG_DEBUG); +$resql = $db->query($sql); +if ($resql) { + $num = $db->num_rows($resql); + + while ( $row = $db->fetch_row($resql)) { + + print ''; + print ''; + for($i = 2; $i <= 12; $i ++) { + print ''; + } + print ''; + print ''; + print ''; + } + $db->free($resql); +} else { + print $db->lasterror(); // Show last sql error +} +print "
' . $langs->trans("Account") . '' . $langs->trans("Label") . '' . $langs->trans('MonthShort' . str_pad($j, 2, '0', STR_PAD_LEFT)) . '' . $langs->trans("Total") . '
'; + if ($row[0] == 'tobind') + { + print $langs->trans("Unknown"); + } + else print length_accountg($row[0]); + print ''; + if ($row[0] == 'tobind') + { + print $langs->trans("UseMenuToSetBindindManualy", DOL_URL_ROOT.'/accountancy/customer/list.php?search_year='.$y, $langs->transnoentitiesnoconv("ToBind")); + } + else print $row[1]; + print '' . price($row[$i]) . '' . price($row[13]) . '' . price($row[14]) . '
\n"; +print '
'; + + +print '
'; + + +print_barre_liste($langs->trans("OverviewOfAmountOfLinesBound"), '', '', '', '', '', '', -1, '', '', 0, '', '', 0, 1, 1); +//print load_fiche_titre($langs->trans("OverviewOfAmountOfLinesBound"), '', ''); + +print '
'; +print ''; +print ''; +print ''; +for($i = 1; $i <= 12; $i ++) { + $j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START?$conf->global->SOCIETE_FISCAL_MONTH_START:1) - 1; + if ($j > 12) $j-=12; + print ''; +} +print ''; + +$sql = "SELECT " . $db->ifsql('aa.account_number IS NULL', "'tobind'", 'aa.account_number') . " AS codecomptable,"; +$sql .= " " . $db->ifsql('aa.label IS NULL', "'tobind'", 'aa.label') . " AS intitule,"; +for($i = 1; $i <= 12; $i ++) { + $j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START?$conf->global->SOCIETE_FISCAL_MONTH_START:1) - 1; + if ($j > 12) $j-=12; + $sql .= " SUM(" . $db->ifsql('MONTH(f.datef)=' . $j, 'fd.total_ht', '0') . ") AS month" . str_pad($j, 2, '0', STR_PAD_LEFT) . ","; +} +$sql .= " SUM(fd.total_ht) as total"; +$sql .= " FROM " . MAIN_DB_PREFIX . "facturedet as fd"; +$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "facture as f ON f.rowid = fd.fk_facture"; +$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.rowid = fd.fk_code_ventilation"; +$sql .= " WHERE f.datef >= '" . $db->idate($search_date_start) . "'"; +$sql .= " AND f.datef <= '" . $db->idate($search_date_end) . "'"; +$sql .= " AND f.entity IN (" . getEntity('invoice', 0) . ")"; // We don't share object for accountancy +$sql .= " AND f.fk_statut > 0"; +if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_REPLACEMENT . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_SITUATION . ")"; +} else { + $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_REPLACEMENT . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_DEPOSIT . "," . Facture::TYPE_SITUATION . ")"; +} +$sql .= " AND aa.account_number IS NOT NULL"; +$sql .= " GROUP BY fd.fk_code_ventilation,aa.account_number,aa.label"; + +dol_syslog('htdocs/accountancy/customer/index.php'); +$resql = $db->query($sql); +if ($resql) { + $num = $db->num_rows($resql); + + while ( $row = $db->fetch_row($resql)) { + + print ''; + + print ''; + + for($i = 2; $i <= 12; $i++) { + print ''; + } + print ''; + print ''; + print ''; + } + $db->free($resql); +} else { + print $db->lasterror(); // Show last sql error +} +print "
' . $langs->trans("Account") . '' . $langs->trans("Label") . '' . $langs->trans('MonthShort' . str_pad($j, 2, '0', STR_PAD_LEFT)) . '' . $langs->trans("Total") . '
'; + if ($row[0] == 'tobind') + { + print $langs->trans("Unknown"); + } + else print length_accountg($row[0]); + print ''; + if ($row[0] == 'tobind') + { + print $langs->trans("UseMenuToSetBindindManualy", DOL_URL_ROOT.'/accountancy/customer/list.php?search_year='.$y, $langs->transnoentitiesnoconv("ToBind")); + } + else print $row[1]; + print '' . price($row[$i]) . '' . price($row[13]) . '' . price($row[14]) . '
\n"; +print '
'; + + +if ($conf->global->MAIN_FEATURES_LEVEL > 0) // This part of code looks strange. Why showing a report that should rely on result of this step ? +{ + print '
'; + print '
'; + + print_barre_liste($langs->trans("OtherInfo"), '', '', '', '', '', '', -1, '', '', 0, '', '', 0, 1, 1); + //print load_fiche_titre($langs->trans("OtherInfo"), '', ''); + + print '
'; + print ''; + print ''; + for($i = 1; $i <= 12; $i ++) { + $j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START?$conf->global->SOCIETE_FISCAL_MONTH_START:1) - 1; + if ($j > 12) $j-=12; + print ''; + } + print ''; + + $sql = "SELECT '" . $langs->trans("TotalVente") . "' AS total,"; + for($i = 1; $i <= 12; $i ++) { + $j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START?$conf->global->SOCIETE_FISCAL_MONTH_START:1) - 1; + if ($j > 12) $j-=12; + $sql .= " SUM(" . $db->ifsql('MONTH(f.datef)=' . $j, 'fd.total_ht', '0') . ") AS month" . str_pad($j, 2, '0', STR_PAD_LEFT) . ","; + } + $sql .= " SUM(fd.total_ht) as total"; + $sql .= " FROM " . MAIN_DB_PREFIX . "facturedet as fd"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "facture as f ON f.rowid = fd.fk_facture"; + $sql .= " WHERE f.datef >= '" . $db->idate($search_date_start) . "'"; + $sql .= " AND f.datef <= '" . $db->idate($search_date_end) . "'"; + $sql .= " AND f.entity IN (" . getEntity('invoice', 0) . ")"; // We don't share object for accountancy + $sql .= " AND f.fk_statut > 0"; + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_REPLACEMENT . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_SITUATION . ")"; + } else { + $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_REPLACEMENT . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_DEPOSIT . "," . Facture::TYPE_SITUATION . ")"; + } + + dol_syslog('htdocs/accountancy/customer/index.php'); + $resql = $db->query($sql); + if ($resql) { + $num = $db->num_rows($resql); + + while ($row = $db->fetch_row($resql)) { + print ''; + for($i = 1; $i <= 12; $i ++) { + print ''; + } + print ''; + print ''; + } + $db->free($resql); + } else { + print $db->lasterror(); // Show last sql error + } + print "
' . $langs->trans("TotalVente") . '' . $langs->trans('MonthShort' . str_pad($j, 2, '0', STR_PAD_LEFT)) . '' . $langs->trans("Total") . '
' . $row[0] . '' . price($row[$i]) . '' . price($row[13]) . '
\n"; + print '
'; + + + if (! empty($conf->margin->enabled)) { + print "
\n"; + print '
'; + print ''; + print ''; + for($i = 1; $i <= 12; $i ++) { + $j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START?$conf->global->SOCIETE_FISCAL_MONTH_START:1) - 1; + if ($j > 12) $j-=12; + print ''; + } + print ''; + + $sql = "SELECT '" . $langs->trans("Vide") . "' AS marge,"; + for($i = 1; $i <= 12; $i ++) { + $j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START?$conf->global->SOCIETE_FISCAL_MONTH_START:1) - 1; + if ($j > 12) $j-=12; + $sql .= " SUM(" . $db->ifsql('MONTH(f.datef)=' . $j, '(fd.total_ht-(fd.qty * fd.buy_price_ht))', '0') . ") AS month" . str_pad($j, 2, '0', STR_PAD_LEFT) . ","; + } + $sql .= " SUM((fd.total_ht-(fd.qty * fd.buy_price_ht))) as total"; + $sql .= " FROM " . MAIN_DB_PREFIX . "facturedet as fd"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "facture as f ON f.rowid = fd.fk_facture"; + $sql .= " WHERE f.datef >= '" . $db->idate($search_date_start) . "'"; + $sql .= " AND f.datef <= '" . $db->idate($search_date_end) . "'"; + $sql .= " AND f.entity IN (" . getEntity('invoice', 0) . ")"; // We don't share object for accountancy + $sql .= " AND f.fk_statut > 0"; + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_REPLACEMENT . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_SITUATION . ")"; + } else { + $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_REPLACEMENT . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_DEPOSIT . "," . Facture::TYPE_SITUATION . ")"; + } + + dol_syslog('htdocs/accountancy/customer/index.php'); + $resql = $db->query($sql); + if ($resql) { + $num = $db->num_rows($resql); + + while ($row = $db->fetch_row($resql)) { + + print ''; + for($i = 1; $i <= 12; $i ++) { + print ''; + } + print ''; + print ''; + } + $db->free($resql); + } else { + print $db->lasterror(); // Show last sql error + } + print "
' . $langs->trans("TotalMarge") . '' . $langs->trans('MonthShort' . str_pad($j, 2, '0', STR_PAD_LEFT)) . '' . $langs->trans("Total") . '
' . $row[0] . '' . price(price2num($row[$i])) . '' . price(price2num($row[13])) . '
\n"; + print '
'; + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 7491556bebd..9382e3d4984 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1303,9 +1303,9 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM $newmenu->add("/compta/resultat/index.php?mainmenu=accountancy&leftmenu=accountancy_report", $langs->trans("Reportings"), 1, $user->rights->accounting->comptarapport->lire, '', $mainmenu, 'ca'); - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_report/', $leftmenu)) { + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_report/', $leftmenu)) { $newmenu->add("/compta/resultat/index.php?leftmenu=accountancy_report", $langs->trans("MenuReportInOut"), 2, $user->rights->accounting->comptarapport->lire); - $newmenu->add("/compta/resultat/clientfourn.php?leftmenu=accountancy_report", $langs->trans("ByPredefinedAccountGroups"), 3, $user->rights->accounting->comptarapport->lire); + $newmenu->add("/compta/resultat/clientfourn.php?leftmenu=accountancy_report", $langs->trans("ByPredefinedAccountGroups"), 3, $user->rights->accounting->comptarapport->lire); $newmenu->add("/compta/resultat/result.php?leftmenu=accountancy_report", $langs->trans("ByPersonalizedAccountGroups"), 3, $user->rights->accounting->comptarapport->lire); } @@ -1335,6 +1335,15 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM } } + // Closure + if (! empty($conf->global->MAIN_FEATURES_LEVEL) && $conf->global->MAIN_FEATURES_LEVEL >= 2) { + $newmenu->add("/accountancy/closure/index.php?mainmenu=accountancy&leftmenu=accountancy_closure", $langs->trans("Closure"), 1, $user->rights->accounting->closure->read, '', $mainmenu, 'closure'); + + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_closure/', $leftmenu)) { + $newmenu->add("/accountancy/closure/validation.php?leftmenu=accountancy_closure", $langs->trans("MenuAccountancyValidationMovements"), 2, $user->rights->accounting->closure->read); + } + } + // Accountancy (simple) if (! empty($conf->comptabilite->enabled)) {