Skip to content

Commit

Permalink
- Fixed display error in the Cashflow report.
Browse files Browse the repository at this point in the history
- Added a new summary section to improve budget report.
closes #7897
  • Loading branch information
lomamech committed Dec 11, 2024
1 parent 60f0e55 commit d05f4f5
Show file tree
Hide file tree
Showing 29 changed files with 397 additions and 37 deletions.
1 change: 1 addition & 0 deletions client/src/i18n/en/form.json
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@
"BILLING_DATE": "Billing Date",
"BREAK_EVEN": "Break Even",
"BUDGET": "Budget",
"BUDGET_ANALYSIS": "Budget analysis",
"BULK_QUANTITY": "Bulk quantity",
"BY": "by",
"BY_ID": "By Id",
Expand Down
3 changes: 3 additions & 0 deletions client/src/i18n/en/report.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,14 @@
"EXPENSES": "Expenses",
"HIDE_TITLE_ACCOUNT": "Hide Title Account",
"HIDE_UNUSED_ACCOUNTS": "Hide Unused Accounts or Accounts with Zero Values",
"INCLUDE_SUMMARY_SECTION": "Include summary section",
"MAX_5_YEAR": "Please note that the budget analysis period is limited to a maximum of 5 years.",
"PERCENTAGE_VARIATION_COMPARED": "Percentage Variation Compared to the Budget",
"REALIZATION" : "Actuals",
"REVENUS": "Income",
"SET_NUMBER_YEAR": "Set the Number of Years for Analysis",
"SHOW_ONLY_TITLE_ACCOUNT": "Display Only the Title Account",
"SUMMARY_SECTION": "Summary section",
"VARIATION_IN_AMOUNT": "Variation in Amount"
},
"BY_ASC": "By Ascending Order",
Expand Down Expand Up @@ -135,6 +137,7 @@
"TITLE": "Configurable Analysis Report"
},
"CONFIGURATION": "Report Configuration",
"CONSIDER_TRANSFER_MOVEMENTS_REVENUE": "Consider transfer movements as revenue.",
"DELETE": "Delete Report",
"DOWNLOAD": "Download",
"EMPLOYEE_STANDING": {
Expand Down
4 changes: 4 additions & 0 deletions client/src/i18n/en/table.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
"LAST_PAYMENT": "Last Payment",
"LISTS": "Registered price list",
"LOADING": "Fetching data from the server.",
"LOCAL_CASH_REVENUES": "Local Cash Revenues",
"LOCKED": "Locked",
"LOCKEDQ": "Locked?",
"LOT": "Lot / Batch",
Expand Down Expand Up @@ -228,6 +229,7 @@
"RESULT": "Result",
"RESULTS": "Results",
"RESULT_ACCOUNT_SCT": "Result Account section",
"RESULT_WITHOUT_ACCOUNTS": "Result Without Accounts:",
"RUBRICS": "Rubrics",
"SEE_SITUATION_ALL_EMPLOYEES": "See the overall situation of all employees",
"SECTOR": "Sector",
Expand Down Expand Up @@ -258,9 +260,11 @@
"TOTAL_DEBT": "Total Debt",
"TOTAL_DISTRIBUTE": "Total Distributions",
"TOTAL_DISTRIBUTION_COST": "Total distribution cost",
"TOTAL_FINANCEMENT": "Total financement",
"TOTAL_GENERAL": "Total General",
"TOTAL_INVOICE": "Total invoice",
"TOTAL_MEDICAL_CARE_EMPLOYEE": "Total medical care provided to the employee",
"TOTAL_SUBSIDIES": "Total subsidies",
"TOTAL_UNICORPORATED_CHARGE": "Total unincorporated cost",
"TOTAL_UNICORPORARED_PRODUCT": "Total unincorporated product",
"TRANSACTION": "Transaction",
Expand Down
1 change: 1 addition & 0 deletions client/src/i18n/en/vouchers.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"SUPPORT_INCOME": "Support Incomes",
"TITLE": "Simple Voucher",
"TRANSFER": "Money Transfer",
"TRANSFER_MONEY_DISBURSEMENT": "Money Disbursement",
"TRANSFER_PATIENT_INVOICE_AMOUNT": "Patient Invoice Debt Transfer",
"STOCK_INTEGRATION" : "Stock Integration",
"STOCK_EXIT":"Stock Exit",
Expand Down
1 change: 1 addition & 0 deletions client/src/i18n/fr/form.json
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@
"BILLING_DATE": "Date Facturation",
"BREAK_EVEN": "Seuil de rentabilité",
"BUDGET": "Budget",
"BUDGET_ANALYSIS": "Analyse du budget",
"BULK_QUANTITY": "Quantité en vrac",
"BY_ID": "Par id",
"BY_NAME": "Par nom",
Expand Down
3 changes: 3 additions & 0 deletions client/src/i18n/fr/report.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,14 @@
"EXPENSES": "Dépenses",
"HIDE_TITLE_ACCOUNT": "Cacher le compte de titre",
"HIDE_UNUSED_ACCOUNTS": "Cacher le compte non utilisé ou dont les valeurs sont égales à zéro",
"INCLUDE_SUMMARY_SECTION": "Inclure une section récapitulative",
"MAX_5_YEAR": "Veuillez noter que la période d'analyse budgétaire est limitée à un maximum de 5 années.",
"PERCENTAGE_VARIATION_COMPARED": "Variation en pourcentage par rapport au budget",
"REALIZATION" : "Réalisation",
"REVENUS": "Revenus",
"SET_NUMBER_YEAR": "Définir le Nombre d'années pour l'Analyse",
"SHOW_ONLY_TITLE_ACCOUNT": "Afficher uniquement le compte de titre",
"SUMMARY_SECTION": "Section récapitulative",
"VARIATION_IN_AMOUNT": "Variation en chiffre"
},
"BY_ASC": "Par ordre croissant",
Expand Down Expand Up @@ -117,6 +119,7 @@
"TITLE": "Rapport d'analyse configurable"
},
"CONFIGURATION" : "Configuration rapport",
"CONSIDER_TRANSFER_MOVEMENTS_REVENUE": "Considérer les mouvements de transfert comme des recettes.",
"DELETE" : "Supprimer un rapport",
"DOWNLOAD" : "Télécharger",
"EMPLOYEE_STANDING" : {
Expand Down
4 changes: 4 additions & 0 deletions client/src/i18n/fr/table.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
"LAST_PAYMENT": "Derniere Paiement",
"LISTS": "Liste des prix enregistrés",
"LOADING": "Récupération des données à partir du serveur.",
"LOCAL_CASH_REVENUES": "Recettes locales",
"LOCKED": "Bloquée",
"LOCKEDQ": "Bloquée ?",
"LONGITUDE": "Longitude",
Expand Down Expand Up @@ -228,6 +229,7 @@
"RESULT": "Résultat",
"RESULTS": "Résultats",
"RESULT_ACCOUNT_SCT": "Section Compte Résultat",
"RESULT_WITHOUT_ACCOUNTS": "Résultat sans les comptes:",
"RUBRICS": "Rubriques",
"SEE_SITUATION_ALL_EMPLOYEES": "Voir la situation globale de tous les employés",
"SECTOR": "Secteur",
Expand Down Expand Up @@ -259,8 +261,10 @@
"TOTAL_GENERAL": "Total général",
"TOTAL_DISTRIBUTE": "Total de répartition",
"TOTAL_DISTRIBUTION_COST": "Total du coût de la distribution",
"TOTAL_FINANCEMENT": "Total financement",
"TOTAL_INVOICE": "Total de la facture",
"TOTAL_MEDICAL_CARE_EMPLOYEE": "Total des soins médicaux accordés à l'employé",
"TOTAL_SUBSIDIES": "Total subventions",
"TOTAL_UNICORPORATED_CHARGE": "Total charge non incorporé",
"TOTAL_UNICORPORARED_PRODUCT": "Total produit non incorporé",
"TRANSACTION": "Transaction",
Expand Down
1 change: 1 addition & 0 deletions client/src/i18n/fr/vouchers.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"SUPPORT_INCOME": "Paiement Prise en charge",
"TITLE": "Bordereau de transfert",
"TRANSFER": "Transfert d'argent",
"TRANSFER_MONEY_DISBURSEMENT": "Transfert: Décaissement d'argent",
"TRANSFER_PATIENT_INVOICE_AMOUNT": "Prise en Charge de Facture de Patient",
"STOCK_INTEGRATION" : "Intégration Stock",
"STOCK_EXIT":"Sortie de stock",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ function BudgetReportController($sce, Notify, SavedReports, AppCache, reportData
filter : 'default',
};

vm.reportDetails.include_summary_section = 0;

vm.previewGenerated = false;
checkCachedConfiguration();

Expand All @@ -31,13 +33,29 @@ function BudgetReportController($sce, Notify, SavedReports, AppCache, reportData
vm.reportDetails = angular.copy(report);
};

vm.onChangeIncludeSection = value => {
if (value === 0) {
vm.reportDetails.cashboxesIds = [];
}

vm.reportDetails.include_summary_section = value;
};

vm.onSelectCashboxes = (cashboxesIds) => {
vm.reportDetails.cashboxesIds = cashboxesIds;
};

vm.numberYears = [
{ id : 1 }, { id : 2 }, { id : 3 }, { id : 4 }, { id : 5 },
];

vm.preview = function preview(form) {
if (form.$invalid) { return null; }

if (vm.reportDetails.include_summary_section === 0) {
vm.reportDetails.cashboxesIds = [];
}

// update cached configuration
cache.reportDetails = angular.copy(vm.reportDetails);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,21 @@ <h3 class="text-capitalize" translate>REPORT.BUDGET_REPORT.TITLE</h3>
</div>
</div>

<bh-yes-no-radios
label="REPORT.BUDGET_REPORT.INCLUDE_SUMMARY_SECTION"
value="ReportConfigCtrl.reportDetails.include_summary_section"
name="include_summary_section"
on-change-callback="ReportConfigCtrl.onChangeIncludeSection(value)">
</bh-yes-no-radios>

<div ng-if="ReportConfigCtrl.reportDetails.include_summary_section === 1">
<bh-multiple-cashbox-select
cashbox-ids="ReportConfigCtrl.reportDetails.cashboxes"
on-change="ReportConfigCtrl.onSelectCashboxes(cashboxes)"
required="true">
</bh-multiple-cashbox-select>
</div>

<bh-loading-button loading-state="ConfigForm.$loading">
<span translate>REPORT.UTIL.PREVIEW</span>
</bh-loading-button>
Expand Down
9 changes: 9 additions & 0 deletions client/src/modules/reports/generate/cashflow/cashflow.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ <h3 class="text-capitalize" translate>REPORT.CASHFLOW.TITLE</h3>
required="true">
</bh-multiple-cashbox-select>

<div class="form-group">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="ReportConfigCtrl.reportDetails.is_transfer_as_revenue" ng-true-value="1" ng-false-value="0">
<span translate>REPORT.CONSIDER_TRANSFER_MOVEMENTS_REVENUE</span>
</label>
</div>
</div>

<div class="panel-body">
<div class="radio">
<label class="radio-inline">
Expand Down
129 changes: 127 additions & 2 deletions server/controllers/finance/reports/budget_analytical/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@ exports.report = report;
*/
async function report(req, res, next) {
const params = req.query;

const fiscalYearId = parseInt(params.fiscal_id, 10);
const setNumberYear = parseInt(params.set_number_year, 10) + 1;
const colspanValue = parseInt(params.set_number_year, 10) + 6;
const hideUnused = parseInt(params.hide_unused, 10);
const { enterprise } = req.session;
const includeSummarySection = parseInt(params.include_summary_section, 10);

const ACCOUNT_TYPES_INCOME = 4;
const ACCOUNT_TYPES_EXPENSE = 5;

let totalBudgetIncome = 0;
let totalRealisationIncome = 0;
Expand All @@ -31,6 +36,11 @@ async function report(req, res, next) {
let totalBudgetExpense = 0;
let totalRealisationExpense = 0;
let totalVariationExpense = 0;
let totalFinancement = 0;
let cashLabelDetails;

let firstIncomeDescription;
let secondIncomeDescription;

const optionReport = _.extend(params, {
csvKey : 'rows',
Expand All @@ -43,9 +53,89 @@ async function report(req, res, next) {
const reportColumn = [];
const reportFootColumIncome = [];
const reportFootColumExpense = [];
let configurationReferences = [];

const fiscalYear = await Fiscal.lookupFiscalYear(fiscalYearId);

if (includeSummarySection) {
const cashboxesIds = _.values(params.cashboxesIds);

const query = `
SELECT
cac.currency_id, cac.account_id, c.id, c.label, cur.symbol,
a.number AS account_number, a.label AS account_label
FROM cash_box c
JOIN cash_box_account_currency cac ON cac.cash_box_id = c.id
JOIN currency cur ON cur.id = cac.currency_id
JOIN account a ON a.id = cac.account_id
WHERE c.id IN ? ORDER BY c.id;
`;

const cashboxes = await db.exec(query, [[cashboxesIds]]);
const cashAccountIds = cashboxes.map(cashbox => cashbox.account_id);
cashLabelDetails = cashboxes.map(
cashbox => `${cashbox.account_number} - ${cashbox.account_label}`);

const sqlTotalIncomeCash = `
SELECT gl.trans_id, gl.trans_date, a.number, a.label, gl.debit_equiv, gl.credit_equiv, tt.text, tt.type,
SUM(gl.debit_equiv - gl.credit_equiv) AS balance
FROM general_ledger AS gl
JOIN account AS a ON a.id = gl.account_id
JOIN transaction_type AS tt ON tt.id = gl.transaction_type_id
WHERE gl.account_id IN ? AND gl.fiscal_year_id = ? AND tt.type = 'income'
AND gl.record_uuid NOT IN (
SELECT DISTINCT gl.record_uuid
FROM general_ledger AS gl
WHERE gl.record_uuid IN (
SELECT rev.uuid
FROM (
SELECT v.uuid FROM voucher v WHERE v.reversed = 1
AND DATE(v.date) >= DATE(?) AND DATE(v.date) <= DATE(?) UNION
SELECT c.uuid FROM cash c WHERE c.reversed = 1
AND DATE(c.date) >= DATE(?) AND DATE(c.date) <= DATE(?) UNION
SELECT i.uuid FROM invoice i WHERE i.reversed = 1
AND DATE(i.date) >= DATE(?) AND DATE(i.date) <= DATE(?)
) AS rev
)
);`;

const paramsFilter = [
[cashAccountIds],
fiscalYearId,
fiscalYear.start_date,
fiscalYear.end_date,
fiscalYear.start_date,
fiscalYear.end_date,
fiscalYear.start_date,
fiscalYear.end_date,
];

const totalIncomeCash = await db.one(sqlTotalIncomeCash, paramsFilter);
totalFinancement = totalIncomeCash.balance;

const BUDGET_ANALYSIS_REFERENCE_TYPE_ID = 8;

const sqlReferences = `
SELECT ar.id, ar.abbr, ar.description, art.account_id, GROUP_CONCAT(a.number, ' ') AS accounts_number,
a.label
FROM account_reference AS ar
JOIN account_reference_item AS art ON art.account_reference_id = ar.id
JOIN account AS a ON a.id = art.account_id
WHERE ar.reference_type_id = ?
GROUP BY ar.id;
`;

configurationReferences = await db.exec(sqlReferences, [BUDGET_ANALYSIS_REFERENCE_TYPE_ID]);

configurationReferences = configurationReferences.map(item => ({
...item,
accounts_number_formated : item.accounts_number
.split(',')
.map(num => parseInt(num.trim(), 10))
.filter(num => Number.isInteger(num)),
}));
}

const sqlGetPreviousFiscalYear = `
SELECT fy.id, fy.label, YEAR(fy.end_date) AS year
FROM fiscal_year AS fy
Expand Down Expand Up @@ -192,15 +282,39 @@ async function report(req, res, next) {
}

const tabFiscalIncomeData = tabFiscalReport.filter(id => {
return (id.type_id === 4 || id.isIncomeTitle);
return (id.type_id === ACCOUNT_TYPES_INCOME || id.isIncomeTitle);
});

const tabFiscalExpenseData = tabFiscalReport.filter(id => {
return (id.type_id === 5 || id.isExpenseTitle);
return (id.type_id === ACCOUNT_TYPES_EXPENSE || id.isExpenseTitle);
});

const totalCompletionIncome = totalRealisationIncome / totalBudgetIncome;
const totalCompletionExpense = totalRealisationExpense / totalBudgetExpense;
const realisationIncomeExpense = totalRealisationIncome - totalRealisationExpense;

configurationReferences.forEach(item => {
item.value_account_number = item.accounts_number_formated.reduce((total, accountNumber) => {
const matchingIncome = tabFiscalIncomeData.find(income => income.number === accountNumber);
return total + (matchingIncome ? matchingIncome.realisation : 0);
}, 0);
});

let firstIncomeConfigurationReferences = 0;
let secondIncomeConfigurationReferences = 0;

if (includeSummarySection) {
firstIncomeConfigurationReferences = configurationReferences[0].value_account_number;
firstIncomeDescription = configurationReferences[0].description;

secondIncomeConfigurationReferences = configurationReferences[1].value_account_number;
secondIncomeDescription = configurationReferences[1].description;
}

const realisationIncomeExpenseFirst = realisationIncomeExpense - firstIncomeConfigurationReferences;
const realisationIncomeExpenseSecond = realisationIncomeExpense - secondIncomeConfigurationReferences;
const localCashRevenues = totalFinancement - secondIncomeConfigurationReferences;
const soldeTotalFinancement = totalFinancement - totalRealisationExpense;

const data = {
colums : dataFiscalsYear,
Expand All @@ -223,6 +337,17 @@ async function report(req, res, next) {
reportFootColumIncome,
reportFootColumExpense,
currencyId : Number(req.session.enterprise.currency_id),
includeSummarySection,
totalFinancement,
realisationIncomeExpense,
realisationIncomeExpenseFirst,
realisationIncomeExpenseSecond,
secondIncomeConfigurationReferences,
localCashRevenues,
soldeTotalFinancement,
cashLabelDetails,
firstIncomeDescription,
secondIncomeDescription,
};

const result = await reporting.render(data);
Expand Down
Loading

0 comments on commit d05f4f5

Please sign in to comment.