fix: major refactor to monkey-patch into the QueryReport class
This commit is contained in:
parent
dba4b3cd13
commit
8e413651c2
@ -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 @@ frappe.query_reports["Tax Detail"] = {
|
||||
// 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 @@ class TaxReport {
|
||||
});
|
||||
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 @@ class TaxReport {
|
||||
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 @@ class TaxReport {
|
||||
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 @@ class TaxReport {
|
||||
}
|
||||
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 @@ class TaxReport {
|
||||
}
|
||||
});
|
||||
// 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 @@ class TaxReport {
|
||||
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 @@ class TaxReport {
|
||||
}
|
||||
}
|
||||
});
|
||||
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 @@ class TaxReport {
|
||||
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 get_reports(cb) {
|
||||
})
|
||||
}
|
||||
|
||||
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 @@ function new_report() {
|
||||
},
|
||||
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 new_report() {
|
||||
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 @@ function load_report() {
|
||||
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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user