blob: bd8b70af02e3eac97b39d45a2ad0964af90455ff [file] [log] [blame]
Anand Doshi825d0142014-07-18 18:05:26 +05301frappe.provide("erpnext.financial_statements");
2
3erpnext.financial_statements = {
Ankush Menatec74a5e2024-03-10 19:45:40 +05304 filters: get_filters(),
5 baseData: null,
6 formatter: function (value, row, column, data, default_formatter, filter) {
7 if (
8 frappe.query_report.get_filter_value("selected_view") == "Growth" &&
9 data &&
10 column.colIndex >= 3
11 ) {
nitmit92649de2024-01-27 10:18:35 +053012 //Assuming that the first three columns are s.no, account name and the very first year of the accounting values, to calculate the relative percentage values of the successive columns.
13 const lastAnnualValue = row[column.colIndex - 1].content;
14 const currentAnnualvalue = data[column.fieldname];
Ankush Menatec74a5e2024-03-10 19:45:40 +053015 if (currentAnnualvalue == undefined) return "NA"; //making this not applicable for undefined/null values
nitmit92649de2024-01-27 10:18:35 +053016 let annualGrowth = 0;
Ankush Menatec74a5e2024-03-10 19:45:40 +053017 if (lastAnnualValue == 0 && currentAnnualvalue > 0) {
nitmit92649de2024-01-27 10:18:35 +053018 //If the previous year value is 0 and the current value is greater than 0
19 annualGrowth = 1;
Ankush Menatec74a5e2024-03-10 19:45:40 +053020 } else if (lastAnnualValue > 0) {
21 annualGrowth = (currentAnnualvalue - lastAnnualValue) / lastAnnualValue;
nitmit92649de2024-01-27 10:18:35 +053022 }
23
Ankush Menatec74a5e2024-03-10 19:45:40 +053024 const growthPercent = Math.round(annualGrowth * 10000) / 100; //calculating the rounded off percentage
nitmit92649de2024-01-27 10:18:35 +053025
Ankush Menatec74a5e2024-03-10 19:45:40 +053026 value = $(`<span>${(growthPercent >= 0 ? "+" : "") + growthPercent + "%"}</span>`);
27 if (growthPercent < 0) {
nitmit92649de2024-01-27 10:18:35 +053028 value = $(value).addClass("text-danger");
Ankush Menatec74a5e2024-03-10 19:45:40 +053029 } else {
nitmit92649de2024-01-27 10:18:35 +053030 value = $(value).addClass("text-success");
31 }
32 value = $(value).wrap("<p></p>").parent().html();
33
34 return value;
Ankush Menatec74a5e2024-03-10 19:45:40 +053035 } else if (frappe.query_report.get_filter_value("selected_view") == "Margin" && data) {
36 if (column.fieldname == "account" && data.account_name == __("Income")) {
nitmit92649de2024-01-27 10:18:35 +053037 //Taking the total income from each column (for all the financial years) as the base (100%)
38 this.baseData = row;
39 }
Ankush Menatec74a5e2024-03-10 19:45:40 +053040 if (column.colIndex >= 2) {
nitmit92649de2024-01-27 10:18:35 +053041 //Assuming that the first two columns are s.no and account name, to calculate the relative percentage values of the successive columns.
42 const currentAnnualvalue = data[column.fieldname];
43 const baseValue = this.baseData[column.colIndex].content;
Ankush Menatec74a5e2024-03-10 19:45:40 +053044 if (currentAnnualvalue == undefined || baseValue <= 0) return "NA";
45 const marginPercent = Math.round((currentAnnualvalue / baseValue) * 10000) / 100;
nitmit92649de2024-01-27 10:18:35 +053046
Ankush Menatec74a5e2024-03-10 19:45:40 +053047 value = $(`<span>${marginPercent + "%"}</span>`);
48 if (marginPercent < 0) value = $(value).addClass("text-danger");
49 else value = $(value).addClass("text-success");
nitmit92649de2024-01-27 10:18:35 +053050 value = $(value).wrap("<p></p>").parent().html();
51 return value;
52 }
nitmit92649de2024-01-27 10:18:35 +053053 }
54
Ankush Menatec74a5e2024-03-10 19:45:40 +053055 if (data && column.fieldname == "account") {
thefalconx33a639f162019-12-04 09:46:42 +053056 value = data.account_name || value;
Anand Doshi825d0142014-07-18 18:05:26 +053057
Shariq Ansari08ed3cd2023-12-07 19:39:24 +053058 if (filter && filter?.text && filter?.type == "contains") {
59 if (!value.toLowerCase().includes(filter.text)) {
60 return value;
61 }
62 }
63
Ankush Menat2dc95e52023-09-27 12:34:40 +053064 if (data.account) {
65 column.link_onclick =
66 "erpnext.financial_statements.open_general_ledger(" + JSON.stringify(data) + ")";
67 }
Faris Ansari5986d592018-07-20 15:11:55 +053068 column.is_tree = true;
Anand Doshi825d0142014-07-18 18:05:26 +053069 }
70
Faris Ansari5986d592018-07-20 15:11:55 +053071 value = default_formatter(value, row, column, data);
Anand Doshicb86d592014-07-22 19:02:11 +053072
Diksha Jadhav09b8caf2020-07-21 17:35:10 +053073 if (data && !data.parent_account) {
Faris Ansari5986d592018-07-20 15:11:55 +053074 value = $(`<span>${value}</span>`);
75
Anand Doshi5f0459c2014-07-21 16:13:06 +053076 var $value = $(value).css("font-weight", "bold");
Faris Ansari5986d592018-07-20 15:11:55 +053077 if (data.warn_if_negative && data[column.fieldname] < 0) {
Anand Doshi5f0459c2014-07-21 16:13:06 +053078 $value.addClass("text-danger");
79 }
80
81 value = $value.wrap("<p></p>").parent().html();
Anand Doshi825d0142014-07-18 18:05:26 +053082 }
83
84 return value;
85 },
Ankush Menatec74a5e2024-03-10 19:45:40 +053086 open_general_ledger: function (data) {
Anand Doshi5f0459c2014-07-21 16:13:06 +053087 if (!data.account) return;
Ankush Menatec74a5e2024-03-10 19:45:40 +053088 let project = $.grep(frappe.query_report.filters, function (e) {
89 return e.df.fieldname == "project";
90 });
Anand Doshi825d0142014-07-18 18:05:26 +053091
92 frappe.route_options = {
Ankush Menatec74a5e2024-03-10 19:45:40 +053093 account: data.account,
94 company: frappe.query_report.get_filter_value("company"),
95 from_date: data.from_date || data.year_start_date,
96 to_date: data.to_date || data.year_end_date,
97 project: project && project.length > 0 ? project[0].$input.val() : "",
Anand Doshi825d0142014-07-18 18:05:26 +053098 };
FinByz Tech Pvt. Ltdc52b41d2022-10-19 23:14:10 +053099
100 let report = "General Ledger";
101
102 if (["Payable", "Receivable"].includes(data.account_type)) {
103 report = data.account_type == "Payable" ? "Accounts Payable" : "Accounts Receivable";
104 frappe.route_options["party_account"] = data.account;
105 frappe.route_options["report_date"] = data.year_end_date;
106 }
107
108 frappe.set_route("query-report", report);
Anand Doshicb86d592014-07-22 19:02:11 +0530109 },
Ankush Menatec74a5e2024-03-10 19:45:40 +0530110 tree: true,
111 name_field: "account",
112 parent_field: "parent_account",
113 initial_depth: 3,
114 onload: function (report) {
Rushabh Mehta05253872016-04-18 19:27:36 +0530115 // dropdown for links to other financial statements
Ankush Menatec74a5e2024-03-10 19:45:40 +0530116 erpnext.financial_statements.filters = get_filters();
Rohit Waghchaure4275c302016-08-19 11:48:58 +0530117
Deepesh Garg62706072023-07-16 12:58:42 +0530118 let fiscal_year = erpnext.utils.get_fiscal_year(frappe.datetime.get_today());
Deepesh Garg1f3fe592020-05-28 18:36:21 +0530119
Ankush Menatec74a5e2024-03-10 19:45:40 +0530120 frappe.model.with_doc("Fiscal Year", fiscal_year, function (r) {
Deepesh Garg1f3fe592020-05-28 18:36:21 +0530121 var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
122 frappe.query_report.set_filter_value({
123 period_start_date: fy.year_start_date,
Ankush Menatec74a5e2024-03-10 19:45:40 +0530124 period_end_date: fy.year_end_date,
Deepesh Garg1f3fe592020-05-28 18:36:21 +0530125 });
126 });
127
Ankush Menatec74a5e2024-03-10 19:45:40 +0530128 if (report.page) {
129 const views_menu = report.page.add_custom_button_group(__("Financial Statements"));
Shivam Mishrab6fb1322020-07-09 16:51:36 +0530130
Ankush Menatec74a5e2024-03-10 19:45:40 +0530131 report.page.add_custom_menu_item(views_menu, __("Balance Sheet"), function () {
Gursheen Anand2486b642024-01-27 23:30:17 +0530132 var filters = report.get_values();
Ankush Menatec74a5e2024-03-10 19:45:40 +0530133 frappe.set_route("query-report", "Balance Sheet", { company: filters.company });
Gursheen Anand2486b642024-01-27 23:30:17 +0530134 });
Shivam Mishrab6fb1322020-07-09 16:51:36 +0530135
Ankush Menatec74a5e2024-03-10 19:45:40 +0530136 report.page.add_custom_menu_item(views_menu, __("Profit and Loss"), function () {
Gursheen Anand2486b642024-01-27 23:30:17 +0530137 var filters = report.get_values();
Ankush Menatec74a5e2024-03-10 19:45:40 +0530138 frappe.set_route("query-report", "Profit and Loss Statement", { company: filters.company });
Gursheen Anand2486b642024-01-27 23:30:17 +0530139 });
Shivam Mishrab6fb1322020-07-09 16:51:36 +0530140
Ankush Menatec74a5e2024-03-10 19:45:40 +0530141 report.page.add_custom_menu_item(views_menu, __("Cash Flow Statement"), function () {
Gursheen Anand2486b642024-01-27 23:30:17 +0530142 var filters = report.get_values();
Ankush Menatec74a5e2024-03-10 19:45:40 +0530143 frappe.set_route("query-report", "Cash Flow", { company: filters.company });
Gursheen Anand2486b642024-01-27 23:30:17 +0530144 });
145 }
Ankush Menatec74a5e2024-03-10 19:45:40 +0530146 },
Anand Doshi825d0142014-07-18 18:05:26 +0530147};
Rohit Waghchaure4275c302016-08-19 11:48:58 +0530148
Deepesh Garg11ea0b12020-05-26 19:23:45 +0530149function get_filters() {
deepeshgarg007d83cf652019-05-12 18:34:23 +0530150 let filters = [
Rohit Waghchaure4275c302016-08-19 11:48:58 +0530151 {
Ankush Menatec74a5e2024-03-10 19:45:40 +0530152 fieldname: "company",
153 label: __("Company"),
154 fieldtype: "Link",
155 options: "Company",
156 default: frappe.defaults.get_user_default("Company"),
157 reqd: 1,
Rohit Waghchaure4275c302016-08-19 11:48:58 +0530158 },
159 {
Ankush Menatec74a5e2024-03-10 19:45:40 +0530160 fieldname: "finance_book",
161 label: __("Finance Book"),
162 fieldtype: "Link",
163 options: "Finance Book",
Gaurav Naik8cbbdfd2018-04-23 03:36:02 +0530164 },
165 {
Ankush Menatec74a5e2024-03-10 19:45:40 +0530166 fieldname: "filter_based_on",
167 label: __("Filter Based On"),
168 fieldtype: "Select",
169 options: ["Fiscal Year", "Date Range"],
170 default: ["Fiscal Year"],
171 reqd: 1,
172 on_change: function () {
173 let filter_based_on = frappe.query_report.get_filter_value("filter_based_on");
174 frappe.query_report.toggle_filter_display(
175 "from_fiscal_year",
176 filter_based_on === "Date Range"
177 );
178 frappe.query_report.toggle_filter_display("to_fiscal_year", filter_based_on === "Date Range");
179 frappe.query_report.toggle_filter_display(
180 "period_start_date",
181 filter_based_on === "Fiscal Year"
182 );
183 frappe.query_report.toggle_filter_display(
184 "period_end_date",
185 filter_based_on === "Fiscal Year"
186 );
Deepesh Garg24a2c9b2020-04-07 12:16:25 +0530187
188 frappe.query_report.refresh();
Ankush Menatec74a5e2024-03-10 19:45:40 +0530189 },
Deepesh Garg24a2c9b2020-04-07 12:16:25 +0530190 },
191 {
Ankush Menatec74a5e2024-03-10 19:45:40 +0530192 fieldname: "period_start_date",
193 label: __("Start Date"),
194 fieldtype: "Date",
195 reqd: 1,
196 depends_on: "eval:doc.filter_based_on == 'Date Range'",
Deepesh Garg24a2c9b2020-04-07 12:16:25 +0530197 },
198 {
Ankush Menatec74a5e2024-03-10 19:45:40 +0530199 fieldname: "period_end_date",
200 label: __("End Date"),
201 fieldtype: "Date",
202 reqd: 1,
203 depends_on: "eval:doc.filter_based_on == 'Date Range'",
Deepesh Garg24a2c9b2020-04-07 12:16:25 +0530204 },
205 {
Ankush Menatec74a5e2024-03-10 19:45:40 +0530206 fieldname: "from_fiscal_year",
207 label: __("Start Year"),
208 fieldtype: "Link",
209 options: "Fiscal Year",
210 reqd: 1,
211 depends_on: "eval:doc.filter_based_on == 'Fiscal Year'",
Rohit Waghchaure4275c302016-08-19 11:48:58 +0530212 },
213 {
Ankush Menatec74a5e2024-03-10 19:45:40 +0530214 fieldname: "to_fiscal_year",
215 label: __("End Year"),
216 fieldtype: "Link",
217 options: "Fiscal Year",
218 reqd: 1,
219 depends_on: "eval:doc.filter_based_on == 'Fiscal Year'",
Rohit Waghchaure4275c302016-08-19 11:48:58 +0530220 },
221 {
Ankush Menatec74a5e2024-03-10 19:45:40 +0530222 fieldname: "periodicity",
223 label: __("Periodicity"),
224 fieldtype: "Select",
225 options: [
226 { value: "Monthly", label: __("Monthly") },
227 { value: "Quarterly", label: __("Quarterly") },
228 { value: "Half-Yearly", label: __("Half-Yearly") },
229 { value: "Yearly", label: __("Yearly") },
Rohit Waghchaure4275c302016-08-19 11:48:58 +0530230 ],
Ankush Menatec74a5e2024-03-10 19:45:40 +0530231 default: "Yearly",
232 reqd: 1,
tundebabzyc8978252018-02-12 10:34:50 +0100233 },
234 // Note:
235 // If you are modifying this array such that the presentation_currency object
236 // is no longer the last object, please make adjustments in cash_flow.js
237 // accordingly.
238 {
Ankush Menatec74a5e2024-03-10 19:45:40 +0530239 fieldname: "presentation_currency",
240 label: __("Currency"),
241 fieldtype: "Select",
242 options: erpnext.get_presentation_currency_list(),
deepeshgarg007f5b6ee92019-05-28 12:15:56 +0530243 },
244 {
Ankush Menatec74a5e2024-03-10 19:45:40 +0530245 fieldname: "cost_center",
246 label: __("Cost Center"),
247 fieldtype: "MultiSelectList",
248 get_data: function (txt) {
249 return frappe.db.get_link_options("Cost Center", txt, {
250 company: frappe.query_report.get_filter_value("company"),
Gursheen Kaur Anand596a14e2023-07-12 15:49:17 +0530251 });
252 },
Ankush Menatec74a5e2024-03-10 19:45:40 +0530253 },
254 {
255 fieldname: "project",
256 label: __("Project"),
257 fieldtype: "MultiSelectList",
258 get_data: function (txt) {
259 return frappe.db.get_link_options("Project", txt, {
260 company: frappe.query_report.get_filter_value("company"),
261 });
262 },
263 },
264 ];
deepeshgarg007d83cf652019-05-12 18:34:23 +0530265
ruthra kumarc31ee8e2023-11-14 06:44:49 +0530266 // Dynamically set 'default' values for fiscal year filters
Ankush Menatec74a5e2024-03-10 19:45:40 +0530267 let fy_filters = filters.filter((x) => {
268 return ["from_fiscal_year", "to_fiscal_year"].includes(x.fieldname);
269 });
ruthra kumarc31ee8e2023-11-14 06:44:49 +0530270 let fiscal_year = erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), false, true);
271 if (fiscal_year) {
272 let fy = erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), false, false);
Ankush Menatec74a5e2024-03-10 19:45:40 +0530273 fy_filters.forEach((x) => {
274 x.default = fy;
275 });
ruthra kumarc31ee8e2023-11-14 06:44:49 +0530276 }
277
deepeshgarg007d83cf652019-05-12 18:34:23 +0530278 return filters;
279}