develop: progress tax detail report
This commit is contained in:
parent
a5d47f70b8
commit
ef8ab135c9
@ -29,11 +29,28 @@ frappe.query_reports["Tax Detail"] = {
|
||||
reqd: 1,
|
||||
width: "60px"
|
||||
},
|
||||
{
|
||||
fieldname: "report_name",
|
||||
label: __("Report Name"),
|
||||
fieldtype: "Read Only",
|
||||
default: frappe.query_report.report_name,
|
||||
hidden: 1,
|
||||
reqd: 1
|
||||
},
|
||||
{
|
||||
fieldname: "mode",
|
||||
label: __("Mode"),
|
||||
fieldtype: "Read Only",
|
||||
default: "run",
|
||||
hidden: 1,
|
||||
reqd: 1
|
||||
}
|
||||
],
|
||||
onload: function onload(report) {
|
||||
// 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"));
|
||||
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') {
|
||||
@ -47,65 +64,83 @@ frappe.query_reports["Tax Detail"] = {
|
||||
}
|
||||
};
|
||||
|
||||
function hide_filters() {
|
||||
frappe.query_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
|
||||
constructor() {
|
||||
this.report = frappe.query_reports["Tax Detail"];
|
||||
this.qr = frappe.query_report;
|
||||
this.page = frappe.query_report.page;
|
||||
this.create_controls();
|
||||
this.sections = {};
|
||||
this.mode = 'run';
|
||||
this.load_report();
|
||||
}
|
||||
load_report() {
|
||||
// TODO
|
||||
this.setup_menu();
|
||||
// this.qr.refresh_report()
|
||||
}
|
||||
setup_menu() {
|
||||
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();
|
||||
}
|
||||
save_report() {
|
||||
// TODO
|
||||
if (this.loaded) {
|
||||
return;
|
||||
}
|
||||
const report_name = this.qr.report_name;
|
||||
this.report_name.value = report_name;
|
||||
frappe.call({
|
||||
method:'erpnext.accounts.report.tax_detail.tax_detail.new_custom_report',
|
||||
args: {'name': values.report_name},
|
||||
method: 'erpnext.accounts.report.tax_detail.tax_detail.get_custom_reports',
|
||||
args: {name: report_name},
|
||||
freeze: true
|
||||
}).then((r) => {
|
||||
frappe.set_route("query-report", values.report_name);
|
||||
const data = JSON.parse(r.message[report_name]['json']);
|
||||
if (data && data['sections']) {
|
||||
this.sections = data['sections'];
|
||||
} else {
|
||||
this.sections = {};
|
||||
}
|
||||
this.set_section();
|
||||
})
|
||||
this.loaded = 1;
|
||||
}
|
||||
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,
|
||||
columns: this.qr.get_visible_columns(),
|
||||
sections: this.sections
|
||||
},
|
||||
freeze: true
|
||||
}).then((r) => {
|
||||
this.reload();
|
||||
});
|
||||
}
|
||||
set_value_options() {
|
||||
let curcols = [];
|
||||
let options = [];
|
||||
this.fieldname_lookup = {};
|
||||
this.label_lookup = {};
|
||||
this.qr.columns.forEach((col, index) => {
|
||||
if (col['fieldtype'] == "Currency") {
|
||||
curcols.push(index);
|
||||
options.push(col['label']);
|
||||
this.fieldname_lookup[col['label']] = col['fieldname'];
|
||||
this.label_lookup[col['fieldname']] = col['label'];
|
||||
}
|
||||
});
|
||||
this.currency_cols = curcols;
|
||||
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]);
|
||||
}
|
||||
add_value_field_to_filters(filters) {
|
||||
set_value_label_from_filter() {
|
||||
const section_name = this.controls['section_name'].value;
|
||||
const fidx = this.controls['filter_index'].value;
|
||||
if (section_name && fidx) {
|
||||
const fieldname = this.sections[section_name][fidx]['fieldname'];
|
||||
this.controls['value_field'].set_input(this.label_lookup[fieldname]);
|
||||
} else {
|
||||
this.controls['value_field'].set_input(Object.keys(this.fieldname_lookup)[0]);
|
||||
}
|
||||
}
|
||||
get_value_fieldname() {
|
||||
const curlabel = this.controls['value_field'].value;
|
||||
this.currency_cols.forEach(index => {
|
||||
if (this.qr.columns[index]['label'] == curlabel) {
|
||||
filters['fieldname'] = this.qr.columns[index]['fieldname'];
|
||||
}
|
||||
});
|
||||
return filters;
|
||||
return this.fieldname_lookup[curlabel];
|
||||
}
|
||||
new_section(label) {
|
||||
const dialog = new frappe.ui.Dialog({
|
||||
@ -123,57 +158,87 @@ class TaxReport {
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
set_section(name) {
|
||||
this.mode = 'edit';
|
||||
if (name && !this.sections[name]) {
|
||||
this.sections[name] = {};
|
||||
this.controls['section_name'].$wrapper.find("select").empty().add_options(Object.keys(this.sections));
|
||||
}
|
||||
if (name) {
|
||||
this.controls['section_name'].set_input(name);
|
||||
}
|
||||
this.reload();
|
||||
}
|
||||
reload() {
|
||||
if (this.mode == 'edit') {
|
||||
const section_name = this.controls['section_name'].value;
|
||||
let filters = {};
|
||||
if (section_name) {
|
||||
let fidx = this.controls['filter_index'].value;
|
||||
let section = this.sections[section_name];
|
||||
let fidxs = Object.keys(section);
|
||||
fidxs.unshift('');
|
||||
this.controls['filter_index'].$wrapper.find("select").empty().add_options(fidxs);
|
||||
this.controls['filter_index'].set_input(fidx);
|
||||
if (fidx != '') {
|
||||
filters = section[fidx];
|
||||
}
|
||||
} else {
|
||||
this.controls['filter_index'].$wrapper.find("select").empty();
|
||||
get_filter_controls() {
|
||||
this.qr.filters.forEach(filter => {
|
||||
if (filter['fieldname'] == 'mode') {
|
||||
this.mode = filter;
|
||||
}
|
||||
// Set filters
|
||||
// reload datatable
|
||||
} else {
|
||||
this.controls['filter_index'].$wrapper.find("select").empty();
|
||||
// Query the result from the server & render
|
||||
}
|
||||
}
|
||||
get_select(label, list, type) {
|
||||
const dialog = new frappe.ui.Dialog({
|
||||
title: label,
|
||||
fields: [{
|
||||
fieldname: 'select',
|
||||
label: label,
|
||||
fieldtype: 'Select',
|
||||
options: list
|
||||
}],
|
||||
primary_action_label: label,
|
||||
primary_action: (values) => {
|
||||
dialog.hide();
|
||||
this.exec_select(values.select, type);
|
||||
if (filter['fieldname'] == 'report_name') {
|
||||
this.report_name = filter;
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
set_mode(mode) {
|
||||
this.mode.value = mode;
|
||||
}
|
||||
edit_mode() {
|
||||
return this.mode.value == 'edit';
|
||||
}
|
||||
set_section(name) {
|
||||
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);
|
||||
if (name) {
|
||||
this.controls['section_name'].set_input(name);
|
||||
} else {
|
||||
this.controls['section_name'].set_input('');
|
||||
}
|
||||
if (this.controls['section_name'].value) {
|
||||
this.set_mode('edit');
|
||||
} else {
|
||||
this.set_mode('run');
|
||||
}
|
||||
this.controls['filter_index'].set_input('');
|
||||
this.reload();
|
||||
}
|
||||
reload_filter() {
|
||||
const section_name = this.controls['section_name'].value;
|
||||
if (section_name) {
|
||||
let fidx = this.controls['filter_index'].value;
|
||||
let section = this.sections[section_name];
|
||||
let fidxs = Object.keys(section);
|
||||
fidxs.unshift('');
|
||||
this.controls['filter_index'].$wrapper.find("select").empty().add_options(fidxs);
|
||||
this.controls['filter_index'].set_input(fidx);
|
||||
} else {
|
||||
this.controls['filter_index'].$wrapper.find("select").empty();
|
||||
this.controls['filter_index'].set_input('');
|
||||
}
|
||||
this.set_filters();
|
||||
}
|
||||
set_filters() {
|
||||
let filters = {};
|
||||
const section_name = this.controls['section_name'].value;
|
||||
const fidx = this.controls['filter_index'].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) {
|
||||
Array.from(this.qr.datatable.header.querySelectorAll('.dt-filter')).map(function setFilters(input) {
|
||||
let idx = input.dataset.colIndex;
|
||||
if (filters[idx]) {
|
||||
input.value = filters[idx];
|
||||
} else {
|
||||
input.value = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
reload() {
|
||||
// Reloads the data. When the datatable is reloaded, load_report()
|
||||
// will be run by the after_datatable_render event.
|
||||
this.qr.refresh();
|
||||
if (this.edit_mode()) {
|
||||
this.reload_filter();
|
||||
} else {
|
||||
this.controls['filter_index'].$wrapper.find("select").empty();
|
||||
}
|
||||
}
|
||||
delete(name, type) {
|
||||
if (type === 'section') {
|
||||
@ -200,7 +265,7 @@ class TaxReport {
|
||||
fieldtype: 'Select',
|
||||
fieldname: 'section_name',
|
||||
change: (e) => {
|
||||
this.set_section();
|
||||
this.set_section(this.controls['section_name'].get_input_value());
|
||||
}
|
||||
});
|
||||
// BUTTON in button.js
|
||||
@ -229,7 +294,8 @@ class TaxReport {
|
||||
fieldtype: 'Select',
|
||||
fieldname: 'filter_index',
|
||||
change: (e) => {
|
||||
// TODO
|
||||
this.controls['filter_index'].set_input(this.controls['filter_index'].get_input_value());
|
||||
this.set_filters();
|
||||
}
|
||||
});
|
||||
controls['add_filter'] = this.page.add_field({
|
||||
@ -240,17 +306,19 @@ class TaxReport {
|
||||
let section_name = this.controls['section_name'].value;
|
||||
if (section_name) {
|
||||
let prefix = 'Filter';
|
||||
let filters = this.qr.datatable.columnmanager.getAppliedFilters();
|
||||
filters = this.add_value_field_to_filters(filters);
|
||||
let data = {
|
||||
filters: this.qr.datatable.columnmanager.getAppliedFilters(),
|
||||
fieldname: this.get_value_fieldname()
|
||||
}
|
||||
const fidxs = Object.keys(this.sections[section_name]);
|
||||
let new_idx = prefix + '0';
|
||||
if (fidxs.length > 0) {
|
||||
const fiidxs = fidxs.map((key) => parseInt(key.replace(prefix, '')));
|
||||
new_idx = prefix + (Math.max(...fiidxs) + 1).toString();
|
||||
}
|
||||
this.sections[section_name][new_idx] = filters;
|
||||
this.sections[section_name][new_idx] = data;
|
||||
this.controls['filter_index'].set_input(new_idx);
|
||||
this.reload();
|
||||
this.reload_filter();
|
||||
} else {
|
||||
frappe.throw(__('Please add or select the Section first'));
|
||||
}
|
||||
@ -273,7 +341,7 @@ class TaxReport {
|
||||
fieldtype: 'Select',
|
||||
fieldname: 'value_field',
|
||||
change: (e) => {
|
||||
// TODO
|
||||
this.controls['value_field'].set_input(this.controls['value_field'].get_input_value());
|
||||
}
|
||||
});
|
||||
controls['save'] = this.page.add_field({
|
||||
@ -281,17 +349,22 @@ class TaxReport {
|
||||
fieldtype: 'Button',
|
||||
fieldname: 'save',
|
||||
click: () => {
|
||||
// TODO: Save to db
|
||||
this.mode = 'run';
|
||||
this.reload();
|
||||
this.controls['section_name'].set_input('');
|
||||
this.set_mode('run');
|
||||
this.save_report();
|
||||
}
|
||||
});
|
||||
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.');
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -306,6 +379,20 @@ 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"),
|
||||
@ -320,8 +407,13 @@ function new_report() {
|
||||
primary_action_label: __('Create'),
|
||||
primary_action: function new_report_pa(values) {
|
||||
frappe.call({
|
||||
method:'erpnext.accounts.report.tax_detail.tax_detail.new_custom_report',
|
||||
args: {'name': values.report_name},
|
||||
method:'erpnext.accounts.report.tax_detail.tax_detail.save_custom_report',
|
||||
args: {
|
||||
reference_report: 'Tax Detail',
|
||||
report_name: values.report_name,
|
||||
columns: frappe.query_report.get_visible_columns(),
|
||||
sections: {}
|
||||
},
|
||||
freeze: true
|
||||
}).then((r) => {
|
||||
frappe.set_route("query-report", values.report_name);
|
||||
|
@ -3,7 +3,7 @@
|
||||
# Contributed by Case Solved and sponsored by Nulight Studios
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe, json
|
||||
from frappe import _
|
||||
|
||||
# field lists in multiple doctypes will be coalesced
|
||||
@ -16,15 +16,12 @@ required_sql_fields = {
|
||||
# "Journal Entry Account": ["debit_in_account_currency", "credit_in_account_currency"]
|
||||
}
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_required_fieldlist():
|
||||
"""For overriding the fieldlist from the client"""
|
||||
return required_sql_fields
|
||||
|
||||
def execute(filters=None, fieldlist=required_sql_fields):
|
||||
def execute(filters=None):
|
||||
if not filters:
|
||||
return [], []
|
||||
|
||||
fieldlist = required_sql_fields
|
||||
fieldstr = get_fieldstr(fieldlist)
|
||||
|
||||
gl_entries = frappe.db.sql("""
|
||||
@ -136,9 +133,12 @@ custom_report_dict = {
|
||||
}
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_custom_reports():
|
||||
def get_custom_reports(name=None):
|
||||
filters = custom_report_dict.copy()
|
||||
if name:
|
||||
filters['name'] = name
|
||||
reports = frappe.get_list('Report',
|
||||
filters = custom_report_dict,
|
||||
filters = filters,
|
||||
fields = ['name', 'json'],
|
||||
as_list=False
|
||||
)
|
||||
@ -148,22 +148,34 @@ def get_custom_reports():
|
||||
return reports_dict
|
||||
|
||||
@frappe.whitelist()
|
||||
def new_custom_report(name=None):
|
||||
if name == 'Tax Detail':
|
||||
frappe.throw("The parent report cannot be overwritten.")
|
||||
if not name:
|
||||
frappe.throw("The report name must be supplied.")
|
||||
def save_custom_report(reference_report, report_name, columns, sections):
|
||||
import pymysql
|
||||
if reference_report != 'Tax Detail':
|
||||
frappe.throw(_("The wrong report is referenced."))
|
||||
if report_name == 'Tax Detail':
|
||||
frappe.throw(_("The parent report cannot be overwritten."))
|
||||
|
||||
data = {
|
||||
'columns': json.loads(columns),
|
||||
'sections': json.loads(sections)
|
||||
}
|
||||
|
||||
doc = {
|
||||
'doctype': 'Report',
|
||||
'report_name': name,
|
||||
'report_name': report_name,
|
||||
'is_standard': 'No',
|
||||
'module': 'Accounts'
|
||||
'module': 'Accounts',
|
||||
'json': json.dumps(data, separators=(',', ':'))
|
||||
}
|
||||
doc.update(custom_report_dict)
|
||||
doc = frappe.get_doc(doc)
|
||||
doc.insert()
|
||||
return True
|
||||
|
||||
@frappe.whitelist()
|
||||
def save_custom_report(data):
|
||||
return None
|
||||
try:
|
||||
newdoc = frappe.get_doc(doc)
|
||||
newdoc.insert()
|
||||
frappe.msgprint(_("Report created successfully"))
|
||||
except (frappe.exceptions.DuplicateEntryError, pymysql.err.IntegrityError):
|
||||
dbdoc = frappe.get_doc('Report', report_name)
|
||||
dbdoc.update(doc)
|
||||
dbdoc.save()
|
||||
frappe.msgprint(_("Report updated successfully"))
|
||||
return report_name
|
||||
|
Loading…
x
Reference in New Issue
Block a user