fix: major refactor to monkey-patch into the QueryReport class
diff --git a/erpnext/accounts/report/tax_detail/tax_detail.js b/erpnext/accounts/report/tax_detail/tax_detail.js
index 8cdce54..6049000 100644
--- a/erpnext/accounts/report/tax_detail/tax_detail.js
+++ b/erpnext/accounts/report/tax_detail/tax_detail.js
@@ -3,6 +3,8 @@
// Contributed by Case Solved and sponsored by Nulight Studios
/* eslint-disable */
+frappe.provide('frappe.query_reports');
+
frappe.query_reports["Tax Detail"] = {
filters: [
{
@@ -50,83 +52,124 @@
// Remove Add Column and Save from menu
report.page.add_inner_button(__("New Report"), () => new_report(), __("Custom Report"));
report.page.add_inner_button(__("Load Report"), () => load_report(), __("Custom Report"));
- hide_filters();
- },
- after_datatable_render: (datatable) => {
- if (frappe.query_report.report_name == 'Tax Detail') {
- return;
- }
- if (this.taxreport) {
- this.taxreport.load_report();
- } else {
- this.taxreport = new TaxReport();
- }
+ hide_filters(report);
}
};
-function hide_filters() {
- frappe.query_report.page.page_form[0].querySelectorAll('.form-group.frappe-control').forEach(function setHidden(field) {
+function hide_filters(report) {
+ report.page.page_form[0].querySelectorAll('.form-group.frappe-control').forEach(function setHidden(field) {
if (field.dataset.fieldtype == "Read Only") {
field.classList.add("hidden");
}
});
}
-class TaxReport {
- // construct after datatable is loaded
+erpnext.TaxDetail = class TaxDetail {
constructor() {
- this.qr = frappe.query_report;
- this.page = frappe.query_report.page;
- this.create_controls();
+ this.patch();
this.load_report();
}
- load_report() {
- if (this.loaded) {
- return;
+ // Monkey patch the QueryReport class
+ patch() {
+ this.qr = frappe.query_report;
+ this.super = {
+ refresh_report: this.qr.refresh_report,
+ show_footer_message: this.qr.show_footer_message
}
- const report_name = this.qr.report_name;
- this.report_name.value = report_name;
- frappe.call({
- method: 'erpnext.accounts.report.tax_detail.tax_detail.get_custom_reports',
- args: {name: report_name},
- freeze: true
- }).then((r) => {
- const data = JSON.parse(r.message[report_name]['json']);
- this.sections = data.sections || {};
- this.controls['show_detail'].set_input(data.show_detail);
- this.set_section();
- })
- this.loaded = 1;
+ this.qr.refresh_report = () => this.refresh_report();
+ this.qr.show_footer_message = () => this.show_footer_message();
+ }
+ show_footer_message() {
+ // The last thing to run after datatable_render in refresh()
+ console.log('show_footer_message');
+ this.super.show_footer_message.apply(this.qr);
+ if (this.qr.report_name !== 'Tax Detail') {
+ this.set_value_options();
+ this.show_help();
+ if (this.loading) {
+ this.set_section('');
+ }
+ this.reload_filter();
+ }
+ this.loading = false;
+ }
+ refresh_report() {
+ // Infrequent report build (onload), load filters & data
+ // super function runs a refresh() serially
+ // already run within frappe.run_serially
+ console.log('refresh_report');
+ this.loading = true;
+ this.super.refresh_report.apply(this.qr);
+ if (this.qr.report_name !== 'Tax Detail') {
+ frappe.call({
+ method: 'erpnext.accounts.report.tax_detail.tax_detail.get_custom_reports',
+ args: {name: this.qr.report_name}
+ }).then((r) => {
+ const data = JSON.parse(r.message[this.qr.report_name]['json']);
+ this.create_controls();
+ this.sections = data.sections || {};
+ this.controls['show_detail'].set_input(data.show_detail);
+ });
+ }
+ }
+ load_report() {
+ // One-off report build like titles, menu, etc
+ // Run when this object is created which happens in qr.load_report
+ console.log('load_report');
+ this.qr.menu_items = this.get_menu_items();
+ }
+ get_menu_items() {
+ // Replace save button
+ let new_items = [];
+ const label = __('Save');
+
+ for (let item of this.qr.menu_items) {
+ if (item.label === label) {
+ new_items.push({
+ label: label,
+ action: this.save_report,
+ standard: false
+ });
+ } else {
+ new_items.push(item);
+ }
+ }
+ return new_items;
}
save_report() {
- frappe.call({
- method:'erpnext.accounts.report.tax_detail.tax_detail.save_custom_report',
- args: {
- reference_report: 'Tax Detail',
- report_name: this.qr.report_name,
- data: {
- columns: this.qr.get_visible_columns(),
- sections: this.sections,
- show_detail: this.controls['show_detail'].get_input_value()
- }
- },
- freeze: true
- }).then((r) => {
- this.reload();
- });
+ if (this.qr.report_name !== 'Tax Detail') {
+ frappe.call({
+ method:'erpnext.accounts.report.tax_detail.tax_detail.save_custom_report',
+ args: {
+ reference_report: 'Tax Detail',
+ report_name: this.qr.report_name,
+ data: {
+ columns: this.qr.get_visible_columns(),
+ sections: this.sections,
+ show_detail: this.controls['show_detail'].get_input_value()
+ }
+ },
+ freeze: true
+ }).then((r) => {
+ this.set_section('');
+ });
+ }
}
set_value_options() {
- this.fieldname_lookup = {};
- this.label_lookup = {};
- this.qr.columns.forEach((col, index) => {
- if (col['fieldtype'] == "Currency") {
- this.fieldname_lookup[col['label']] = col['fieldname'];
- this.label_lookup[col['fieldname']] = col['label'];
- }
- });
- const options = Object.keys(this.fieldname_lookup);
- this.controls['value_field'].$wrapper.find("select").empty().add_options(options);
- this.controls['value_field'].set_input(options[0]);
+ // May be run with no columns or data
+ if (this.qr.columns) {
+ this.fieldname_lookup = {};
+ this.label_lookup = {};
+ this.qr.columns.forEach((col, index) => {
+ if (col['fieldtype'] == "Currency") {
+ this.fieldname_lookup[col['label']] = col['fieldname'];
+ this.label_lookup[col['fieldname']] = col['label'];
+ }
+ });
+ const options = Object.keys(this.fieldname_lookup);
+ this.controls['value_field'].$wrapper.find("select").empty().add_options(options);
+ this.controls['value_field'].set_input(options[0]);
+ }
}
set_value_label_from_filter() {
const section_name = this.controls['section_name'].value;
@@ -158,46 +201,38 @@
});
dialog.show();
}
- get_filter_controls() {
- this.qr.filters.forEach(filter => {
- if (filter['fieldname'] == 'mode') {
- this.mode = filter;
- }
- if (filter['fieldname'] == 'report_name') {
- this.report_name = filter;
- }
- });
- }
- set_mode(mode) {
- this.mode.value = mode;
- }
- edit_mode() {
- return this.mode.value == 'edit';
- }
set_section(name) {
+ // Sets the given section name and then reloads the data
if (name && !this.sections[name]) {
this.sections[name] = {};
}
let options = Object.keys(this.sections);
options.unshift('');
this.controls['section_name'].$wrapper.find("select").empty().add_options(options);
+ const org_mode = this.qr.get_filter_value('mode');
+ let refresh = false;
if (name) {
this.controls['section_name'].set_input(name);
+ this.qr.set_filter_value('mode', 'edit');
+ if (org_mode === 'run') {
+ refresh = true;
+ }
} else {
this.controls['section_name'].set_input('');
+ this.qr.set_filter_value('mode', 'run');
+ if (org_mode === 'edit') {
+ refresh = true;
+ }
}
- if (this.controls['section_name'].value) {
- this.set_mode('edit');
- } else {
- this.set_mode('run');
+ this.reload_filter();
+ if (refresh) {
+ this.qr.refresh();
}
- this.controls['filter_index'].set_input('');
- this.reload();
}
reload_filter() {
- const section_name = this.controls['section_name'].value;
+ const section_name = this.controls['section_name'].get_input_value();
if (section_name) {
- let fidx = this.controls['filter_index'].value;
+ let fidx = this.controls['filter_index'].get_input_value();
let section = this.sections[section_name];
let fidxs = Object.keys(section);
fidxs.unshift('');
@@ -207,17 +242,16 @@
this.controls['filter_index'].$wrapper.find("select").empty();
this.controls['filter_index'].set_input('');
}
- this.set_filters();
+ this.set_table_filters();
}
- set_filters() {
+ set_table_filters() {
let filters = {};
- const section_name = this.controls['section_name'].value;
- const fidx = this.controls['filter_index'].value;
+ const section_name = this.controls['section_name'].get_input_value();
+ const fidx = this.controls['filter_index'].get_input_value();
if (section_name && fidx) {
filters = this.sections[section_name][fidx]['filters'];
}
this.setAppliedFilters(filters);
- this.qr.datatable.columnmanager.applyFilter(filters);
this.set_value_label_from_filter();
}
setAppliedFilters(filters) {
@@ -229,32 +263,20 @@
input.value = null;
}
});
- }
- reload() {
- // Reloads the data. When the datatable is reloaded, load_report()
- // will be run by the after_datatable_render event.
- // TODO: why does this trigger multiple reloads?
- this.qr.refresh();
- this.show_help();
- if (this.edit_mode()) {
- this.reload_filter();
- } else {
- this.controls['filter_index'].$wrapper.find("select").empty();
- }
+ this.qr.datatable.columnmanager.applyFilter(filters);
}
delete(name, type) {
if (type === 'section') {
delete this.sections[name];
- this.controls['section_name'].$wrapper.find("select").empty().add_options(Object.keys(this.sections));
- this.controls['section_name'].set_input(Object.keys(this.sections)[0] || '');
- this.controls['filter_index'].set_input('');
+ const new_section = Object.keys(this.sections)[0] || '';
+ this.set_section(new_section);
}
if (type === 'filter') {
- let cur_section = this.controls['section_name'].value;
+ const cur_section = this.controls['section_name'].get_input_value();
delete this.sections[cur_section][name];
this.controls['filter_index'].set_input('');
+ this.reload_filter();
}
- this.reload();
}
create_controls() {
if (this.controls) {
@@ -262,7 +284,7 @@
}
let controls = {};
// SELECT in data.js
- controls['section_name'] = this.page.add_field({
+ controls['section_name'] = this.qr.page.add_field({
label: __('Section'),
fieldtype: 'Select',
fieldname: 'section_name',
@@ -271,7 +293,7 @@
}
});
// BUTTON in button.js
- controls['new_section'] = this.page.add_field({
+ controls['new_section'] = this.qr.page.add_field({
label: __('New Section'),
fieldtype: 'Button',
fieldname: 'new_section',
@@ -279,33 +301,33 @@
this.new_section(__('New Section'));
}
});
- controls['delete_section'] = this.page.add_field({
+ controls['delete_section'] = this.qr.page.add_field({
label: __('Delete Section'),
fieldtype: 'Button',
fieldname: 'delete_section',
click: () => {
- let cur_section = this.controls['section_name'].value;
+ let cur_section = this.controls['section_name'].get_input_value();
if (cur_section) {
frappe.confirm(__('Are you sure you want to delete section ') + cur_section + '?',
() => {this.delete(cur_section, 'section')});
}
}
});
- controls['filter_index'] = this.page.add_field({
+ controls['filter_index'] = this.qr.page.add_field({
label: __('Filter'),
fieldtype: 'Select',
fieldname: 'filter_index',
change: (e) => {
this.controls['filter_index'].set_input(this.controls['filter_index'].get_input_value());
- this.set_filters();
+ this.set_table_filters();
}
});
- controls['add_filter'] = this.page.add_field({
+ controls['add_filter'] = this.qr.page.add_field({
label: __('Add Filter'),
fieldtype: 'Button',
fieldname: 'add_filter',
click: () => {
- let section_name = this.controls['section_name'].value;
+ let section_name = this.controls['section_name'].get_input_value();
if (section_name) {
let prefix = 'Filter';
let data = {
@@ -326,19 +348,19 @@
}
}
});
- controls['delete_filter'] = this.page.add_field({
+ controls['delete_filter'] = this.qr.page.add_field({
label: __('Delete Filter'),
fieldtype: 'Button',
fieldname: 'delete_filter',
click: () => {
- let cur_filter = this.controls['filter_index'].value;
+ let cur_filter = this.controls['filter_index'].get_input_value();
if (cur_filter) {
frappe.confirm(__('Are you sure you want to delete filter ') + cur_filter + '?',
() => {this.delete(cur_filter, 'filter')});
}
}
});
- controls['value_field'] = this.page.add_field({
+ controls['value_field'] = this.qr.page.add_field({
label: __('Value Column'),
fieldtype: 'Select',
fieldname: 'value_field',
@@ -346,37 +368,35 @@
this.controls['value_field'].set_input(this.controls['value_field'].get_input_value());
}
});
- controls['save'] = this.page.add_field({
+ controls['save'] = this.qr.page.add_field({
label: __('Save & Run'),
fieldtype: 'Button',
fieldname: 'save',
click: () => {
- this.controls['section_name'].set_input('');
- this.set_mode('run');
this.save_report();
}
});
- controls['show_detail'] = this.page.add_field({
+ controls['show_detail'] = this.qr.page.add_field({
label: __('Show Detail'),
fieldtype: 'Check',
fieldname: 'show_detail',
default: 1
});
this.controls = controls;
- this.set_value_options();
- this.get_filter_controls();
- this.show_help();
}
show_help() {
const help = __(`You can add multiple sections to your custom report using the New Section button above.
- To specify what data goes in each section, specify column filters below, then save with Add Filter.
- Each section can have multiple filters added.
- You can specify which Currency column will be summed for each filter in the final report with the Value Column select box.
- Once you're done, hit Save & Run.`);
- this.qr.show_status(help);
+ To specify what data goes in each section, specify column filters in the data table, then save with Add Filter.
+ Each section can have multiple filters added but be careful with the duplicated data rows.
+ You can specify which Currency column will be summed for each filter in the final report with the Value Column
+ select box. Once you're done, hit Save & Run.`);
+ this.qr.$report_footer.append(`<div class="col-md-12">${help}</div>`);
}
}
+if (!window.taxdetail) {
+ window.taxdetail = new erpnext.TaxDetail();
+}
function get_reports(cb) {
frappe.call({
@@ -387,23 +407,9 @@
})
}
-function override_menu() {
- //TODO: Replace save button
- this.qr.menu_items.forEach((item, idx) => {
- if (item['label'] == __('Save')) {
- delete this.qr.menu_items[idx];
- }
- })
- this.qr.menu_items.push({
- label: __('Save'),
- action: this.save_report
- })
- this.qr.set_menu_items();
-}
-
function new_report() {
const dialog = new frappe.ui.Dialog({
- title: __("New Report"),
+ title: __('New Report'),
fields: [
{
fieldname: 'report_name',
@@ -424,7 +430,7 @@
},
freeze: true
}).then((r) => {
- frappe.set_route("query-report", values.report_name);
+ frappe.set_route('query-report', values.report_name);
});
dialog.hide();
}
@@ -435,7 +441,7 @@
function load_report() {
get_reports(function load_report_cb(reports) {
const dialog = new frappe.ui.Dialog({
- title: __("Load Report"),
+ title: __('Load Report'),
fields: [
{
fieldname: 'report_name',
@@ -447,7 +453,7 @@
primary_action_label: __('Load'),
primary_action: function load_report_pa(values) {
dialog.hide();
- frappe.set_route("query-report", values.report_name);
+ frappe.set_route('query-report', values.report_name);
}
});
dialog.show();