From 66f10cd14fce583b608c0d2b9e9ace9f7d680a67 Mon Sep 17 00:00:00 2001 From: Saurabh Date: Fri, 7 Jun 2013 18:05:16 +0530 Subject: [PATCH 01/21] Quotation Trend --- selling/page/selling_home/selling_home.js | 5 + selling/report/quotation_trends/__init__.py | 0 .../quotation_trends/quotation_trends.js | 40 ++++++++ .../quotation_trends/quotation_trends.py | 96 +++++++++++++++++++ .../quotation_trends/quotation_trends.txt | 22 +++++ 5 files changed, 163 insertions(+) create mode 100644 selling/report/quotation_trends/__init__.py create mode 100644 selling/report/quotation_trends/quotation_trends.js create mode 100644 selling/report/quotation_trends/quotation_trends.py create mode 100644 selling/report/quotation_trends/quotation_trends.txt diff --git a/selling/page/selling_home/selling_home.js b/selling/page/selling_home/selling_home.js index 9c18fda681..15f9b86162 100644 --- a/selling/page/selling_home/selling_home.js +++ b/selling/page/selling_home/selling_home.js @@ -170,6 +170,11 @@ wn.module_page["Selling"] = [ route: "query-report/Customers Not Buying Since Long Time", doctype: "Sales Order" }, + { + "label":wn._("Quotation Trend"), + route: "query-report/Quotation Trends", + doctype: "Sales Order" + }, ] } diff --git a/selling/report/quotation_trends/__init__.py b/selling/report/quotation_trends/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/selling/report/quotation_trends/quotation_trends.js b/selling/report/quotation_trends/quotation_trends.js new file mode 100644 index 0000000000..e55e252c0b --- /dev/null +++ b/selling/report/quotation_trends/quotation_trends.js @@ -0,0 +1,40 @@ +wn.query_reports["Quotation Trends"] = { + "filters": [ + { + "fieldname":"period", + "label": "Period", + "fieldtype": "Select", + "options": "Monthly"+NEWLINE+"Quarterly"+NEWLINE+"Half-yearly"+NEWLINE+"Yearly", + "default": "Monthly" + }, + { + "fieldname":"based_on", + "label": "Based On", + "fieldtype": "Select", + "options": "Item"+NEWLINE+"Item Group"+NEWLINE+"Customer"+NEWLINE+"Customer Group"+NEWLINE+"Territory"+NEWLINE+"Project", + "default": "Item" + }, + { + "fieldname":"group_by", + "label": "Group By", + "fieldtype": "Select", + "options": "Item"+NEWLINE+"Customer", + "default": "Customer" + }, + { + "fieldname":"fiscal_year", + "label": "Fiscal Year", + "fieldtype": "Link", + "options":'Fiscal Year', + "default": "Fiscal Year" + }, + { + "fieldname":"company", + "label": "Company", + "fieldtype": "Link", + "options": "Company", + "default": "Company" + }, + + ] +} \ No newline at end of file diff --git a/selling/report/quotation_trends/quotation_trends.py b/selling/report/quotation_trends/quotation_trends.py new file mode 100644 index 0000000000..5b9fc04fb3 --- /dev/null +++ b/selling/report/quotation_trends/quotation_trends.py @@ -0,0 +1,96 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import unicode_literals +import webnotes +from webnotes.utils import getdate, cint + +def execute(filters=None): + if not filters: filters ={} + + period = filters.get("period") + based_on = filters.get("based_on") + group_by = filters.get("group_by") + + columns = get_columns(filters, period, based_on, group_by) + data = [] + + return columns, data + +def get_columns(filters, period, based_on, group_by): + columns = [] + pwc = [] + bon = [] + gby = [] + + if not (period and based_on): + webnotes.msgprint("Value missing in 'Period' or 'Based On'",raise_exception=1) + elif based_on == group_by: + webnotes.msgprint("Plese select different values in 'Based On' and 'Group By'") + else: + pwc = period_wise_column(filters, period, pwc) + bon = base_wise_column(based_on, bon) + gby = gruoup_wise_column(group_by) + + if gby: + columns = bon + gby + pwc + else: + columns = bon + pwc + return columns + + +def period_wise_column(filters, period, pwc): + + if period == "Monthly": + month_name = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] + for month in range(0,len(month_name)): + pwc.append(month_name[month]+' (Qty):Float:120') + pwc.append(month_name[month]+' (Amt):Currency:120') + + elif period == "Quarterly": + pwc = ["Q1(qty):Float:120", "Q1(amt):Currency:120", "Q2(qty):Float:120", "Q2(amt):Currency:120", + "Q3(qty):Float:120", "Q3(amt):Currency:120", "Q4(qty):Float:120", "Q4(amt):Currency:120" + ] + + elif period == "Half-yearly": + pwc = ["Fisrt Half(qty):Float:120", "Fisrt Half(amt):Currency:120", "Second Half(qty):Float:120", + "Second Half(amt):Currency:120" + ] + else: + pwc = [filters.get("fiscal_year")+"(qty):Float:120", filters.get("fiscal_year")+"(amt):Currency:120"] + + return pwc + +def base_wise_column(based_on, bon): + if based_on == "Item": + bon = ["Item:Link/Item:120", "Item Name:Data:120"] + elif based_on == "Item Group": + bon = ["Item Group:Link/Item Group:120"] + elif based_on == "Customer": + bon = ["Customer:Link/Customer:120", "Territory:Link/Territory:120"] + elif based_on == "Customer Group": + bon = ["Customer Group:Link/Customer Group"] + elif based_on == "Territory": + bon = ["Territory:Link/Territory:120"] + else: + bon = ["Project:Link/Project:120"] + return bon + +def gruoup_wise_column(group_by): + if group_by: + return [group_by+":Link/"+group_by+":120"] + else: + return [] \ No newline at end of file diff --git a/selling/report/quotation_trends/quotation_trends.txt b/selling/report/quotation_trends/quotation_trends.txt new file mode 100644 index 0000000000..a135c34560 --- /dev/null +++ b/selling/report/quotation_trends/quotation_trends.txt @@ -0,0 +1,22 @@ +[ + { + "creation": "2013-06-07 16:01:16", + "docstatus": 0, + "modified": "2013-06-07 16:01:16", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "add_total_row": 1, + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Quotation", + "report_name": "Quotation Trends", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "Quotation Trends" + } +] \ No newline at end of file From f75ebb5a1bc940db2d5d47e4da060a8841d26cc1 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Tue, 11 Jun 2013 10:23:10 +0530 Subject: [PATCH 02/21] Report partially completed - Territory Target Variance(Item-Group Wise) --- selling/page/selling_home/selling_home.js | 4 + .../__init__.py | 0 ...itory_target_variance_(item_group_wise).js | 25 ++++++ ...itory_target_variance_(item_group_wise).py | 89 +++++++++++++++++++ ...tory_target_variance_(item_group_wise).txt | 21 +++++ 5 files changed, 139 insertions(+) create mode 100644 selling/report/territory_target_variance_(item_group_wise)/__init__.py create mode 100644 selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).js create mode 100644 selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py create mode 100644 selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).txt diff --git a/selling/page/selling_home/selling_home.js b/selling/page/selling_home/selling_home.js index 682978bd17..7d0162d2ab 100644 --- a/selling/page/selling_home/selling_home.js +++ b/selling/page/selling_home/selling_home.js @@ -165,6 +165,10 @@ wn.module_page["Selling"] = [ "label":wn._("Item-wise Sales History"), route: "query-report/Item-wise Sales History", }, + { + "label":wn._("Territory Target Variance (Item Group-Wise)"), + route: "query-report/Territory Target Variance (Item Group-Wise)", + }, ] } ] diff --git a/selling/report/territory_target_variance_(item_group_wise)/__init__.py b/selling/report/territory_target_variance_(item_group_wise)/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).js b/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).js new file mode 100644 index 0000000000..58718a4e0b --- /dev/null +++ b/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).js @@ -0,0 +1,25 @@ +wn.query_reports["Territory Target Variance (Item Group-Wise)"] = { + "filters": [ + { + fieldname: "fiscal_year", + label: "Fiscal Year", + fieldtype: "Link", + options: "Fiscal Year", + default: sys_defaults.fiscal_year + }, + { + fieldname: "period", + label: "Period", + fieldtype: "Select", + options: "Monthly\nQuarterly\nHalf-Yearly\nYearly", + default: "Monthly" + }, + { + fieldname: "target_on", + label: "Target On", + fieldtype: "Select", + options: "Quantity\nAmount", + default: "Quantity" + }, + ] +} \ No newline at end of file diff --git a/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py b/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py new file mode 100644 index 0000000000..790c6f02ad --- /dev/null +++ b/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py @@ -0,0 +1,89 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import unicode_literals +import webnotes +import calendar +from webnotes import msgprint +from webnotes.utils import cint, cstr, add_months + +def execute(filters=None): + if not filters: filters = {} + + columns = get_columns(filters) + + data = [] + + return columns, data + +def get_columns(filters): + """return columns based on filters""" + + if not filters.get("period"): + msgprint("Please select the Period", raise_exception=1) + + mo = cint(cstr(webnotes.conn.get_value("Fiscal Year", filters["fiscal_year"], "year_start_date")).split("-")[1]) + period_months = [] + if (filters["period"] == "Monthly" or "Yearly"): + for x in range(0,12): + period_months.append(mo) + if (mo!=12): + mo += 1 + else: + mo = 1 + + columns = ["Territory:Link/Territory:80"] + ["Item Group:Link/Item Group:80"] + + period = [] + + if (filters["period"] == "Monthly" or "Yearly"): + for i in (0,12): + period.append("Target (" + "i" + ")::80") + period.append("Achieved (" + "i" + ")::80") + period.append("Variance (" + "i" + ")::80") + + columns = columns + [(p) for p in period] + \ + ["Total Target::80"] + ["Total Achieved::80"] + ["Total Variance::80"] + + return columns + +def get_conditions(filters): + conditions = "" + + if filters.get("fiscal_year"): + conditions += " and posting_date <= '%s'" % filters["fiscal_year"] + else: + webnotes.msgprint("Please enter Fiscal Year", raise_exception=1) + + if filters.get("target_on"): + conditions += " and posting_date <= '%s'" % filters["target_on"] + else: + webnotes.msgprint("Please select Target On", raise_exception=1) + + return conditions + + +#get territory details +def get_territory_details(filters): + conditions = get_conditions(filters) + return webnotes.conn.sql("""select item_code, batch_no, warehouse, + posting_date, actual_qty + from `tabStock Ledger Entry` + where ifnull(is_cancelled, 'No') = 'No' %s order by item_code, warehouse""" % + conditions, as_dict=1) + +def get_month_abbr(month_number): + return 0 \ No newline at end of file diff --git a/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).txt b/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).txt new file mode 100644 index 0000000000..7fff64a861 --- /dev/null +++ b/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).txt @@ -0,0 +1,21 @@ +[ + { + "creation": "2013-06-07 15:13:13", + "docstatus": 0, + "modified": "2013-06-07 15:13:13", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Sales Order", + "report_name": "Territory Target Variance (Item Group-Wise)", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "Territory Target Variance (Item Group-Wise)" + } +] \ No newline at end of file From 85e1026325253f15d133a6b2fd3accd35726433f Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Tue, 11 Jun 2013 11:17:56 +0530 Subject: [PATCH 03/21] Fixed selling_home.js conflicted during merge --- selling/page/selling_home/selling_home.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/selling/page/selling_home/selling_home.js b/selling/page/selling_home/selling_home.js index 5996625577..e3663c93e4 100644 --- a/selling/page/selling_home/selling_home.js +++ b/selling/page/selling_home/selling_home.js @@ -159,16 +159,18 @@ wn.module_page["Selling"] = [ }, { "label":wn._("Sales Person-wise Transaction Summary"), - route: "query-report/Sales Person-wise Transaction Summary", + route: "query-report/Sales Person-wise Transaction Summary" }, { "label":wn._("Item-wise Sales History"), - route: "query-report/Item-wise Sales History", + route: "query-report/Item-wise Sales History" }, { "label":wn._("Territory Target Variance (Item Group-Wise)"), route: "query-report/Territory Target Variance (Item Group-Wise)", + doctype: "Sales Order" }, + { "label":wn._("Customers Not Buying Since Long Time"), route: "query-report/Customers Not Buying Since Long Time", doctype: "Sales Order" From bcbd9a48008e80326d584260a23037fc305341c3 Mon Sep 17 00:00:00 2001 From: Saurabh Date: Tue, 11 Jun 2013 18:06:58 +0530 Subject: [PATCH 04/21] [Report][Quotation Trend] --- .../trend_analyzer/trend_analyzer.py | 6 +- .../quotation_trends/quotation_trends.js | 6 +- .../quotation_trends/quotation_trends.py | 134 ++++++++++++++---- 3 files changed, 110 insertions(+), 36 deletions(-) diff --git a/accounts/search_criteria/trend_analyzer/trend_analyzer.py b/accounts/search_criteria/trend_analyzer/trend_analyzer.py index 87e1e8ed09..9bdde392b4 100644 --- a/accounts/search_criteria/trend_analyzer/trend_analyzer.py +++ b/accounts/search_criteria/trend_analyzer/trend_analyzer.py @@ -155,10 +155,8 @@ for r in res: for d in range(len(colnames) - cr): r.append(flt(main_det[0][d])) out.append(r) - if group_by: flag = 1 - # check for root nodes if based_on in ['Item Group','Customer Group','Territory']: is_grp = sql("select is_group from `tab%s` where name = '%s'" % (based_on, cstr(r[col_idx[based_on]]).strip())) is_grp = is_grp and cstr(is_grp[0][0]) or '' @@ -167,11 +165,11 @@ for r in res: if flag == 1: det = [x[0] for x in sql("SELECT DISTINCT %s FROM %s where %s" % (sel_col, add_tab, add_cond % {'value':cstr(r[col_idx[based_on]]).strip()}))] - for des in range(len(det)): t_row = ['' for i in range(len(colnames))] t_row[col_idx[group_by]] = cstr(det[des]) gr_det = sql("SELECT %s FROM %s WHERE %s = '%s' and %s" % (query_val, add_tab, sel_col, cstr(det[des]), add_cond % {'value':cstr(r[col_idx[based_on]]).strip()})) + webnotes.errprint(cstr(r[col_idx[based_on]]).strip()) for d in range(len(col_names)): t_row[col_idx[col_names[d]]] = flt(gr_det[0][d]) - out.append(t_row) + out.append(t_row) \ No newline at end of file diff --git a/selling/report/quotation_trends/quotation_trends.js b/selling/report/quotation_trends/quotation_trends.js index e55e252c0b..e166fa66ce 100644 --- a/selling/report/quotation_trends/quotation_trends.js +++ b/selling/report/quotation_trends/quotation_trends.js @@ -19,21 +19,21 @@ wn.query_reports["Quotation Trends"] = { "label": "Group By", "fieldtype": "Select", "options": "Item"+NEWLINE+"Customer", - "default": "Customer" + "default": "" }, { "fieldname":"fiscal_year", "label": "Fiscal Year", "fieldtype": "Link", "options":'Fiscal Year', - "default": "Fiscal Year" + "default": sys_defaults.fiscal_year }, { "fieldname":"company", "label": "Company", "fieldtype": "Link", "options": "Company", - "default": "Company" + "default": sys_defaults.company }, ] diff --git a/selling/report/quotation_trends/quotation_trends.py b/selling/report/quotation_trends/quotation_trends.py index 5b9fc04fb3..6a81d97f16 100644 --- a/selling/report/quotation_trends/quotation_trends.py +++ b/selling/report/quotation_trends/quotation_trends.py @@ -16,78 +16,154 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import getdate, cint +from webnotes.utils import cint, add_days, add_months, cstr def execute(filters=None): if not filters: filters ={} - - period = filters.get("period") - based_on = filters.get("based_on") - group_by = filters.get("group_by") - columns = get_columns(filters, period, based_on, group_by) - data = [] + # Global data + ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name = '%s'"%filters.get("fiscal_year"))[0][0] + year_start_date = ysd.strftime('%Y-%m-%d') + start_month = cint(year_start_date.split('-')[1]) + + columns, query_bon, query_pwc, group_by = get_columns(filters, year_start_date, start_month) + + ptab = "tabQuotation" + ctab = "tabQuotation Item" + data = get_data(filters, ptab, ctab, query_bon, query_pwc, group_by) return columns, data -def get_columns(filters, period, based_on, group_by): - columns = [] - pwc = [] - bon = [] - gby = [] +def get_columns(filters, year_start_date, start_month): + columns, pwc, bon, gby = [], [], [], [] + query_bon, query_pwc = '', '' + + period = filters.get("period") + based_on = filters.get("based_on") + grby = filters.get("group_by") if not (period and based_on): - webnotes.msgprint("Value missing in 'Period' or 'Based On'",raise_exception=1) - elif based_on == group_by: - webnotes.msgprint("Plese select different values in 'Based On' and 'Group By'") + webnotes.msgprint("Value missing in 'Period' or 'Based On'", raise_exception=1) + elif based_on == grby: + webnotes.msgprint("Plese select different values in 'Based On' and 'Group By'", raise_exception=1) else: - pwc = period_wise_column(filters, period, pwc) - bon = base_wise_column(based_on, bon) - gby = gruoup_wise_column(group_by) + bon,query_bon,group_by = base_wise_column(based_on, bon) + pwc,query_pwc = period_wise_column_and_query(filters, period, pwc, year_start_date,start_month) + gby = gruoup_wise_column(grby) if gby: - columns = bon + gby + pwc + columns = bon + gby + pwc +["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] else: - columns = bon + pwc - return columns + columns = bon + pwc + ["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] + return columns, query_bon, query_pwc, group_by -def period_wise_column(filters, period, pwc): +def get_data(filters, ptab, ctab, query_bon, query_pwc, group_by): + query_details = query_bon + query_pwc + 'SUM(t2.qty), SUM(t1.grand_total) ' + query_pwc = query_pwc + 'SUM(t2.qty), SUM(t1.grand_total)' + if not filters.get("group_by"): + data = webnotes.conn.sql(""" select %s from `%s` t1, `%s` t2 + where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' and t1.docstatus = 1 + group by %s + """%(query_details, ptab, ctab, filters.get("company"), filters.get("fiscal_year"), group_by), as_list=1) + + # No coma is included between %s and t2.item_code cause it's already bounded with query_bon + if filters.get("group_by") == 'Item': + data = webnotes.conn.sql(""" select %s t2.item_code, %s from `%s` t1, `%s` t2 + where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' and t1.docstatus = 1 + group by %s, %s"""%( query_bon, query_pwc, ptab, ctab, filters.get("company"), filters.get("fiscal_year"), + group_by,'t2.item_code'), as_list=1) + + if filters.get("group_by") == 'Customer': + data = webnotes.conn.sql(""" select %s t1.customer_name, %s from `%s` t1, `%s` t2 + where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' and t1.docstatus = 1 + group by %s, %s"""%(query_bon, query_pwc, ptab, ctab, filters.get("company"), filters.get("fiscal_year"), group_by, 't1.customer_name'), as_list=1) + + return data + +def period_wise_column_and_query(filters, period, pwc, year_start_date, start_month): + query_details = '' if period == "Monthly": month_name = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] - for month in range(0,len(month_name)): + for month in range(start_month-1,len(month_name)): pwc.append(month_name[month]+' (Qty):Float:120') pwc.append(month_name[month]+' (Amt):Currency:120') + query_details += """Sum(CASE WHEN MONTH(t1.transaction_date)= %(mon_num)s THEN t2.qty ELSE NULL END), + SUM(CASE WHEN MONTH(t1.transaction_date)= %(mon_num)s THEN t1.grand_total ELSE NULL END), + """%{"mon_num": cstr(month+1)} + for month in range(0, start_month-1): + pwc.append(month_name[month]+' (Qty):Float:120') + pwc.append(month_name[month]+' (Amt):Currency:120') + query_details += """Sum(CASE WHEN MONTH(t1.transaction_date)= %(mon_num)s THEN t2.qty ELSE NULL END), + SUM(CASE WHEN MONTH(t1.transaction_date)= %(mon_num)s THEN t1.grand_total ELSE NULL END), + """%{"mon_num": cstr(month+1)} + elif period == "Quarterly": pwc = ["Q1(qty):Float:120", "Q1(amt):Currency:120", "Q2(qty):Float:120", "Q2(amt):Currency:120", - "Q3(qty):Float:120", "Q3(amt):Currency:120", "Q4(qty):Float:120", "Q4(amt):Currency:120" - ] + "Q3(qty):Float:120", "Q3(amt):Currency:120", "Q4(qty):Float:120", "Q4(amt):Currency:120"] + + first_qsd, second_qsd, third_qsd, fourth_qsd = year_start_date, add_months(year_start_date,3), add_months(year_start_date,6), add_months(year_start_date,9) + first_qed, second_qed, third_qed, fourth_qed = add_days(add_months(first_qsd,3),-1), add_days(add_months(second_qsd,3),-1), add_days(add_months(third_qsd,3),-1), add_days(add_months(fourth_qsd,3),-1) + + bet_dates = [[first_qsd,first_qed],[second_qsd,second_qed],[third_qsd,third_qed],[fourth_qsd,fourth_qed]] + for d in bet_dates: + query_details += """ + SUM(CASE WHEN t1.transaction_date BETWEEN '%(sd)s' AND '%(ed)s' THEN t2.qty ELSE NULL END), + SUM(CASE WHEN t1.transaction_date BETWEEN '%(sd)s' AND '%(ed)s' THEN t1.grand_total ELSE NULL END), + """%{"sd": d[0],"ed": d[1]} elif period == "Half-yearly": pwc = ["Fisrt Half(qty):Float:120", "Fisrt Half(amt):Currency:120", "Second Half(qty):Float:120", - "Second Half(amt):Currency:120" - ] + "Second Half(amt):Currency:120"] + + first_half_start = year_start_date + first_half_end = add_days(add_months(first_half_start,6),-1) + second_half_start = add_days(first_half_end,1) + second_half_end = add_days(add_months(second_half_start,6),-1) + + query_details = """ SUM(CASE WHEN t1.transaction_date BETWEEN '%(fhs)s' AND '%(fhe)s' THEN t2.qty ELSE NULL END), + SUM(CASE WHEN t1.transaction_date BETWEEN '%(fhs)s' AND '%(fhe)s' THEN t1.grand_total ELSE NULL END), + SUM(CASE WHEN t1.transaction_date BETWEEN '%(shs)s' AND '%(she)s' THEN t2.qty ELSE NULL END), + SUM(CASE WHEN t1.transaction_date BETWEEN '%(shs)s' AND '%(she)s' THEN t1.grand_total ELSE NULL END), + """%{"fhs": first_half_start, "fhe": first_half_end,"shs": second_half_start, "she": second_half_end} + else: pwc = [filters.get("fiscal_year")+"(qty):Float:120", filters.get("fiscal_year")+"(amt):Currency:120"] + query_details = " SUM(t2.qty), SUM(t1.grand_total)," - return pwc + return pwc, query_details def base_wise_column(based_on, bon): if based_on == "Item": bon = ["Item:Link/Item:120", "Item Name:Data:120"] + query_details = "t2.item_code, t2.item_name," + group_by = 't2.item_code' + elif based_on == "Item Group": bon = ["Item Group:Link/Item Group:120"] + query_details = "t2.item_group," + group_by = 't2.item_group' + elif based_on == "Customer": bon = ["Customer:Link/Customer:120", "Territory:Link/Territory:120"] + query_details = "t1.customer_name, t1.territory, " + group_by = 't1.customer_name' + elif based_on == "Customer Group": bon = ["Customer Group:Link/Customer Group"] + query_details = "t1.customer_group, " + group_by = 't1.customer_group' + elif based_on == "Territory": bon = ["Territory:Link/Territory:120"] + query_details = "t1.territory, " + group_by = 't1.territory' + else: bon = ["Project:Link/Project:120"] - return bon + return bon, query_details, group_by def gruoup_wise_column(group_by): if group_by: From f9966f44cdb553dff236cba71b04336e16a34796 Mon Sep 17 00:00:00 2001 From: Saurabh Date: Wed, 12 Jun 2013 17:55:19 +0530 Subject: [PATCH 05/21] [Report][Quotation Trend Complete] --- .../trend_analyzer/trend_analyzer.py | 4 +- .../quotation_trends/quotation_trends.py | 128 ++++++++++++------ .../quotation_trends/quotation_trends.txt | 4 +- 3 files changed, 93 insertions(+), 43 deletions(-) diff --git a/accounts/search_criteria/trend_analyzer/trend_analyzer.py b/accounts/search_criteria/trend_analyzer/trend_analyzer.py index 9bdde392b4..6bc4cf6f69 100644 --- a/accounts/search_criteria/trend_analyzer/trend_analyzer.py +++ b/accounts/search_criteria/trend_analyzer/trend_analyzer.py @@ -155,8 +155,10 @@ for r in res: for d in range(len(colnames) - cr): r.append(flt(main_det[0][d])) out.append(r) + if group_by: flag = 1 + # check for root nodes if based_on in ['Item Group','Customer Group','Territory']: is_grp = sql("select is_group from `tab%s` where name = '%s'" % (based_on, cstr(r[col_idx[based_on]]).strip())) is_grp = is_grp and cstr(is_grp[0][0]) or '' @@ -165,11 +167,11 @@ for r in res: if flag == 1: det = [x[0] for x in sql("SELECT DISTINCT %s FROM %s where %s" % (sel_col, add_tab, add_cond % {'value':cstr(r[col_idx[based_on]]).strip()}))] + for des in range(len(det)): t_row = ['' for i in range(len(colnames))] t_row[col_idx[group_by]] = cstr(det[des]) gr_det = sql("SELECT %s FROM %s WHERE %s = '%s' and %s" % (query_val, add_tab, sel_col, cstr(det[des]), add_cond % {'value':cstr(r[col_idx[based_on]]).strip()})) - webnotes.errprint(cstr(r[col_idx[based_on]]).strip()) for d in range(len(col_names)): t_row[col_idx[col_names[d]]] = flt(gr_det[0][d]) out.append(t_row) \ No newline at end of file diff --git a/selling/report/quotation_trends/quotation_trends.py b/selling/report/quotation_trends/quotation_trends.py index 6a81d97f16..7f944e0f23 100644 --- a/selling/report/quotation_trends/quotation_trends.py +++ b/selling/report/quotation_trends/quotation_trends.py @@ -22,19 +22,18 @@ def execute(filters=None): if not filters: filters ={} # Global data + trans = "Quotation" + tab = ["tabQuotation","tabQuotation Item"] ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name = '%s'"%filters.get("fiscal_year"))[0][0] year_start_date = ysd.strftime('%Y-%m-%d') start_month = cint(year_start_date.split('-')[1]) - columns, query_bon, query_pwc, group_by = get_columns(filters, year_start_date, start_month) - - ptab = "tabQuotation" - ctab = "tabQuotation Item" - data = get_data(filters, ptab, ctab, query_bon, query_pwc, group_by) + columns, query_bon, query_pwc, group_by, gby = get_columns(filters, year_start_date, start_month, trans) + data = get_data(columns,filters, tab, query_bon, query_pwc, group_by, gby) return columns, data -def get_columns(filters, year_start_date, start_month): +def get_columns(filters, year_start_date, start_month, trans): columns, pwc, bon, gby = [], [], [], [] query_bon, query_pwc = '', '' @@ -44,11 +43,13 @@ def get_columns(filters, year_start_date, start_month): if not (period and based_on): webnotes.msgprint("Value missing in 'Period' or 'Based On'", raise_exception=1) + elif based_on == grby: webnotes.msgprint("Plese select different values in 'Based On' and 'Group By'", raise_exception=1) + else: bon,query_bon,group_by = base_wise_column(based_on, bon) - pwc,query_pwc = period_wise_column_and_query(filters, period, pwc, year_start_date,start_month) + pwc,query_pwc = period_wise_column_and_query(filters, period, pwc, year_start_date,start_month, trans) gby = gruoup_wise_column(grby) if gby: @@ -56,49 +57,95 @@ def get_columns(filters, year_start_date, start_month): else: columns = bon + pwc + ["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] - return columns, query_bon, query_pwc, group_by + return columns, query_bon, query_pwc, group_by,gby -def get_data(filters, ptab, ctab, query_bon, query_pwc, group_by): +def get_data(columns, filters, tab, query_bon, query_pwc, group_by,gby): + query_details = query_bon + query_pwc + 'SUM(t2.qty), SUM(t1.grand_total) ' query_pwc = query_pwc + 'SUM(t2.qty), SUM(t1.grand_total)' - if not filters.get("group_by"): + data = [] + inc = '' + + if filters.get("group_by"): + sel_col = '' + if filters.get("group_by") == 'Item': + sel_col = 't2.item_code' + + elif filters.get("group_by") == 'Customer': + sel_col = 't1.customer' + + if filters.get('based_on') in ['Item','Customer']: + inc = 2 + else : + inc = 1 + + ind = columns.index(gby[0]) + + data1 = webnotes.conn.sql(""" select %s %s from `%s` t1, `%s` t2 + where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' + and t1.docstatus = 1 group by %s """%(query_bon, query_pwc, tab[0], tab[1], + filters.get("company"), filters.get("fiscal_year"), group_by), as_list=1) + + for d in range(len(data1)): + + dt = data1[d] + dt.insert(ind,'') + data.append(dt) + + row = webnotes.conn.sql("""select DISTINCT(%s) from `%s` t1, `%s` t2 + where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' + and t1.docstatus = 1 and %s = '%s' """%(sel_col, tab[0], tab[1], filters.get("company"), + filters.get("fiscal_year"), group_by, data1[d][0]),as_list=1) + + for i in range(len(row)): + des = ['' for q in range(len(columns))] + + row1 = webnotes.conn.sql(""" select %s , %s from `%s` t1, `%s` t2 + where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' + and t1.docstatus = 1 and %s = '%s' and %s ='%s' """%(sel_col, query_pwc, tab[0], tab[1], + filters.get("company"), filters.get("fiscal_year"), sel_col, row[i][0], group_by, + data1[d][0]),as_list=1) + + des[ind] = row[i] + for j in range(1,len(columns)-inc): + des[j+inc] = row1[0][j] + data.append(des) + else: + data = webnotes.conn.sql(""" select %s from `%s` t1, `%s` t2 - where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' and t1.docstatus = 1 - group by %s - """%(query_details, ptab, ctab, filters.get("company"), filters.get("fiscal_year"), group_by), as_list=1) + where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' + and t1.docstatus = 1 group by %s + """%(query_details, tab[0], tab[1], filters.get("company"), filters.get("fiscal_year"), group_by), as_list=1) - # No coma is included between %s and t2.item_code cause it's already bounded with query_bon - if filters.get("group_by") == 'Item': - data = webnotes.conn.sql(""" select %s t2.item_code, %s from `%s` t1, `%s` t2 - where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' and t1.docstatus = 1 - group by %s, %s"""%( query_bon, query_pwc, ptab, ctab, filters.get("company"), filters.get("fiscal_year"), - group_by,'t2.item_code'), as_list=1) - - if filters.get("group_by") == 'Customer': - data = webnotes.conn.sql(""" select %s t1.customer_name, %s from `%s` t1, `%s` t2 - where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' and t1.docstatus = 1 - group by %s, %s"""%(query_bon, query_pwc, ptab, ctab, filters.get("company"), filters.get("fiscal_year"), group_by, 't1.customer_name'), as_list=1) - return data -def period_wise_column_and_query(filters, period, pwc, year_start_date, start_month): +def period_wise_column_and_query(filters, period, pwc, year_start_date, start_month, trans): query_details = '' + if trans in ['Purchase Receipt', 'Delivery Note', 'Purchase Invoice', 'Sales Invoice']: + trans_date = 'posting_date' + else: + trans_date = 'transaction_date' if period == "Monthly": month_name = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] + for month in range(start_month-1,len(month_name)): pwc.append(month_name[month]+' (Qty):Float:120') pwc.append(month_name[month]+' (Amt):Currency:120') - query_details += """Sum(CASE WHEN MONTH(t1.transaction_date)= %(mon_num)s THEN t2.qty ELSE NULL END), - SUM(CASE WHEN MONTH(t1.transaction_date)= %(mon_num)s THEN t1.grand_total ELSE NULL END), - """%{"mon_num": cstr(month+1)} + + query_details += """ + Sum(CASE WHEN MONTH(t1.%(trans)s)= %(mon_num)s THEN t2.qty ELSE NULL END), + SUM(CASE WHEN MONTH(t1.%(trans)s)= %(mon_num)s THEN t1.grand_total ELSE NULL END), + """%{"trans": trans_date,"mon_num": cstr(month+1)} for month in range(0, start_month-1): pwc.append(month_name[month]+' (Qty):Float:120') pwc.append(month_name[month]+' (Amt):Currency:120') - query_details += """Sum(CASE WHEN MONTH(t1.transaction_date)= %(mon_num)s THEN t2.qty ELSE NULL END), - SUM(CASE WHEN MONTH(t1.transaction_date)= %(mon_num)s THEN t1.grand_total ELSE NULL END), - """%{"mon_num": cstr(month+1)} + + query_details += """ + Sum(CASE WHEN MONTH(t1.%(trans)s)= %(mon_num)s THEN t2.qty ELSE NULL END), + SUM(CASE WHEN MONTH(t1.%(trans)s)= %(mon_num)s THEN t1.grand_total ELSE NULL END), + """%{"trans": trans_date, "mon_num": cstr(month+1)} elif period == "Quarterly": pwc = ["Q1(qty):Float:120", "Q1(amt):Currency:120", "Q2(qty):Float:120", "Q2(amt):Currency:120", @@ -110,9 +157,9 @@ def period_wise_column_and_query(filters, period, pwc, year_start_date, start_mo bet_dates = [[first_qsd,first_qed],[second_qsd,second_qed],[third_qsd,third_qed],[fourth_qsd,fourth_qed]] for d in bet_dates: query_details += """ - SUM(CASE WHEN t1.transaction_date BETWEEN '%(sd)s' AND '%(ed)s' THEN t2.qty ELSE NULL END), - SUM(CASE WHEN t1.transaction_date BETWEEN '%(sd)s' AND '%(ed)s' THEN t1.grand_total ELSE NULL END), - """%{"sd": d[0],"ed": d[1]} + SUM(CASE WHEN t1.%(trans)s BETWEEN '%(sd)s' AND '%(ed)s' THEN t2.qty ELSE NULL END), + SUM(CASE WHEN t1.%(trans)s BETWEEN '%(sd)s' AND '%(ed)s' THEN t1.grand_total ELSE NULL END), + """%{"trans": trans_date, "sd": d[0],"ed": d[1]} elif period == "Half-yearly": pwc = ["Fisrt Half(qty):Float:120", "Fisrt Half(amt):Currency:120", "Second Half(qty):Float:120", @@ -123,11 +170,12 @@ def period_wise_column_and_query(filters, period, pwc, year_start_date, start_mo second_half_start = add_days(first_half_end,1) second_half_end = add_days(add_months(second_half_start,6),-1) - query_details = """ SUM(CASE WHEN t1.transaction_date BETWEEN '%(fhs)s' AND '%(fhe)s' THEN t2.qty ELSE NULL END), - SUM(CASE WHEN t1.transaction_date BETWEEN '%(fhs)s' AND '%(fhe)s' THEN t1.grand_total ELSE NULL END), - SUM(CASE WHEN t1.transaction_date BETWEEN '%(shs)s' AND '%(she)s' THEN t2.qty ELSE NULL END), - SUM(CASE WHEN t1.transaction_date BETWEEN '%(shs)s' AND '%(she)s' THEN t1.grand_total ELSE NULL END), - """%{"fhs": first_half_start, "fhe": first_half_end,"shs": second_half_start, "she": second_half_end} + query_details = """ + SUM(CASE WHEN t1.%(trans)s BETWEEN '%(fhs)s' AND '%(fhe)s' THEN t2.qty ELSE NULL END), + SUM(CASE WHEN t1.%(trans)s BETWEEN '%(fhs)s' AND '%(fhe)s' THEN t1.grand_total ELSE NULL END), + SUM(CASE WHEN t1.%(trans)s BETWEEN '%(shs)s' AND '%(she)s' THEN t2.qty ELSE NULL END), + SUM(CASE WHEN t1.%(trans)s BETWEEN '%(shs)s' AND '%(she)s' THEN t1.grand_total ELSE NULL END), + """%{"trans": trans_date, "fhs": first_half_start, "fhe": first_half_end,"shs": second_half_start, "she": second_half_end} else: pwc = [filters.get("fiscal_year")+"(qty):Float:120", filters.get("fiscal_year")+"(amt):Currency:120"] diff --git a/selling/report/quotation_trends/quotation_trends.txt b/selling/report/quotation_trends/quotation_trends.txt index a135c34560..eebffcf84b 100644 --- a/selling/report/quotation_trends/quotation_trends.txt +++ b/selling/report/quotation_trends/quotation_trends.txt @@ -2,12 +2,12 @@ { "creation": "2013-06-07 16:01:16", "docstatus": 0, - "modified": "2013-06-07 16:01:16", + "modified": "2013-06-12 16:31:23", "modified_by": "Administrator", "owner": "Administrator" }, { - "add_total_row": 1, + "add_total_row": 0, "doctype": "Report", "is_standard": "Yes", "name": "__common__", From 0326f5414e4ede793ec7f8bdad7c51e795c69864 Mon Sep 17 00:00:00 2001 From: Saurabh Date: Thu, 13 Jun 2013 19:17:56 +0530 Subject: [PATCH 06/21] [reports][purchase and sales trends] --- .../purchase_invoice_trends/__init__.py | 0 .../purchase_invoice_trends.js | 5 + .../purchase_invoice_trends.py | 37 +++ .../purchase_invoice_trends.txt | 21 ++ .../report/sales_invoice_trends/__init__.py | 0 .../sales_invoice_trends.js | 5 + .../sales_invoice_trends.py | 37 +++ .../sales_invoice_trends.txt | 21 ++ .../report/purchase_order_trends/__init__.py | 0 .../purchase_order_trends.js | 5 + .../purchase_order_trends.py | 37 +++ .../purchase_order_trends.txt | 21 ++ controllers/trends.py | 245 ++++++++++++++++++ public/js/purchase_trends_filters.js | 39 +++ public/js/sales_trends_filters.js | 39 +++ .../quotation_trends/quotation_trends.js | 43 +-- .../quotation_trends/quotation_trends.py | 197 +------------- selling/report/sales_order_trends/__init__.py | 0 .../sales_order_trends/sales_order_trends.js | 5 + .../sales_order_trends/sales_order_trends.py | 37 +++ .../sales_order_trends/sales_order_trends.txt | 21 ++ stock/report/delivery_note_trends/__init__.py | 0 .../delivery_note_trends.js | 5 + .../delivery_note_trends.py | 37 +++ .../delivery_note_trends.txt | 21 ++ .../purchase_receipt_trends/__init__.py | 0 .../purchase_receipt_trends.js | 5 + .../purchase_receipt_trends.py | 37 +++ .../purchase_receipt_trends.txt | 21 ++ 29 files changed, 712 insertions(+), 229 deletions(-) create mode 100644 accounts/report/purchase_invoice_trends/__init__.py create mode 100644 accounts/report/purchase_invoice_trends/purchase_invoice_trends.js create mode 100644 accounts/report/purchase_invoice_trends/purchase_invoice_trends.py create mode 100644 accounts/report/purchase_invoice_trends/purchase_invoice_trends.txt create mode 100644 accounts/report/sales_invoice_trends/__init__.py create mode 100644 accounts/report/sales_invoice_trends/sales_invoice_trends.js create mode 100644 accounts/report/sales_invoice_trends/sales_invoice_trends.py create mode 100644 accounts/report/sales_invoice_trends/sales_invoice_trends.txt create mode 100644 buying/report/purchase_order_trends/__init__.py create mode 100644 buying/report/purchase_order_trends/purchase_order_trends.js create mode 100644 buying/report/purchase_order_trends/purchase_order_trends.py create mode 100644 buying/report/purchase_order_trends/purchase_order_trends.txt create mode 100644 controllers/trends.py create mode 100644 public/js/purchase_trends_filters.js create mode 100644 public/js/sales_trends_filters.js create mode 100644 selling/report/sales_order_trends/__init__.py create mode 100644 selling/report/sales_order_trends/sales_order_trends.js create mode 100644 selling/report/sales_order_trends/sales_order_trends.py create mode 100644 selling/report/sales_order_trends/sales_order_trends.txt create mode 100644 stock/report/delivery_note_trends/__init__.py create mode 100644 stock/report/delivery_note_trends/delivery_note_trends.js create mode 100644 stock/report/delivery_note_trends/delivery_note_trends.py create mode 100644 stock/report/delivery_note_trends/delivery_note_trends.txt create mode 100644 stock/report/purchase_receipt_trends/__init__.py create mode 100644 stock/report/purchase_receipt_trends/purchase_receipt_trends.js create mode 100644 stock/report/purchase_receipt_trends/purchase_receipt_trends.py create mode 100644 stock/report/purchase_receipt_trends/purchase_receipt_trends.txt diff --git a/accounts/report/purchase_invoice_trends/__init__.py b/accounts/report/purchase_invoice_trends/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/accounts/report/purchase_invoice_trends/purchase_invoice_trends.js b/accounts/report/purchase_invoice_trends/purchase_invoice_trends.js new file mode 100644 index 0000000000..bb18ce4cbe --- /dev/null +++ b/accounts/report/purchase_invoice_trends/purchase_invoice_trends.js @@ -0,0 +1,5 @@ +wn.require("app/js/purchase_trends_filters.js"); + +wn.query_reports["Purchase Invoice Trends"] = { + filters: get_filters() + } \ No newline at end of file diff --git a/accounts/report/purchase_invoice_trends/purchase_invoice_trends.py b/accounts/report/purchase_invoice_trends/purchase_invoice_trends.py new file mode 100644 index 0000000000..e74ad2129b --- /dev/null +++ b/accounts/report/purchase_invoice_trends/purchase_invoice_trends.py @@ -0,0 +1,37 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import unicode_literals +import webnotes +from webnotes.utils import cint, add_days, add_months, cstr +from controllers.trends import get_columns,get_data + +def execute(filters=None): + if not filters: filters ={} + data = [] + + trans = "Purchase Invoice" + tab = ["tabPurchase Invoice","tabPurchase Invoice Item"] + ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name = '%s'"%filters.get("fiscal_year"))[0][0] + year_start_date = ysd.strftime('%Y-%m-%d') + start_month = cint(year_start_date.split('-')[1]) + + columns, query_bon, query_pwc, basedon, grbc, sup_tab = get_columns(filters, year_start_date, start_month, trans) + data = get_data(columns,filters, tab, query_bon, query_pwc, basedon, grbc ,sup_tab) + + if data == '': + webnotes.msgprint("Data Not Available") + return columns, data \ No newline at end of file diff --git a/accounts/report/purchase_invoice_trends/purchase_invoice_trends.txt b/accounts/report/purchase_invoice_trends/purchase_invoice_trends.txt new file mode 100644 index 0000000000..1d5c2d5f45 --- /dev/null +++ b/accounts/report/purchase_invoice_trends/purchase_invoice_trends.txt @@ -0,0 +1,21 @@ +[ + { + "creation": "2013-06-13 18:46:55", + "docstatus": 0, + "modified": "2013-06-13 18:46:55", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Purchase Invoice", + "report_name": "Purchase Invoice Trends", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "Purchase Invoice Trends" + } +] \ No newline at end of file diff --git a/accounts/report/sales_invoice_trends/__init__.py b/accounts/report/sales_invoice_trends/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/accounts/report/sales_invoice_trends/sales_invoice_trends.js b/accounts/report/sales_invoice_trends/sales_invoice_trends.js new file mode 100644 index 0000000000..6f20015d21 --- /dev/null +++ b/accounts/report/sales_invoice_trends/sales_invoice_trends.js @@ -0,0 +1,5 @@ +wn.require("app/js/sales_trends_filters.js"); + +wn.query_reports["Sales Invoice Trends"] = { + filters: get_filters() + } \ No newline at end of file diff --git a/accounts/report/sales_invoice_trends/sales_invoice_trends.py b/accounts/report/sales_invoice_trends/sales_invoice_trends.py new file mode 100644 index 0000000000..48606f04ed --- /dev/null +++ b/accounts/report/sales_invoice_trends/sales_invoice_trends.py @@ -0,0 +1,37 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import unicode_literals +import webnotes +from webnotes.utils import cint, add_days, add_months, cstr +from controllers.trends import get_columns,get_data + +def execute(filters=None): + if not filters: filters ={} + data = [] + + trans = "Sales Invoice" + tab = ["tabSales Invoice","tabSales Invoice Item"] + ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name = '%s'"%filters.get("fiscal_year"))[0][0] + year_start_date = ysd.strftime('%Y-%m-%d') + start_month = cint(year_start_date.split('-')[1]) + + columns, query_bon, query_pwc, basedon, grbc, sup_tab = get_columns(filters, year_start_date, start_month, trans) + data = get_data(columns,filters, tab, query_bon, query_pwc, basedon, grbc ,sup_tab) + + if data == '': + webnotes.msgprint("Data Not Available") + return columns, data \ No newline at end of file diff --git a/accounts/report/sales_invoice_trends/sales_invoice_trends.txt b/accounts/report/sales_invoice_trends/sales_invoice_trends.txt new file mode 100644 index 0000000000..279ac1269f --- /dev/null +++ b/accounts/report/sales_invoice_trends/sales_invoice_trends.txt @@ -0,0 +1,21 @@ +[ + { + "creation": "2013-06-13 18:44:21", + "docstatus": 0, + "modified": "2013-06-13 18:44:21", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Sales Invoice", + "report_name": "Sales Invoice Trends", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "Sales Invoice Trends" + } +] \ No newline at end of file diff --git a/buying/report/purchase_order_trends/__init__.py b/buying/report/purchase_order_trends/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/buying/report/purchase_order_trends/purchase_order_trends.js b/buying/report/purchase_order_trends/purchase_order_trends.js new file mode 100644 index 0000000000..c6373db6c2 --- /dev/null +++ b/buying/report/purchase_order_trends/purchase_order_trends.js @@ -0,0 +1,5 @@ +wn.require("app/js/purchase_trends_filters.js"); + +wn.query_reports["Purchase Order Trends"] = { + filters: get_filters() + } \ No newline at end of file diff --git a/buying/report/purchase_order_trends/purchase_order_trends.py b/buying/report/purchase_order_trends/purchase_order_trends.py new file mode 100644 index 0000000000..cdf79b2fad --- /dev/null +++ b/buying/report/purchase_order_trends/purchase_order_trends.py @@ -0,0 +1,37 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import unicode_literals +import webnotes +from webnotes.utils import cint, add_days, add_months, cstr +from controllers.trends import get_columns,get_data + +def execute(filters=None): + if not filters: filters ={} + data = [] + + trans = "Purchase Order" + tab = ["tabPurchase Order","tabPurchase Order Item"] + ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name = '%s'"%filters.get("fiscal_year"))[0][0] + year_start_date = ysd.strftime('%Y-%m-%d') + start_month = cint(year_start_date.split('-')[1]) + + columns, query_bon, query_pwc, basedon, grbc, sup_tab = get_columns(filters, year_start_date, start_month, trans) + data = get_data(columns,filters, tab, query_bon, query_pwc, basedon, grbc ,sup_tab) + + if data == '': + webnotes.msgprint("Data Not Available") + return columns, data \ No newline at end of file diff --git a/buying/report/purchase_order_trends/purchase_order_trends.txt b/buying/report/purchase_order_trends/purchase_order_trends.txt new file mode 100644 index 0000000000..658dd4aab1 --- /dev/null +++ b/buying/report/purchase_order_trends/purchase_order_trends.txt @@ -0,0 +1,21 @@ +[ + { + "creation": "2013-06-13 18:45:01", + "docstatus": 0, + "modified": "2013-06-13 18:45:01", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Purchase Order", + "report_name": "Purchase Order Trends", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "Purchase Order Trends" + } +] \ No newline at end of file diff --git a/controllers/trends.py b/controllers/trends.py new file mode 100644 index 0000000000..6c33235b9f --- /dev/null +++ b/controllers/trends.py @@ -0,0 +1,245 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import unicode_literals +import webnotes +from webnotes.utils import cint, add_days, add_months, cstr + +def get_columns(filters, year_start_date, start_month, trans): + columns, pwc, bon, grbc = [], [], [], [] + query_bon, query_pwc = '', '' + + period = filters.get("period") + based_on = filters.get("based_on") + grby = filters.get("group_by") + + if not (period and based_on): + webnotes.msgprint("Value missing in 'Period' or 'Based On'", raise_exception=1) + + elif based_on == grby: + webnotes.msgprint("Plese select different values in 'Based On' and 'Group By'", raise_exception=1) + + else: + bon, query_bon, basedon, sup_tab = bon_columns_qdata(based_on, bon, trans) + pwc, query_pwc = pw_column_qdata(filters, period, pwc, year_start_date,start_month, trans) + grbc = grp_column(grby) + + if grbc: + columns = bon + grbc + pwc +["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] + else: + columns = bon + pwc + ["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] + + return columns, query_bon, query_pwc, basedon, grbc, sup_tab + +def get_data(columns, filters, tab, query_bon, query_pwc, basedon, grbc, sup_tab): + + query_details = query_bon + query_pwc + 'SUM(t2.qty), SUM(t1.grand_total) ' + query_pwc = query_pwc + 'SUM(t2.qty), SUM(t1.grand_total)' + data = [] + inc, cond= '','' + + if query_bon in ["t1.project_name,", "t2.project_name,"]: + cond = 'and '+ query_bon[:-1] +' IS Not NULL' + + if filters.get("group_by"): + sel_col = '' + + if filters.get("group_by") == 'Item': + sel_col = 't2.item_code' + + elif filters.get("group_by") == 'Customer': + sel_col = 't1.customer' + + elif filters.get("group_by") == 'Supplier': + sel_col = 't1.supplier' + + if filters.get('based_on') in ['Item','Customer','Supplier']: + inc = 2 + else : + inc = 1 + + ind = columns.index(grbc[0]) + + data1 = webnotes.conn.sql(""" select %s %s from `%s` t1, `%s` t2 %s + where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' + and t1.docstatus = 1 %s group by %s + """%(query_bon, query_pwc, tab[0], tab[1], sup_tab,filters.get("company"), filters.get("fiscal_year"), + cond, basedon), as_list=1) + + for d in range(len(data1)): + #to add blanck column + dt = data1[d] + dt.insert(ind,'') + data.append(dt) + + #to get distinct value of col specified by group_by in filter + row = webnotes.conn.sql("""select DISTINCT(%s) from `%s` t1, `%s` t2 + where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' + and t1.docstatus = 1 and %s = '%s' + """%(sel_col, tab[0], tab[1], filters.get("company"), filters.get("fiscal_year"), + basedon, data1[d][0]),as_list=1) + + for i in range(len(row)): + des = ['' for q in range(len(columns))] + + #get data for each group_by filter + row1 = webnotes.conn.sql(""" select %s , %s from `%s` t1, `%s` t2 + where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' + and t1.docstatus = 1 and %s = '%s' and %s ='%s' + """%(sel_col, query_pwc, tab[0], tab[1], filters.get("company"), filters.get("fiscal_year"), + sel_col, row[i][0], basedon, data1[d][0]),as_list=1) + + des[ind] = row[i] + for j in range(1,len(columns)-inc): + des[j+inc] = row1[0][j] + data.append(des) + else: + + data = webnotes.conn.sql(""" select %s from `%s` t1, `%s` t2 %s + where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' + and t1.docstatus = 1 %s group by %s + """%(query_details, tab[0], tab[1], sup_tab, filters.get("company"), + filters.get("fiscal_year"), cond,basedon), as_list=1) + + return data + +def pw_column_qdata(filters, period, pwc, year_start_date, start_month, trans): + query_details = '' + if trans in ['Purchase Receipt', 'Delivery Note', 'Purchase Invoice', 'Sales Invoice']: + trans_date = 'posting_date' + else: + trans_date = 'transaction_date' + + if period == "Monthly": + month_name = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] + + for month in range(start_month-1,len(month_name)): + pwc.append(month_name[month]+' (Qty):Float:120') + pwc.append(month_name[month]+' (Amt):Currency:120') + + query_details += """ + Sum(CASE WHEN MONTH(t1.%(trans)s)= %(mon_num)s THEN t2.qty ELSE NULL END), + SUM(CASE WHEN MONTH(t1.%(trans)s)= %(mon_num)s THEN t1.grand_total ELSE NULL END), + """%{"trans": trans_date,"mon_num": cstr(month+1)} + + for month in range(0, start_month-1): + pwc.append(month_name[month]+' (Qty):Float:120') + pwc.append(month_name[month]+' (Amt):Currency:120') + + query_details += """ + Sum(CASE WHEN MONTH(t1.%(trans)s)= %(mon_num)s THEN t2.qty ELSE NULL END), + SUM(CASE WHEN MONTH(t1.%(trans)s)= %(mon_num)s THEN t1.grand_total ELSE NULL END), + """%{"trans": trans_date, "mon_num": cstr(month+1)} + + elif period == "Quarterly": + pwc = ["Q1(qty):Float:120", "Q1(amt):Currency:120", "Q2(qty):Float:120", "Q2(amt):Currency:120", + "Q3(qty):Float:120", "Q3(amt):Currency:120", "Q4(qty):Float:120", "Q4(amt):Currency:120"] + + first_qsd, second_qsd, third_qsd, fourth_qsd = year_start_date, add_months(year_start_date,3), add_months(year_start_date,6), add_months(year_start_date,9) + first_qed, second_qed, third_qed, fourth_qed = add_days(add_months(first_qsd,3),-1), add_days(add_months(second_qsd,3),-1), add_days(add_months(third_qsd,3),-1), add_days(add_months(fourth_qsd,3),-1) + + bet_dates = [[first_qsd,first_qed],[second_qsd,second_qed],[third_qsd,third_qed],[fourth_qsd,fourth_qed]] + for d in bet_dates: + query_details += """ + SUM(CASE WHEN t1.%(trans)s BETWEEN '%(sd)s' AND '%(ed)s' THEN t2.qty ELSE NULL END), + SUM(CASE WHEN t1.%(trans)s BETWEEN '%(sd)s' AND '%(ed)s' THEN t1.grand_total ELSE NULL END), + """%{"trans": trans_date, "sd": d[0],"ed": d[1]} + + elif period == "Half-yearly": + pwc = ["Fisrt Half(qty):Float:120", "Fisrt Half(amt):Currency:120", "Second Half(qty):Float:120", + "Second Half(amt):Currency:120"] + + first_half_start = year_start_date + first_half_end = add_days(add_months(first_half_start,6),-1) + second_half_start = add_days(first_half_end,1) + second_half_end = add_days(add_months(second_half_start,6),-1) + + query_details = """ + SUM(CASE WHEN t1.%(trans)s BETWEEN '%(fhs)s' AND '%(fhe)s' THEN t2.qty ELSE NULL END), + SUM(CASE WHEN t1.%(trans)s BETWEEN '%(fhs)s' AND '%(fhe)s' THEN t1.grand_total ELSE NULL END), + SUM(CASE WHEN t1.%(trans)s BETWEEN '%(shs)s' AND '%(she)s' THEN t2.qty ELSE NULL END), + SUM(CASE WHEN t1.%(trans)s BETWEEN '%(shs)s' AND '%(she)s' THEN t1.grand_total ELSE NULL END), + """%{"trans": trans_date, "fhs": first_half_start, "fhe": first_half_end,"shs": second_half_start, + "she": second_half_end} + + else: + pwc = [filters.get("fiscal_year")+"(qty):Float:120", filters.get("fiscal_year")+"(amt):Currency:120"] + query_details = " SUM(t2.qty), SUM(t1.grand_total)," + + return pwc, query_details + +def bon_columns_qdata(based_on, bon, trans): + sup_tab = '' + + if based_on == "Item": + bon = ["Item:Link/Item:120", "Item Name:Data:120"] + query_details = "t2.item_code, t2.item_name," + basedon = 't2.item_code' + + elif based_on == "Item Group": + bon = ["Item Group:Link/Item Group:120"] + query_details = "t2.item_group," + basedon = 't2.item_group' + + elif based_on == "Customer": + bon = ["Customer:Link/Customer:120", "Territory:Link/Territory:120"] + query_details = "t1.customer_name, t1.territory, " + basedon = 't1.customer_name' + + elif based_on == "Customer Group": + bon = ["Customer Group:Link/Customer Group"] + query_details = "t1.customer_group," + basedon = 't1.customer_group' + + elif based_on == 'Supplier': + bon = ["Supplier:Link/Supplier:120", "Supplier Type:Link/Supplier Type:120"] + query_details = "t1.supplier, t3.supplier_type," + basedon = 't1.supplier' + sup_tab = ',`tabSupplier` t3' + + elif based_on == 'Supplier Type': + bon = ["Supplier Type:Link/Supplier Type:120"] + query_details = "t3.supplier_type," + basedon = 't3.supplier_type' + sup_tab = ',`tabSupplier` t3' + + elif based_on == "Territory": + bon = ["Territory:Link/Territory:120"] + query_details = "t1.territory," + basedon = 't1.territory' + + elif based_on == "Project": + + if trans in ['Sales Invoice', 'Delivery Note', 'Sales Order']: + bon = ["Project:Link/Project:120"] + query_details = "t1.project_name," + basedon = 't1.project_name' + + elif trans in ['Purchase Order', 'Purchase Invoice', 'Purchase Receipt']: + bon = ["Project:Link/Project:120"] + query_details = "t2.project_name," + basedon = 't2.project_name' + + else: + webnotes.msgprint("No Information Available", raise_exception=1) + + return bon, query_details, basedon, sup_tab + +def grp_column(group_by): + if group_by: + return [group_by+":Link/"+group_by+":120"] + else: + return [] \ No newline at end of file diff --git a/public/js/purchase_trends_filters.js b/public/js/purchase_trends_filters.js new file mode 100644 index 0000000000..05f67c92a4 --- /dev/null +++ b/public/js/purchase_trends_filters.js @@ -0,0 +1,39 @@ +var get_filter = function(){ + return [ + { + "fieldname":"period", + "label": "Period", + "fieldtype": "Select", + "options": ["Monthly", "Quarterly", "Half-yearly", "Yearly"].join("\n"), + "default": "Monthly" + }, + { + "fieldname":"based_on", + "label": "Based On", + "fieldtype": "Select", + "options": ["Item", "Item Group", "Supplier", "Supplier Type", "Project"].join("\n"), + "default": "Item" + }, + { + "fieldname":"group_by", + "label": "Group By", + "fieldtype": "Select", + "options": ["Item", "Supplier"].join("\n"), + "default": "" + }, + { + "fieldname":"fiscal_year", + "label": "Fiscal Year", + "fieldtype": "Link", + "options":'Fiscal Year', + "default": sys_defaults.fiscal_year + }, + { + "fieldname":"company", + "label": "Company", + "fieldtype": "Link", + "options": "Company", + "default": sys_defaults.company + }, + ]; +} \ No newline at end of file diff --git a/public/js/sales_trends_filters.js b/public/js/sales_trends_filters.js new file mode 100644 index 0000000000..14dcbe3cf6 --- /dev/null +++ b/public/js/sales_trends_filters.js @@ -0,0 +1,39 @@ +var get_filters = function(){ + return[ + { + "fieldname":"period", + "label": "Period", + "fieldtype": "Select", + "options": ["Monthly", "Quarterly", "Half-yearly", "Yearly"].join("\n"), + "default": "Monthly" + }, + { + "fieldname":"based_on", + "label": "Based On", + "fieldtype": "Select", + "options": ["Item", "Item Group", "Customer", "Customer Group", "Territory", "Project"].join("\n"), + "default": "Item" + }, + { + "fieldname":"group_by", + "label": "Group By", + "fieldtype": "Select", + "options": ["Item", "Customer"].join("\n"), + "default": "" + }, + { + "fieldname":"fiscal_year", + "label": "Fiscal Year", + "fieldtype": "Link", + "options":'Fiscal Year', + "default": sys_defaults.fiscal_year + }, + { + "fieldname":"company", + "label": "Company", + "fieldtype": "Link", + "options": "Company", + "default": sys_defaults.company + }, + ]; +} \ No newline at end of file diff --git a/selling/report/quotation_trends/quotation_trends.js b/selling/report/quotation_trends/quotation_trends.js index e166fa66ce..2f9f23666c 100644 --- a/selling/report/quotation_trends/quotation_trends.js +++ b/selling/report/quotation_trends/quotation_trends.js @@ -1,40 +1,5 @@ +wn.require("app/js/sales_trends_filters.js"); + wn.query_reports["Quotation Trends"] = { - "filters": [ - { - "fieldname":"period", - "label": "Period", - "fieldtype": "Select", - "options": "Monthly"+NEWLINE+"Quarterly"+NEWLINE+"Half-yearly"+NEWLINE+"Yearly", - "default": "Monthly" - }, - { - "fieldname":"based_on", - "label": "Based On", - "fieldtype": "Select", - "options": "Item"+NEWLINE+"Item Group"+NEWLINE+"Customer"+NEWLINE+"Customer Group"+NEWLINE+"Territory"+NEWLINE+"Project", - "default": "Item" - }, - { - "fieldname":"group_by", - "label": "Group By", - "fieldtype": "Select", - "options": "Item"+NEWLINE+"Customer", - "default": "" - }, - { - "fieldname":"fiscal_year", - "label": "Fiscal Year", - "fieldtype": "Link", - "options":'Fiscal Year', - "default": sys_defaults.fiscal_year - }, - { - "fieldname":"company", - "label": "Company", - "fieldtype": "Link", - "options": "Company", - "default": sys_defaults.company - }, - - ] -} \ No newline at end of file + filters: get_filters() + } \ No newline at end of file diff --git a/selling/report/quotation_trends/quotation_trends.py b/selling/report/quotation_trends/quotation_trends.py index 7f944e0f23..527e0addc5 100644 --- a/selling/report/quotation_trends/quotation_trends.py +++ b/selling/report/quotation_trends/quotation_trends.py @@ -17,204 +17,21 @@ from __future__ import unicode_literals import webnotes from webnotes.utils import cint, add_days, add_months, cstr +from controllers.trends import get_columns,get_data def execute(filters=None): if not filters: filters ={} + data = [] - # Global data trans = "Quotation" tab = ["tabQuotation","tabQuotation Item"] ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name = '%s'"%filters.get("fiscal_year"))[0][0] year_start_date = ysd.strftime('%Y-%m-%d') start_month = cint(year_start_date.split('-')[1]) - columns, query_bon, query_pwc, group_by, gby = get_columns(filters, year_start_date, start_month, trans) - data = get_data(columns,filters, tab, query_bon, query_pwc, group_by, gby) + columns, query_bon, query_pwc, basedon, grbc, sup_tab = get_columns(filters, year_start_date, start_month, trans) + data = get_data(columns,filters, tab, query_bon, query_pwc, basedon, grbc ,sup_tab) - return columns, data - -def get_columns(filters, year_start_date, start_month, trans): - columns, pwc, bon, gby = [], [], [], [] - query_bon, query_pwc = '', '' - - period = filters.get("period") - based_on = filters.get("based_on") - grby = filters.get("group_by") - - if not (period and based_on): - webnotes.msgprint("Value missing in 'Period' or 'Based On'", raise_exception=1) - - elif based_on == grby: - webnotes.msgprint("Plese select different values in 'Based On' and 'Group By'", raise_exception=1) - - else: - bon,query_bon,group_by = base_wise_column(based_on, bon) - pwc,query_pwc = period_wise_column_and_query(filters, period, pwc, year_start_date,start_month, trans) - gby = gruoup_wise_column(grby) - - if gby: - columns = bon + gby + pwc +["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] - else: - columns = bon + pwc + ["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] - - return columns, query_bon, query_pwc, group_by,gby - -def get_data(columns, filters, tab, query_bon, query_pwc, group_by,gby): - - query_details = query_bon + query_pwc + 'SUM(t2.qty), SUM(t1.grand_total) ' - query_pwc = query_pwc + 'SUM(t2.qty), SUM(t1.grand_total)' - data = [] - inc = '' - - if filters.get("group_by"): - sel_col = '' - if filters.get("group_by") == 'Item': - sel_col = 't2.item_code' - - elif filters.get("group_by") == 'Customer': - sel_col = 't1.customer' - - if filters.get('based_on') in ['Item','Customer']: - inc = 2 - else : - inc = 1 - - ind = columns.index(gby[0]) - - data1 = webnotes.conn.sql(""" select %s %s from `%s` t1, `%s` t2 - where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' - and t1.docstatus = 1 group by %s """%(query_bon, query_pwc, tab[0], tab[1], - filters.get("company"), filters.get("fiscal_year"), group_by), as_list=1) - - for d in range(len(data1)): - - dt = data1[d] - dt.insert(ind,'') - data.append(dt) - - row = webnotes.conn.sql("""select DISTINCT(%s) from `%s` t1, `%s` t2 - where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' - and t1.docstatus = 1 and %s = '%s' """%(sel_col, tab[0], tab[1], filters.get("company"), - filters.get("fiscal_year"), group_by, data1[d][0]),as_list=1) - - for i in range(len(row)): - des = ['' for q in range(len(columns))] - - row1 = webnotes.conn.sql(""" select %s , %s from `%s` t1, `%s` t2 - where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' - and t1.docstatus = 1 and %s = '%s' and %s ='%s' """%(sel_col, query_pwc, tab[0], tab[1], - filters.get("company"), filters.get("fiscal_year"), sel_col, row[i][0], group_by, - data1[d][0]),as_list=1) - - des[ind] = row[i] - for j in range(1,len(columns)-inc): - des[j+inc] = row1[0][j] - data.append(des) - else: - - data = webnotes.conn.sql(""" select %s from `%s` t1, `%s` t2 - where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' - and t1.docstatus = 1 group by %s - """%(query_details, tab[0], tab[1], filters.get("company"), filters.get("fiscal_year"), group_by), as_list=1) - - return data - -def period_wise_column_and_query(filters, period, pwc, year_start_date, start_month, trans): - query_details = '' - if trans in ['Purchase Receipt', 'Delivery Note', 'Purchase Invoice', 'Sales Invoice']: - trans_date = 'posting_date' - else: - trans_date = 'transaction_date' - - if period == "Monthly": - month_name = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] - - for month in range(start_month-1,len(month_name)): - pwc.append(month_name[month]+' (Qty):Float:120') - pwc.append(month_name[month]+' (Amt):Currency:120') - - query_details += """ - Sum(CASE WHEN MONTH(t1.%(trans)s)= %(mon_num)s THEN t2.qty ELSE NULL END), - SUM(CASE WHEN MONTH(t1.%(trans)s)= %(mon_num)s THEN t1.grand_total ELSE NULL END), - """%{"trans": trans_date,"mon_num": cstr(month+1)} - - for month in range(0, start_month-1): - pwc.append(month_name[month]+' (Qty):Float:120') - pwc.append(month_name[month]+' (Amt):Currency:120') - - query_details += """ - Sum(CASE WHEN MONTH(t1.%(trans)s)= %(mon_num)s THEN t2.qty ELSE NULL END), - SUM(CASE WHEN MONTH(t1.%(trans)s)= %(mon_num)s THEN t1.grand_total ELSE NULL END), - """%{"trans": trans_date, "mon_num": cstr(month+1)} - - elif period == "Quarterly": - pwc = ["Q1(qty):Float:120", "Q1(amt):Currency:120", "Q2(qty):Float:120", "Q2(amt):Currency:120", - "Q3(qty):Float:120", "Q3(amt):Currency:120", "Q4(qty):Float:120", "Q4(amt):Currency:120"] - - first_qsd, second_qsd, third_qsd, fourth_qsd = year_start_date, add_months(year_start_date,3), add_months(year_start_date,6), add_months(year_start_date,9) - first_qed, second_qed, third_qed, fourth_qed = add_days(add_months(first_qsd,3),-1), add_days(add_months(second_qsd,3),-1), add_days(add_months(third_qsd,3),-1), add_days(add_months(fourth_qsd,3),-1) - - bet_dates = [[first_qsd,first_qed],[second_qsd,second_qed],[third_qsd,third_qed],[fourth_qsd,fourth_qed]] - for d in bet_dates: - query_details += """ - SUM(CASE WHEN t1.%(trans)s BETWEEN '%(sd)s' AND '%(ed)s' THEN t2.qty ELSE NULL END), - SUM(CASE WHEN t1.%(trans)s BETWEEN '%(sd)s' AND '%(ed)s' THEN t1.grand_total ELSE NULL END), - """%{"trans": trans_date, "sd": d[0],"ed": d[1]} - - elif period == "Half-yearly": - pwc = ["Fisrt Half(qty):Float:120", "Fisrt Half(amt):Currency:120", "Second Half(qty):Float:120", - "Second Half(amt):Currency:120"] - - first_half_start = year_start_date - first_half_end = add_days(add_months(first_half_start,6),-1) - second_half_start = add_days(first_half_end,1) - second_half_end = add_days(add_months(second_half_start,6),-1) - - query_details = """ - SUM(CASE WHEN t1.%(trans)s BETWEEN '%(fhs)s' AND '%(fhe)s' THEN t2.qty ELSE NULL END), - SUM(CASE WHEN t1.%(trans)s BETWEEN '%(fhs)s' AND '%(fhe)s' THEN t1.grand_total ELSE NULL END), - SUM(CASE WHEN t1.%(trans)s BETWEEN '%(shs)s' AND '%(she)s' THEN t2.qty ELSE NULL END), - SUM(CASE WHEN t1.%(trans)s BETWEEN '%(shs)s' AND '%(she)s' THEN t1.grand_total ELSE NULL END), - """%{"trans": trans_date, "fhs": first_half_start, "fhe": first_half_end,"shs": second_half_start, "she": second_half_end} - - else: - pwc = [filters.get("fiscal_year")+"(qty):Float:120", filters.get("fiscal_year")+"(amt):Currency:120"] - query_details = " SUM(t2.qty), SUM(t1.grand_total)," - - return pwc, query_details - -def base_wise_column(based_on, bon): - if based_on == "Item": - bon = ["Item:Link/Item:120", "Item Name:Data:120"] - query_details = "t2.item_code, t2.item_name," - group_by = 't2.item_code' - - elif based_on == "Item Group": - bon = ["Item Group:Link/Item Group:120"] - query_details = "t2.item_group," - group_by = 't2.item_group' - - elif based_on == "Customer": - bon = ["Customer:Link/Customer:120", "Territory:Link/Territory:120"] - query_details = "t1.customer_name, t1.territory, " - group_by = 't1.customer_name' - - elif based_on == "Customer Group": - bon = ["Customer Group:Link/Customer Group"] - query_details = "t1.customer_group, " - group_by = 't1.customer_group' - - elif based_on == "Territory": - bon = ["Territory:Link/Territory:120"] - query_details = "t1.territory, " - group_by = 't1.territory' - - else: - bon = ["Project:Link/Project:120"] - return bon, query_details, group_by - -def gruoup_wise_column(group_by): - if group_by: - return [group_by+":Link/"+group_by+":120"] - else: - return [] \ No newline at end of file + if data == '': + webnotes.msgprint("Data Not Available") + return columns, data \ No newline at end of file diff --git a/selling/report/sales_order_trends/__init__.py b/selling/report/sales_order_trends/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/selling/report/sales_order_trends/sales_order_trends.js b/selling/report/sales_order_trends/sales_order_trends.js new file mode 100644 index 0000000000..29c124403f --- /dev/null +++ b/selling/report/sales_order_trends/sales_order_trends.js @@ -0,0 +1,5 @@ +wn.require("app/js/sales_trends_filters.js"); + +wn.query_reports["Sales Order"] = { + filters: get_filters() + } \ No newline at end of file diff --git a/selling/report/sales_order_trends/sales_order_trends.py b/selling/report/sales_order_trends/sales_order_trends.py new file mode 100644 index 0000000000..047a8a9e9f --- /dev/null +++ b/selling/report/sales_order_trends/sales_order_trends.py @@ -0,0 +1,37 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import unicode_literals +import webnotes +from webnotes.utils import cint, add_days, add_months, cstr +from controllers.trends import get_columns,get_data + +def execute(filters=None): + if not filters: filters ={} + data = [] + + trans = "Sales Order" + tab = ["tabSales Order","tabSales Order Item"] + ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name = '%s'"%filters.get("fiscal_year"))[0][0] + year_start_date = ysd.strftime('%Y-%m-%d') + start_month = cint(year_start_date.split('-')[1]) + + columns, query_bon, query_pwc, basedon, grbc, sup_tab = get_columns(filters, year_start_date, start_month, trans) + data = get_data(columns,filters, tab, query_bon, query_pwc, basedon, grbc ,sup_tab) + + if data == '': + webnotes.msgprint("Data Not Available") + return columns, data \ No newline at end of file diff --git a/selling/report/sales_order_trends/sales_order_trends.txt b/selling/report/sales_order_trends/sales_order_trends.txt new file mode 100644 index 0000000000..16ee9ca46b --- /dev/null +++ b/selling/report/sales_order_trends/sales_order_trends.txt @@ -0,0 +1,21 @@ +[ + { + "creation": "2013-06-13 18:43:30", + "docstatus": 0, + "modified": "2013-06-13 18:43:30", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Sales Order", + "report_name": "Sales Order Trends", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "Sales Order Trends" + } +] \ No newline at end of file diff --git a/stock/report/delivery_note_trends/__init__.py b/stock/report/delivery_note_trends/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/stock/report/delivery_note_trends/delivery_note_trends.js b/stock/report/delivery_note_trends/delivery_note_trends.js new file mode 100644 index 0000000000..3ec5e594d7 --- /dev/null +++ b/stock/report/delivery_note_trends/delivery_note_trends.js @@ -0,0 +1,5 @@ +wn.require("app/js/sales_trends_filters.js"); + +wn.query_reports["Delivery Note Trends"] = { + filters: get_filters() + } \ No newline at end of file diff --git a/stock/report/delivery_note_trends/delivery_note_trends.py b/stock/report/delivery_note_trends/delivery_note_trends.py new file mode 100644 index 0000000000..685cede509 --- /dev/null +++ b/stock/report/delivery_note_trends/delivery_note_trends.py @@ -0,0 +1,37 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import unicode_literals +import webnotes +from webnotes.utils import cint, add_days, add_months, cstr +from controllers.trends import get_columns,get_data + +def execute(filters=None): + if not filters: filters ={} + data = [] + + trans = "Delivery Note" + tab = ["tabDelivery Note","tabDelivery Note Item"] + ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name = '%s'"%filters.get("fiscal_year"))[0][0] + year_start_date = ysd.strftime('%Y-%m-%d') + start_month = cint(year_start_date.split('-')[1]) + + columns, query_bon, query_pwc, basedon, grbc, sup_tab = get_columns(filters, year_start_date, start_month, trans) + data = get_data(columns,filters, tab, query_bon, query_pwc, basedon, grbc ,sup_tab) + + if data == '': + webnotes.msgprint("Data Not Available") + return columns, data \ No newline at end of file diff --git a/stock/report/delivery_note_trends/delivery_note_trends.txt b/stock/report/delivery_note_trends/delivery_note_trends.txt new file mode 100644 index 0000000000..bb8720074a --- /dev/null +++ b/stock/report/delivery_note_trends/delivery_note_trends.txt @@ -0,0 +1,21 @@ +[ + { + "creation": "2013-06-13 18:42:11", + "docstatus": 0, + "modified": "2013-06-13 18:42:11", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Delivery Note", + "report_name": "Delivery Note Trends", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "Delivery Note Trends" + } +] \ No newline at end of file diff --git a/stock/report/purchase_receipt_trends/__init__.py b/stock/report/purchase_receipt_trends/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/stock/report/purchase_receipt_trends/purchase_receipt_trends.js b/stock/report/purchase_receipt_trends/purchase_receipt_trends.js new file mode 100644 index 0000000000..ecfa5a473e --- /dev/null +++ b/stock/report/purchase_receipt_trends/purchase_receipt_trends.js @@ -0,0 +1,5 @@ +wn.require("app/js/purchase_trends_filters.js"); + +wn.query_reports["Purchase Receipt Trends"] = { + filters: get_filters() + } \ No newline at end of file diff --git a/stock/report/purchase_receipt_trends/purchase_receipt_trends.py b/stock/report/purchase_receipt_trends/purchase_receipt_trends.py new file mode 100644 index 0000000000..aaa18a0a0d --- /dev/null +++ b/stock/report/purchase_receipt_trends/purchase_receipt_trends.py @@ -0,0 +1,37 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import unicode_literals +import webnotes +from webnotes.utils import cint, add_days, add_months, cstr +from controllers.trends import get_columns,get_data + +def execute(filters=None): + if not filters: filters ={} + data = [] + + trans = "Purchase Receipt" + tab = ["tabPurchase Receipt","tabPurchase Receipt Item"] + ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name = '%s'"%filters.get("fiscal_year"))[0][0] + year_start_date = ysd.strftime('%Y-%m-%d') + start_month = cint(year_start_date.split('-')[1]) + + columns, query_bon, query_pwc, basedon, grbc, sup_tab = get_columns(filters, year_start_date, start_month, trans) + data = get_data(columns,filters, tab, query_bon, query_pwc, basedon, grbc ,sup_tab) + + if data == '': + webnotes.msgprint("Data Not Available") + return columns, data \ No newline at end of file diff --git a/stock/report/purchase_receipt_trends/purchase_receipt_trends.txt b/stock/report/purchase_receipt_trends/purchase_receipt_trends.txt new file mode 100644 index 0000000000..179c524f96 --- /dev/null +++ b/stock/report/purchase_receipt_trends/purchase_receipt_trends.txt @@ -0,0 +1,21 @@ +[ + { + "creation": "2013-06-13 18:45:44", + "docstatus": 0, + "modified": "2013-06-13 18:45:44", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Purchase Receipt", + "report_name": "Purchase Receipt Trends", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "Purchase Receipt Trends" + } +] \ No newline at end of file From 1848b71a0a3354134c2b76233176aec0a057d789 Mon Sep 17 00:00:00 2001 From: Saurabh Date: Fri, 14 Jun 2013 15:03:45 +0530 Subject: [PATCH 07/21] [Reports][Sales and Purchase Trends][Completed] --- accounts/page/accounts_home/accounts_home.js | 10 ++ .../purchase_invoice_trends.py | 13 +- .../sales_invoice_trends.py | 13 +- buying/page/buying_home/buying_home.js | 5 + .../purchase_order_trends.py | 13 +- controllers/trends.py | 138 ++++++++++-------- public/js/purchase_trends_filters.js | 2 +- selling/page/selling_home/selling_home.js | 5 + .../quotation_trends/quotation_trends.py | 13 +- .../sales_order_trends/sales_order_trends.js | 2 +- .../sales_order_trends/sales_order_trends.py | 15 +- stock/page/stock_home/stock_home.js | 10 ++ .../delivery_note_trends.py | 15 +- .../purchase_receipt_trends.py | 13 +- 14 files changed, 146 insertions(+), 121 deletions(-) diff --git a/accounts/page/accounts_home/accounts_home.js b/accounts/page/accounts_home/accounts_home.js index 7f623d7115..63fe9695cc 100644 --- a/accounts/page/accounts_home/accounts_home.js +++ b/accounts/page/accounts_home/accounts_home.js @@ -257,6 +257,16 @@ wn.module_page["Accounts"] = [ route: "query-report/Item-wise Purchase Register", doctype: "Purchase Invoice" }, + { + "label":wn._("Purchase Invoice Trends"), + route: "query-report/Purchase Invoice Trends", + doctype: "Purchase Invoice" + }, + { + "label":wn._("Sales Invoice Trends"), + route: "query-report/Sales Invoice Trends", + doctype: "Sales Invoice" + }, ] } ] diff --git a/accounts/report/purchase_invoice_trends/purchase_invoice_trends.py b/accounts/report/purchase_invoice_trends/purchase_invoice_trends.py index e74ad2129b..a38c37cdb5 100644 --- a/accounts/report/purchase_invoice_trends/purchase_invoice_trends.py +++ b/accounts/report/purchase_invoice_trends/purchase_invoice_trends.py @@ -16,7 +16,6 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import cint, add_days, add_months, cstr from controllers.trends import get_columns,get_data def execute(filters=None): @@ -25,13 +24,11 @@ def execute(filters=None): trans = "Purchase Invoice" tab = ["tabPurchase Invoice","tabPurchase Invoice Item"] - ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name = '%s'"%filters.get("fiscal_year"))[0][0] - year_start_date = ysd.strftime('%Y-%m-%d') - start_month = cint(year_start_date.split('-')[1]) - - columns, query_bon, query_pwc, basedon, grbc, sup_tab = get_columns(filters, year_start_date, start_month, trans) - data = get_data(columns,filters, tab, query_bon, query_pwc, basedon, grbc ,sup_tab) + details = get_columns(filters, trans) + data = get_data(filters, tab, details) + if data == '': webnotes.msgprint("Data Not Available") - return columns, data \ No newline at end of file + + return details["columns"], data \ No newline at end of file diff --git a/accounts/report/sales_invoice_trends/sales_invoice_trends.py b/accounts/report/sales_invoice_trends/sales_invoice_trends.py index 48606f04ed..3839900b46 100644 --- a/accounts/report/sales_invoice_trends/sales_invoice_trends.py +++ b/accounts/report/sales_invoice_trends/sales_invoice_trends.py @@ -16,7 +16,6 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import cint, add_days, add_months, cstr from controllers.trends import get_columns,get_data def execute(filters=None): @@ -25,13 +24,11 @@ def execute(filters=None): trans = "Sales Invoice" tab = ["tabSales Invoice","tabSales Invoice Item"] - ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name = '%s'"%filters.get("fiscal_year"))[0][0] - year_start_date = ysd.strftime('%Y-%m-%d') - start_month = cint(year_start_date.split('-')[1]) - - columns, query_bon, query_pwc, basedon, grbc, sup_tab = get_columns(filters, year_start_date, start_month, trans) - data = get_data(columns,filters, tab, query_bon, query_pwc, basedon, grbc ,sup_tab) + details = get_columns(filters, trans) + data = get_data(filters, tab, details) + if data == '': webnotes.msgprint("Data Not Available") - return columns, data \ No newline at end of file + + return details["columns"], data \ No newline at end of file diff --git a/buying/page/buying_home/buying_home.js b/buying/page/buying_home/buying_home.js index 2070fd4e33..dfcd71e17d 100644 --- a/buying/page/buying_home/buying_home.js +++ b/buying/page/buying_home/buying_home.js @@ -115,6 +115,11 @@ wn.module_page["Buying"] = [ "label":wn._("Requested Items To Be Ordered"), route: "query-report/Requested Items To Be Ordered", }, + { + "label":wn._("Purchase Order Trends"), + route: "query-report/Purchase Order Trends", + doctype: "Purchase Order" + }, ] } ] diff --git a/buying/report/purchase_order_trends/purchase_order_trends.py b/buying/report/purchase_order_trends/purchase_order_trends.py index cdf79b2fad..063bef43f2 100644 --- a/buying/report/purchase_order_trends/purchase_order_trends.py +++ b/buying/report/purchase_order_trends/purchase_order_trends.py @@ -16,7 +16,6 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import cint, add_days, add_months, cstr from controllers.trends import get_columns,get_data def execute(filters=None): @@ -25,13 +24,11 @@ def execute(filters=None): trans = "Purchase Order" tab = ["tabPurchase Order","tabPurchase Order Item"] - ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name = '%s'"%filters.get("fiscal_year"))[0][0] - year_start_date = ysd.strftime('%Y-%m-%d') - start_month = cint(year_start_date.split('-')[1]) - - columns, query_bon, query_pwc, basedon, grbc, sup_tab = get_columns(filters, year_start_date, start_month, trans) - data = get_data(columns,filters, tab, query_bon, query_pwc, basedon, grbc ,sup_tab) + details = get_columns(filters, trans) + data = get_data(filters, tab, details) + if data == '': webnotes.msgprint("Data Not Available") - return columns, data \ No newline at end of file + + return details["columns"], data \ No newline at end of file diff --git a/controllers/trends.py b/controllers/trends.py index 6c33235b9f..dee9ec8b4f 100644 --- a/controllers/trends.py +++ b/controllers/trends.py @@ -18,51 +18,45 @@ from __future__ import unicode_literals import webnotes from webnotes.utils import cint, add_days, add_months, cstr -def get_columns(filters, year_start_date, start_month, trans): - columns, pwc, bon, grbc = [], [], [], [] - query_bon, query_pwc = '', '' +def get_columns(filters, trans): - period = filters.get("period") - based_on = filters.get("based_on") - grby = filters.get("group_by") - - if not (period and based_on): + if not (filters.get("period") and filters.get("based_on")): webnotes.msgprint("Value missing in 'Period' or 'Based On'", raise_exception=1) - elif based_on == grby: + elif filters.get("based_on") == filters.get("group_by"): webnotes.msgprint("Plese select different values in 'Based On' and 'Group By'", raise_exception=1) else: - bon, query_bon, basedon, sup_tab = bon_columns_qdata(based_on, bon, trans) - pwc, query_pwc = pw_column_qdata(filters, period, pwc, year_start_date,start_month, trans) - grbc = grp_column(grby) - - if grbc: - columns = bon + grbc + pwc +["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] - else: + bon, query_bon, basedon, sup_tab = basedon_wise_colums_query(filters.get("based_on"), trans) + pwc, query_pwc = period_wise_colums_query(filters, trans) + grbc = group_wise_column(filters.get("group_by")) + columns = bon + pwc + ["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] + if grbc: + columns = bon + grbc + pwc +["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] - return columns, query_bon, query_pwc, basedon, grbc, sup_tab + details = {"query_bon": query_bon, "query_pwc": query_pwc, "columns": columns, "basedon": basedon, + "grbc": grbc, "sup_tab": sup_tab} -def get_data(columns, filters, tab, query_bon, query_pwc, basedon, grbc, sup_tab): + return details + +def get_data(filters, tab, details): - query_details = query_bon + query_pwc + 'SUM(t2.qty), SUM(t1.grand_total) ' - query_pwc = query_pwc + 'SUM(t2.qty), SUM(t1.grand_total)' data = [] inc, cond= '','' + query_details = details["query_bon"] + details["query_pwc"] - if query_bon in ["t1.project_name,", "t2.project_name,"]: - cond = 'and '+ query_bon[:-1] +' IS Not NULL' + if details["query_bon"] in ["t1.project_name,", "t2.project_name,"]: + cond = 'and '+ details["query_bon"][:-1] +' IS Not NULL' if filters.get("group_by"): sel_col = '' + ind = details["columns"].index(details["grbc"][0]) if filters.get("group_by") == 'Item': sel_col = 't2.item_code' - elif filters.get("group_by") == 'Customer': sel_col = 't1.customer' - elif filters.get("group_by") == 'Supplier': sel_col = 't1.supplier' @@ -71,13 +65,14 @@ def get_data(columns, filters, tab, query_bon, query_pwc, basedon, grbc, sup_ta else : inc = 1 - ind = columns.index(grbc[0]) - - data1 = webnotes.conn.sql(""" select %s %s from `%s` t1, `%s` t2 %s - where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' - and t1.docstatus = 1 %s group by %s - """%(query_bon, query_pwc, tab[0], tab[1], sup_tab,filters.get("company"), filters.get("fiscal_year"), - cond, basedon), as_list=1) + data1 = webnotes.conn.sql(""" select %s from `%s` t1, `%s` t2 %s + where t2.parent = t1.name and t1.company = %s + and t1.fiscal_year = %s and t1.docstatus = 1 %s + group by %s + """ % (query_details, tab[0], tab[1], details["sup_tab"], "%s", + "%s", cond, details["basedon"]), (filters.get("company"), + filters["fiscal_year"]), + as_list=1) for d in range(len(data1)): #to add blanck column @@ -86,44 +81,64 @@ def get_data(columns, filters, tab, query_bon, query_pwc, basedon, grbc, sup_ta data.append(dt) #to get distinct value of col specified by group_by in filter - row = webnotes.conn.sql("""select DISTINCT(%s) from `%s` t1, `%s` t2 - where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' - and t1.docstatus = 1 and %s = '%s' - """%(sel_col, tab[0], tab[1], filters.get("company"), filters.get("fiscal_year"), - basedon, data1[d][0]),as_list=1) - + row = webnotes.conn.sql("""select DISTINCT(%s) from `%s` t1, `%s` t2 %s + where t2.parent = t1.name and t1.company = %s + and t1.fiscal_year = %s and t1.docstatus = 1 + and %s = %s + """%(sel_col, tab[0], tab[1], details["sup_tab"], "%s", + "%s", details["basedon"], "%s"), + (filters.get("company"), filters.get("fiscal_year"), + data1[d][0]), + as_list=1) + for i in range(len(row)): - des = ['' for q in range(len(columns))] + des = ['' for q in range(len(details["columns"]))] #get data for each group_by filter - row1 = webnotes.conn.sql(""" select %s , %s from `%s` t1, `%s` t2 - where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' - and t1.docstatus = 1 and %s = '%s' and %s ='%s' - """%(sel_col, query_pwc, tab[0], tab[1], filters.get("company"), filters.get("fiscal_year"), - sel_col, row[i][0], basedon, data1[d][0]),as_list=1) + row1 = webnotes.conn.sql(""" select %s , %s from `%s` t1, `%s` t2 %s + where t2.parent = t1.name and t1.company = %s + and t1.fiscal_year = %s and t1.docstatus = 1 + and %s = %s and %s = %s + """%(sel_col, details["query_pwc"], tab[0], tab[1], details["sup_tab"], + "%s", "%s", sel_col, "%s", details["basedon"], "%s"), + (filters.get("company"), filters.get("fiscal_year"), row[i][0], + data1[d][0]), + as_list=1) des[ind] = row[i] - for j in range(1,len(columns)-inc): + for j in range(1,len(details["columns"])-inc): des[j+inc] = row1[0][j] data.append(des) else: data = webnotes.conn.sql(""" select %s from `%s` t1, `%s` t2 %s - where t2.parent = t1.name and t1.company = '%s' and t1.fiscal_year = '%s' - and t1.docstatus = 1 %s group by %s - """%(query_details, tab[0], tab[1], sup_tab, filters.get("company"), - filters.get("fiscal_year"), cond,basedon), as_list=1) + where t2.parent = t1.name and t1.company = %s + and t1.fiscal_year = %s and t1.docstatus = 1 + %s group by %s + """%(query_details, tab[0], tab[1], details["sup_tab"], "%s", + "%s", cond,details["basedon"]), (filters.get("company"), + filters.get("fiscal_year")), + as_list=1) return data -def pw_column_qdata(filters, period, pwc, year_start_date, start_month, trans): +def period_wise_colums_query(filters, trans): + query_details = '' + pwc = [] + ysd = webnotes.conn.sql("""select year_start_date from `tabFiscal Year` + where name = '%s' + """%filters.get("fiscal_year"))[0][0] + + year_start_date = ysd.strftime('%Y-%m-%d') + start_month = cint(year_start_date.split('-')[1]) + if trans in ['Purchase Receipt', 'Delivery Note', 'Purchase Invoice', 'Sales Invoice']: trans_date = 'posting_date' else: trans_date = 'transaction_date' - if period == "Monthly": + if filters.get("period") == "Monthly": month_name = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] for month in range(start_month-1,len(month_name)): @@ -144,23 +159,23 @@ def pw_column_qdata(filters, period, pwc, year_start_date, start_month, trans): SUM(CASE WHEN MONTH(t1.%(trans)s)= %(mon_num)s THEN t1.grand_total ELSE NULL END), """%{"trans": trans_date, "mon_num": cstr(month+1)} - elif period == "Quarterly": - pwc = ["Q1(qty):Float:120", "Q1(amt):Currency:120", "Q2(qty):Float:120", "Q2(amt):Currency:120", - "Q3(qty):Float:120", "Q3(amt):Currency:120", "Q4(qty):Float:120", "Q4(amt):Currency:120"] + elif filters.get("period") == "Quarterly": + pwc = ["Q1 (Qty):Float:120", "Q1 (Amt):Currency:120", "Q2 (Qty):Float:120", "Q2 (Amt):Currency:120", + "Q3 (Qty):Float:120", "Q3 (Amt):Currency:120", "Q4 (Qty):Float:120", "Q4 (Amt):Currency:120"] first_qsd, second_qsd, third_qsd, fourth_qsd = year_start_date, add_months(year_start_date,3), add_months(year_start_date,6), add_months(year_start_date,9) first_qed, second_qed, third_qed, fourth_qed = add_days(add_months(first_qsd,3),-1), add_days(add_months(second_qsd,3),-1), add_days(add_months(third_qsd,3),-1), add_days(add_months(fourth_qsd,3),-1) - bet_dates = [[first_qsd,first_qed],[second_qsd,second_qed],[third_qsd,third_qed],[fourth_qsd,fourth_qed]] + for d in bet_dates: query_details += """ SUM(CASE WHEN t1.%(trans)s BETWEEN '%(sd)s' AND '%(ed)s' THEN t2.qty ELSE NULL END), SUM(CASE WHEN t1.%(trans)s BETWEEN '%(sd)s' AND '%(ed)s' THEN t1.grand_total ELSE NULL END), """%{"trans": trans_date, "sd": d[0],"ed": d[1]} - elif period == "Half-yearly": - pwc = ["Fisrt Half(qty):Float:120", "Fisrt Half(amt):Currency:120", "Second Half(qty):Float:120", - "Second Half(amt):Currency:120"] + elif filters.get("period") == "Half-yearly": + pwc = ["Fisrt Half (Qty):Float:120", "Fisrt Half (Amt):Currency:120", "Second Half (Qty):Float:120", + "Second Half (Amt):Currency:120"] first_half_start = year_start_date first_half_end = add_days(add_months(first_half_start,6),-1) @@ -176,12 +191,13 @@ def pw_column_qdata(filters, period, pwc, year_start_date, start_month, trans): "she": second_half_end} else: - pwc = [filters.get("fiscal_year")+"(qty):Float:120", filters.get("fiscal_year")+"(amt):Currency:120"] + pwc = [filters.get("fiscal_year")+" (Qty):Float:120", filters.get("fiscal_year")+" (Amt):Currency:120"] query_details = " SUM(t2.qty), SUM(t1.grand_total)," + query_details += 'SUM(t2.qty), SUM(t1.grand_total)' return pwc, query_details -def bon_columns_qdata(based_on, bon, trans): +def basedon_wise_colums_query(based_on, trans): sup_tab = '' if based_on == "Item": @@ -234,11 +250,11 @@ def bon_columns_qdata(based_on, bon, trans): basedon = 't2.project_name' else: - webnotes.msgprint("No Information Available", raise_exception=1) + webnotes.msgprint("Information Not Available", raise_exception=1) return bon, query_details, basedon, sup_tab -def grp_column(group_by): +def group_wise_column(group_by): if group_by: return [group_by+":Link/"+group_by+":120"] else: diff --git a/public/js/purchase_trends_filters.js b/public/js/purchase_trends_filters.js index 05f67c92a4..e994a47ebd 100644 --- a/public/js/purchase_trends_filters.js +++ b/public/js/purchase_trends_filters.js @@ -1,4 +1,4 @@ -var get_filter = function(){ +var get_filters = function(){ return [ { "fieldname":"period", diff --git a/selling/page/selling_home/selling_home.js b/selling/page/selling_home/selling_home.js index 15f9b86162..ff8cff8892 100644 --- a/selling/page/selling_home/selling_home.js +++ b/selling/page/selling_home/selling_home.js @@ -173,6 +173,11 @@ wn.module_page["Selling"] = [ { "label":wn._("Quotation Trend"), route: "query-report/Quotation Trends", + doctype: "Quotation" + }, + { + "label":wn._("Sales Order Trend"), + route: "query-report/Sales Order Trends", doctype: "Sales Order" }, diff --git a/selling/report/quotation_trends/quotation_trends.py b/selling/report/quotation_trends/quotation_trends.py index 527e0addc5..548a4a8253 100644 --- a/selling/report/quotation_trends/quotation_trends.py +++ b/selling/report/quotation_trends/quotation_trends.py @@ -16,7 +16,6 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import cint, add_days, add_months, cstr from controllers.trends import get_columns,get_data def execute(filters=None): @@ -25,13 +24,11 @@ def execute(filters=None): trans = "Quotation" tab = ["tabQuotation","tabQuotation Item"] - ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name = '%s'"%filters.get("fiscal_year"))[0][0] - year_start_date = ysd.strftime('%Y-%m-%d') - start_month = cint(year_start_date.split('-')[1]) - - columns, query_bon, query_pwc, basedon, grbc, sup_tab = get_columns(filters, year_start_date, start_month, trans) - data = get_data(columns,filters, tab, query_bon, query_pwc, basedon, grbc ,sup_tab) + details = get_columns(filters, trans) + data = get_data(filters, tab, details) + if data == '': webnotes.msgprint("Data Not Available") - return columns, data \ No newline at end of file + + return details["columns"], data \ No newline at end of file diff --git a/selling/report/sales_order_trends/sales_order_trends.js b/selling/report/sales_order_trends/sales_order_trends.js index 29c124403f..458fee6ed3 100644 --- a/selling/report/sales_order_trends/sales_order_trends.js +++ b/selling/report/sales_order_trends/sales_order_trends.js @@ -1,5 +1,5 @@ wn.require("app/js/sales_trends_filters.js"); -wn.query_reports["Sales Order"] = { +wn.query_reports["Sales Order Trends"] = { filters: get_filters() } \ No newline at end of file diff --git a/selling/report/sales_order_trends/sales_order_trends.py b/selling/report/sales_order_trends/sales_order_trends.py index 047a8a9e9f..e3d9d9f523 100644 --- a/selling/report/sales_order_trends/sales_order_trends.py +++ b/selling/report/sales_order_trends/sales_order_trends.py @@ -16,7 +16,6 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import cint, add_days, add_months, cstr from controllers.trends import get_columns,get_data def execute(filters=None): @@ -25,13 +24,11 @@ def execute(filters=None): trans = "Sales Order" tab = ["tabSales Order","tabSales Order Item"] - ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name = '%s'"%filters.get("fiscal_year"))[0][0] - year_start_date = ysd.strftime('%Y-%m-%d') - start_month = cint(year_start_date.split('-')[1]) - - columns, query_bon, query_pwc, basedon, grbc, sup_tab = get_columns(filters, year_start_date, start_month, trans) - data = get_data(columns,filters, tab, query_bon, query_pwc, basedon, grbc ,sup_tab) - + + details = get_columns(filters, trans) + data = get_data(filters, tab, details) + if data == '': webnotes.msgprint("Data Not Available") - return columns, data \ No newline at end of file + + return details["columns"], data \ No newline at end of file diff --git a/stock/page/stock_home/stock_home.js b/stock/page/stock_home/stock_home.js index d8c63aab66..532eb66406 100644 --- a/stock/page/stock_home/stock_home.js +++ b/stock/page/stock_home/stock_home.js @@ -223,6 +223,16 @@ wn.module_page["Stock"] = [ route: "query-report/Itemwise Recommended Reorder Level", doctype: "Item" }, + { + "label":wn._("Delivery Note Trends"), + route: "query-report/Delivery Note Trends", + doctype: "Delivery Note" + }, + { + "label":wn._("Purchase Receipt Trends"), + route: "query-report/Purchase Receipt Trends", + doctype: "Purchase Receipt" + }, ] } ] diff --git a/stock/report/delivery_note_trends/delivery_note_trends.py b/stock/report/delivery_note_trends/delivery_note_trends.py index 685cede509..a161c65eee 100644 --- a/stock/report/delivery_note_trends/delivery_note_trends.py +++ b/stock/report/delivery_note_trends/delivery_note_trends.py @@ -16,7 +16,6 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import cint, add_days, add_months, cstr from controllers.trends import get_columns,get_data def execute(filters=None): @@ -25,13 +24,11 @@ def execute(filters=None): trans = "Delivery Note" tab = ["tabDelivery Note","tabDelivery Note Item"] - ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name = '%s'"%filters.get("fiscal_year"))[0][0] - year_start_date = ysd.strftime('%Y-%m-%d') - start_month = cint(year_start_date.split('-')[1]) - - columns, query_bon, query_pwc, basedon, grbc, sup_tab = get_columns(filters, year_start_date, start_month, trans) - data = get_data(columns,filters, tab, query_bon, query_pwc, basedon, grbc ,sup_tab) - + + details = get_columns(filters, trans) + data = get_data(filters, tab, details) + if data == '': webnotes.msgprint("Data Not Available") - return columns, data \ No newline at end of file + + return details["columns"], data \ No newline at end of file diff --git a/stock/report/purchase_receipt_trends/purchase_receipt_trends.py b/stock/report/purchase_receipt_trends/purchase_receipt_trends.py index aaa18a0a0d..abce01eedd 100644 --- a/stock/report/purchase_receipt_trends/purchase_receipt_trends.py +++ b/stock/report/purchase_receipt_trends/purchase_receipt_trends.py @@ -16,7 +16,6 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import cint, add_days, add_months, cstr from controllers.trends import get_columns,get_data def execute(filters=None): @@ -25,13 +24,11 @@ def execute(filters=None): trans = "Purchase Receipt" tab = ["tabPurchase Receipt","tabPurchase Receipt Item"] - ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name = '%s'"%filters.get("fiscal_year"))[0][0] - year_start_date = ysd.strftime('%Y-%m-%d') - start_month = cint(year_start_date.split('-')[1]) - - columns, query_bon, query_pwc, basedon, grbc, sup_tab = get_columns(filters, year_start_date, start_month, trans) - data = get_data(columns,filters, tab, query_bon, query_pwc, basedon, grbc ,sup_tab) + details = get_columns(filters, trans) + data = get_data(filters, tab, details) + if data == '': webnotes.msgprint("Data Not Available") - return columns, data \ No newline at end of file + + return details["columns"], data \ No newline at end of file From feb8669cbde3cb784b8ad5169834921dd83f4138 Mon Sep 17 00:00:00 2001 From: Saurabh Date: Fri, 14 Jun 2013 17:40:48 +0530 Subject: [PATCH 08/21] [Reports][Validation changes in Purchase and Sales trends] --- .../purchase_invoice_trends/purchase_invoice_trends.py | 6 +++--- accounts/report/purchase_register/purchase_register.py | 1 + .../report/sales_invoice_trends/sales_invoice_trends.py | 4 ++-- .../report/purchase_order_trends/purchase_order_trends.py | 4 ++-- selling/report/quotation_trends/quotation_trends.py | 4 ++-- selling/report/sales_order_trends/sales_order_trends.py | 4 ++-- stock/report/delivery_note_trends/delivery_note_trends.py | 4 ++-- .../purchase_receipt_trends/purchase_receipt_trends.py | 4 ++-- 8 files changed, 16 insertions(+), 15 deletions(-) diff --git a/accounts/report/purchase_invoice_trends/purchase_invoice_trends.py b/accounts/report/purchase_invoice_trends/purchase_invoice_trends.py index a38c37cdb5..b2f376b471 100644 --- a/accounts/report/purchase_invoice_trends/purchase_invoice_trends.py +++ b/accounts/report/purchase_invoice_trends/purchase_invoice_trends.py @@ -27,8 +27,8 @@ def execute(filters=None): details = get_columns(filters, trans) data = get_data(filters, tab, details) - - if data == '': - webnotes.msgprint("Data Not Available") + + if not data : + webnotes.msgprint("Data not found for selected criterias") return details["columns"], data \ No newline at end of file diff --git a/accounts/report/purchase_register/purchase_register.py b/accounts/report/purchase_register/purchase_register.py index 7c4b38671d..548b561344 100644 --- a/accounts/report/purchase_register/purchase_register.py +++ b/accounts/report/purchase_register/purchase_register.py @@ -107,6 +107,7 @@ def get_invoices(filters): from `tabPurchase Invoice` where docstatus = 1 %s order by posting_date desc, name desc""" % conditions, filters, as_dict=1) + def get_invoice_expense_map(invoice_list): expense_details = webnotes.conn.sql("""select parent, expense_head, sum(amount) as amount from `tabPurchase Invoice Item` where parent in (%s) group by parent, expense_head""" % diff --git a/accounts/report/sales_invoice_trends/sales_invoice_trends.py b/accounts/report/sales_invoice_trends/sales_invoice_trends.py index 3839900b46..11d6665ff3 100644 --- a/accounts/report/sales_invoice_trends/sales_invoice_trends.py +++ b/accounts/report/sales_invoice_trends/sales_invoice_trends.py @@ -28,7 +28,7 @@ def execute(filters=None): details = get_columns(filters, trans) data = get_data(filters, tab, details) - if data == '': - webnotes.msgprint("Data Not Available") + if not data : + webnotes.msgprint("Data not found for selected criterias") return details["columns"], data \ No newline at end of file diff --git a/buying/report/purchase_order_trends/purchase_order_trends.py b/buying/report/purchase_order_trends/purchase_order_trends.py index 063bef43f2..301124fd3b 100644 --- a/buying/report/purchase_order_trends/purchase_order_trends.py +++ b/buying/report/purchase_order_trends/purchase_order_trends.py @@ -28,7 +28,7 @@ def execute(filters=None): details = get_columns(filters, trans) data = get_data(filters, tab, details) - if data == '': - webnotes.msgprint("Data Not Available") + if not data : + webnotes.msgprint("Data not found for selected criterias") return details["columns"], data \ No newline at end of file diff --git a/selling/report/quotation_trends/quotation_trends.py b/selling/report/quotation_trends/quotation_trends.py index 548a4a8253..e341752cd0 100644 --- a/selling/report/quotation_trends/quotation_trends.py +++ b/selling/report/quotation_trends/quotation_trends.py @@ -28,7 +28,7 @@ def execute(filters=None): details = get_columns(filters, trans) data = get_data(filters, tab, details) - if data == '': - webnotes.msgprint("Data Not Available") + if not data: + webnotes.msgprint("Data not found for selected criterias") return details["columns"], data \ No newline at end of file diff --git a/selling/report/sales_order_trends/sales_order_trends.py b/selling/report/sales_order_trends/sales_order_trends.py index e3d9d9f523..d556a58d37 100644 --- a/selling/report/sales_order_trends/sales_order_trends.py +++ b/selling/report/sales_order_trends/sales_order_trends.py @@ -28,7 +28,7 @@ def execute(filters=None): details = get_columns(filters, trans) data = get_data(filters, tab, details) - if data == '': - webnotes.msgprint("Data Not Available") + if not data : + webnotes.msgprint("Data not found for selected criterias") return details["columns"], data \ No newline at end of file diff --git a/stock/report/delivery_note_trends/delivery_note_trends.py b/stock/report/delivery_note_trends/delivery_note_trends.py index a161c65eee..369b6a36b1 100644 --- a/stock/report/delivery_note_trends/delivery_note_trends.py +++ b/stock/report/delivery_note_trends/delivery_note_trends.py @@ -28,7 +28,7 @@ def execute(filters=None): details = get_columns(filters, trans) data = get_data(filters, tab, details) - if data == '': - webnotes.msgprint("Data Not Available") + if not data : + webnotes.msgprint("Data not found for selected criterias") return details["columns"], data \ No newline at end of file diff --git a/stock/report/purchase_receipt_trends/purchase_receipt_trends.py b/stock/report/purchase_receipt_trends/purchase_receipt_trends.py index abce01eedd..bd089fafa2 100644 --- a/stock/report/purchase_receipt_trends/purchase_receipt_trends.py +++ b/stock/report/purchase_receipt_trends/purchase_receipt_trends.py @@ -28,7 +28,7 @@ def execute(filters=None): details = get_columns(filters, trans) data = get_data(filters, tab, details) - if data == '': - webnotes.msgprint("Data Not Available") + if not data : + webnotes.msgprint("Data not found for selected criterias") return details["columns"], data \ No newline at end of file From f841a7bc144074d496f0c935524a0d87ce1fc2c0 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Mon, 17 Jun 2013 19:25:48 +0530 Subject: [PATCH 09/21] Completed territory_target_variance(item_group_wise) report --- ...itory_target_variance_(item_group_wise).py | 193 +++++++++++++----- 1 file changed, 145 insertions(+), 48 deletions(-) diff --git a/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py b/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py index 790c6f02ad..844d4f3e05 100644 --- a/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py +++ b/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py @@ -17,73 +17,170 @@ from __future__ import unicode_literals import webnotes import calendar -from webnotes import msgprint -from webnotes.utils import cint, cstr, add_months +from webnotes import _, msgprint +from webnotes.utils import cint, cstr, add_months, flt +import time +import calendar def execute(filters=None): if not filters: filters = {} columns = get_columns(filters) + period_month_ranges = get_period_month_ranges(filters) + + target_on = "Quantity" if (filters.get("target_on")=="Quantity") else "Amount" + tim_map = get_territory_item_month_map(filters, target_on) data = [] - - return columns, data + + for territory, territory_items in tim_map.items(): + for item_group, monthwise_data in territory_items.items(): + row = [territory, item_group] + totals = [0, 0, 0] + for relevant_months in period_month_ranges: + period_data = [0, 0, 0] + for month in relevant_months: + month_data = monthwise_data.get(month, {}) + for i, fieldname in enumerate(["target", "achieved", "variance"]): + value = flt(month_data.get(fieldname)) + period_data[i] += value + totals[i] += value + period_data[2] = period_data[0] - period_data[1] + row += period_data + totals[2] = totals[0] - totals[1] + row += totals + data.append(row) + + return columns, sorted(data, key=lambda x: (x[0], x[1])) def get_columns(filters): - """return columns based on filters""" - - if not filters.get("period"): - msgprint("Please select the Period", raise_exception=1) + for fieldname in ["fiscal_year", "period", "target_on"]: + if not filters.get(fieldname): + label = (" ".join(fieldname.split("_"))).title() + msgprint(_("Please specify") + ": " + label, + raise_exception=True) - mo = cint(cstr(webnotes.conn.get_value("Fiscal Year", filters["fiscal_year"], "year_start_date")).split("-")[1]) - period_months = [] - if (filters["period"] == "Monthly" or "Yearly"): - for x in range(0,12): - period_months.append(mo) - if (mo!=12): - mo += 1 + columns = ["Territory:Link/Territory:80", "Item Group:Link/Item Group:80"] + + group_months = False if filters["period"] == "Monthly" else True + + for from_date, to_date in get_period_date_ranges(filters): + for label in ["Target (%s)", "Achieved (%s)", "Variance (%s)"]: + if group_months: + columns.append(label % (from_date.strftime("%b") + " - " + to_date.strftime("%b"))) else: - mo = 1 + columns.append(label % from_date.strftime("%b")) - columns = ["Territory:Link/Territory:80"] + ["Item Group:Link/Item Group:80"] + return columns + ["Total Target::80", "Total Achieved::80", "Total Variance::80"] - period = [] +def get_period_date_ranges(filters): + from dateutil.relativedelta import relativedelta - if (filters["period"] == "Monthly" or "Yearly"): - for i in (0,12): - period.append("Target (" + "i" + ")::80") - period.append("Achieved (" + "i" + ")::80") - period.append("Variance (" + "i" + ")::80") + year_start_date, year_end_date = get_year_start_end_date(filters) - columns = columns + [(p) for p in period] + \ - ["Total Target::80"] + ["Total Achieved::80"] + ["Total Variance::80"] + increment = { + "Monthly": 1, + "Quarterly": 3, + "Half-Yearly": 6, + "Yearly": 12 + }.get(filters["period"]) - return columns + period_date_ranges = [] + for i in xrange(1, 13, increment): + period_end_date = year_start_date + relativedelta(months=increment, + days=-1) + period_date_ranges.append([year_start_date, period_end_date]) + year_start_date = period_end_date + relativedelta(days=1) -def get_conditions(filters): - conditions = "" - - if filters.get("fiscal_year"): - conditions += " and posting_date <= '%s'" % filters["fiscal_year"] - else: - webnotes.msgprint("Please enter Fiscal Year", raise_exception=1) - - if filters.get("target_on"): - conditions += " and posting_date <= '%s'" % filters["target_on"] - else: - webnotes.msgprint("Please select Target On", raise_exception=1) + return period_date_ranges - return conditions +def get_period_month_ranges(filters): + from dateutil.relativedelta import relativedelta + period_month_ranges = [] + + for start_date, end_date in get_period_date_ranges(filters): + months_in_this_period = [] + while start_date <= end_date: + months_in_this_period.append(start_date.strftime("%B")) + start_date += relativedelta(months=1) + period_month_ranges.append(months_in_this_period) + + return period_month_ranges -#get territory details +#Get territory & item group details def get_territory_details(filters): - conditions = get_conditions(filters) - return webnotes.conn.sql("""select item_code, batch_no, warehouse, - posting_date, actual_qty - from `tabStock Ledger Entry` - where ifnull(is_cancelled, 'No') = 'No' %s order by item_code, warehouse""" % - conditions, as_dict=1) + return webnotes.conn.sql("""select t.name, td.item_group, td.target_qty, td.target_amount, + t.distribution_id from `tabTerritory` t, `tabTarget Detail` td + where td.parent=t.name and td.fiscal_year=%s and + ifnull(t.distribution_id, '')!='' order by t.name""" % + ('%s'), (filters.get("fiscal_year")), as_dict=1) -def get_month_abbr(month_number): - return 0 \ No newline at end of file +#Get target distribution details of item group +def get_target_distribution_details(filters): + target_details = {} + abc = [] + for d in webnotes.conn.sql("""select bdd.month, bdd.percentage_allocation \ + from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd, \ + `tabTerritory` t where bdd.parent=bd.name and t.distribution_id=bd.name and \ + bd.fiscal_year=%s """ % ('%s'), (filters.get("fiscal_year")), as_dict=1): + target_details.setdefault(d.month, d) + + return target_details + +#Get achieved details from sales order +def get_achieved_details(filters): + start_date, end_date = get_year_start_end_date(filters) + achieved_details = {} + + for d in webnotes.conn.sql("""select soi.item_code, soi.qty, soi.amount, so.transaction_date, \ + MONTHNAME(so.transaction_date) as month_name \ + from `tabSales Order Item` soi, `tabSales Order` so \ + where soi.parent=so.name and so.docstatus=1 and so.transaction_date>=%s and \ + so.transaction_date<=%s""" % ('%s', '%s'), \ + (start_date, end_date), as_dict=1): + achieved_details.setdefault(d.month_name, d) + + return achieved_details + +def get_territory_item_month_map(filters, target_on): + territory_details = get_territory_details(filters) + tdd = get_target_distribution_details(filters) + achieved_details = get_achieved_details(filters) + + ti_map = {} + + for td in territory_details: + for month in tdd: + ti_map.setdefault(td.name, {}).setdefault(td.item_group, {})\ + .setdefault(month, webnotes._dict({ + "target": 0.0, "achieved": 0.0, "variance": 0.0 + })) + + tav_dict = ti_map[td.name][td.item_group][month] + + for ad in achieved_details: + if (target_on == "Quantity"): + tav_dict.target = td.target_qty*(tdd[month]["percentage_allocation"]/100) + if ad == month and ''.join(get_item_group(achieved_details[month]["item_code"])) == td.item_group: + tav_dict.achieved += achieved_details[month]["qty"] + + if (target_on == "Amount"): + tav_dict.target = td.target_amount*(tdd[month]["percentage_allocation"]/100) + if ad == month and ''.join(get_item_group(achieved_details[month]["item_code"])) == td.item_group: + tav_dict.achieved += achieved_details[month]["amount"] + + return ti_map + +def get_year_start_end_date(filters): + return webnotes.conn.sql("""select year_start_date, + subdate(adddate(year_start_date, interval 1 year), interval 1 day) + as year_end_date + from `tabFiscal Year` + where name=%s""", filters["fiscal_year"])[0] + +def get_item_group(item_name): + """Get Item Group of an item""" + + return webnotes.conn.sql_list("select item_group from `tabItem` where name=%s""" % + ('%s'), (item_name)) \ No newline at end of file From 24208f5c4a985d1a762251d166808c4f7e85ee89 Mon Sep 17 00:00:00 2001 From: Saurabh Date: Tue, 18 Jun 2013 15:45:08 +0530 Subject: [PATCH 10/21] [Report][Item-Wise Purchase Receipt] --- buying/page/buying_home/buying_home.js | 4 ++++ .../item_wise_last_purchase_rate/__init__.py | 0 .../item_wise_last_purchase_rate.txt | 22 +++++++++++++++++++ controllers/trends.py | 6 ++--- 4 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 buying/report/item_wise_last_purchase_rate/__init__.py create mode 100644 buying/report/item_wise_last_purchase_rate/item_wise_last_purchase_rate.txt diff --git a/buying/page/buying_home/buying_home.js b/buying/page/buying_home/buying_home.js index dfcd71e17d..0e078fefc9 100644 --- a/buying/page/buying_home/buying_home.js +++ b/buying/page/buying_home/buying_home.js @@ -120,6 +120,10 @@ wn.module_page["Buying"] = [ route: "query-report/Purchase Order Trends", doctype: "Purchase Order" }, + { + "label":wn._("Item-wise Last Purchase Rate"), + route: "query-report/Item-wise Last Purchase Rate", + } ] } ] diff --git a/buying/report/item_wise_last_purchase_rate/__init__.py b/buying/report/item_wise_last_purchase_rate/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/buying/report/item_wise_last_purchase_rate/item_wise_last_purchase_rate.txt b/buying/report/item_wise_last_purchase_rate/item_wise_last_purchase_rate.txt new file mode 100644 index 0000000000..db99e724ce --- /dev/null +++ b/buying/report/item_wise_last_purchase_rate/item_wise_last_purchase_rate.txt @@ -0,0 +1,22 @@ +[ + { + "creation": "2013-06-18 11:24:36", + "docstatus": 0, + "modified": "2013-06-18 15:28:57", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "query": "select * from (select \n result.item_code as \"Item Code:Link/Item:120\",\n result.item_name as \"Item Name::120\",\n result.description as \"Description::150\",\n result.posting_date as \"Date::150\",\n result.purchase_ref_rate as \"Price List Rate::180\", \n result.discount_rate as \"Discount::120\", \n result.purchase_rate as \"Rate::120\"\nfrom (\n (select \n po_item.item_code,\n po_item.item_name,\n po_item.description,\n po.transaction_date as posting_date,\n po_item.purchase_ref_rate, \n po_item.discount_rate, \n po_item.purchase_rate\n from `tabPurchase Order` po, `tabPurchase Order Item` po_item\n where po.name = po_item.parent and po.docstatus = 1)\n union\n (select \n pr_item.item_code,\n pr_item.item_name,\n pr_item.description,\n pr.posting_date,\n pr_item.purchase_ref_rate,\n pr_item.discount_rate,\n pr_item.purchase_rate\n from `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pr_item\n where pr.name = pr_item.parent and pr.docstatus = 1)\n) result\norder by result.item_code asc, result.posting_date desc) result_wrapper\ngroup by `Item Code:Link/Item:120`\n", + "ref_doctype": "Purchase Order", + "report_name": "Item-wise Last Purchase Rate", + "report_type": "Query Report" + }, + { + "doctype": "Report", + "name": "Item-wise Last Purchase Rate" + } +] \ No newline at end of file diff --git a/controllers/trends.py b/controllers/trends.py index dee9ec8b4f..8905591193 100644 --- a/controllers/trends.py +++ b/controllers/trends.py @@ -83,7 +83,7 @@ def get_data(filters, tab, details): #to get distinct value of col specified by group_by in filter row = webnotes.conn.sql("""select DISTINCT(%s) from `%s` t1, `%s` t2 %s where t2.parent = t1.name and t1.company = %s - and t1.fiscal_year = %s and t1.docstatus = 1 + and t1.fiscal_year = %s and t1.docstatus = 1 and %s = %s """%(sel_col, tab[0], tab[1], details["sup_tab"], "%s", "%s", details["basedon"], "%s"), @@ -224,13 +224,13 @@ def basedon_wise_colums_query(based_on, trans): bon = ["Supplier:Link/Supplier:120", "Supplier Type:Link/Supplier Type:120"] query_details = "t1.supplier, t3.supplier_type," basedon = 't1.supplier' - sup_tab = ',`tabSupplier` t3' + sup_tab = '`tabSupplier` t3', elif based_on == 'Supplier Type': bon = ["Supplier Type:Link/Supplier Type:120"] query_details = "t3.supplier_type," basedon = 't3.supplier_type' - sup_tab = ',`tabSupplier` t3' + sup_tab ='`tabSupplier` t3', elif based_on == "Territory": bon = ["Territory:Link/Territory:120"] From 4ddc2618e8611f39665cddb49a6d93e646a80317 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Tue, 18 Jun 2013 18:46:02 +0530 Subject: [PATCH 11/21] [Report] Completed Sales Person Target Variance (Item-Group wise) --- accounts/page/accounts_home/accounts_home.js | 5 + .../report/budget_variance_report/__init__.py | 0 .../budget_variance_report.js | 25 +++ .../budget_variance_report.py | 184 ++++++++++++++++++ .../budget_variance_report.txt | 21 ++ selling/page/selling_home/selling_home.js | 5 + .../__init__.py | 0 ...erson_target_variance_(item_group_wise).js | 25 +++ ...erson_target_variance_(item_group_wise).py | 184 ++++++++++++++++++ ...rson_target_variance_(item_group_wise).txt | 21 ++ ...itory_target_variance_(item_group_wise).py | 26 ++- 11 files changed, 482 insertions(+), 14 deletions(-) create mode 100644 accounts/report/budget_variance_report/__init__.py create mode 100644 accounts/report/budget_variance_report/budget_variance_report.js create mode 100644 accounts/report/budget_variance_report/budget_variance_report.py create mode 100644 accounts/report/budget_variance_report/budget_variance_report.txt create mode 100644 selling/report/sales_person_target_variance_(item_group_wise)/__init__.py create mode 100644 selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).js create mode 100644 selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).py create mode 100644 selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).txt diff --git a/accounts/page/accounts_home/accounts_home.js b/accounts/page/accounts_home/accounts_home.js index b920bfdbab..b4846746a4 100644 --- a/accounts/page/accounts_home/accounts_home.js +++ b/accounts/page/accounts_home/accounts_home.js @@ -252,6 +252,11 @@ wn.module_page["Accounts"] = [ route: "query-report/Item-wise Purchase Register", doctype: "Purchase Invoice" }, + { + "label":wn._("Budget Variance Report"), + route: "query-report/Budget Variance Report", + doctype: "Cost Center" + }, ] } ] diff --git a/accounts/report/budget_variance_report/__init__.py b/accounts/report/budget_variance_report/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/accounts/report/budget_variance_report/budget_variance_report.js b/accounts/report/budget_variance_report/budget_variance_report.js new file mode 100644 index 0000000000..a0516050ce --- /dev/null +++ b/accounts/report/budget_variance_report/budget_variance_report.js @@ -0,0 +1,25 @@ +wn.query_reports["Budget Variance Report"] = { + "filters": [ + { + fieldname: "fiscal_year", + label: "Fiscal Year", + fieldtype: "Link", + options: "Fiscal Year", + default: sys_defaults.fiscal_year + }, + { + fieldname: "period", + label: "Period", + fieldtype: "Select", + options: "Monthly\nQuarterly\nHalf-Yearly\nYearly", + default: "Monthly" + }, + { + fieldname: "company", + label: "Company", + fieldtype: "Link", + options: "Company", + default: sys_defaults.company + }, + ] +} \ No newline at end of file diff --git a/accounts/report/budget_variance_report/budget_variance_report.py b/accounts/report/budget_variance_report/budget_variance_report.py new file mode 100644 index 0000000000..ac38d9f34d --- /dev/null +++ b/accounts/report/budget_variance_report/budget_variance_report.py @@ -0,0 +1,184 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import unicode_literals +import webnotes +import calendar +from webnotes import _, msgprint +from webnotes.utils import flt +import time + +def execute(filters=None): + if not filters: filters = {} + + columns = get_columns(filters) + period_month_ranges = get_period_month_ranges(filters) + # tim_map = get_territory_item_month_map(filters) + + data = [] + + # for territory, territory_items in tim_map.items(): + # for item_group, monthwise_data in territory_items.items(): + # row = [territory, item_group] + # totals = [0, 0, 0] + # for relevant_months in period_month_ranges: + # period_data = [0, 0, 0] + # for month in relevant_months: + # month_data = monthwise_data.get(month, {}) + # for i, fieldname in enumerate(["target", "achieved", "variance"]): + # value = flt(month_data.get(fieldname)) + # period_data[i] += value + # totals[i] += value + # period_data[2] = period_data[0] - period_data[1] + # row += period_data + # totals[2] = totals[0] - totals[1] + # row += totals + # data.append(row) + + return columns, sorted(data, key=lambda x: (x[0], x[1])) + +def get_columns(filters): + for fieldname in ["fiscal_year", "period", "company"]: + if not filters.get(fieldname): + label = (" ".join(fieldname.split("_"))).title() + msgprint(_("Please specify") + ": " + label, + raise_exception=True) + + columns = ["Cost Center:Link/Cost Center:80"] + + group_months = False if filters["period"] == "Monthly" else True + + for from_date, to_date in get_period_date_ranges(filters): + for label in ["Target (%s)", "Actual (%s)", "Variance (%s)"]: + if group_months: + columns.append(label % (from_date.strftime("%b") + " - " + to_date.strftime("%b"))) + else: + columns.append(label % from_date.strftime("%b")) + + return columns + ["Total Target::80", "Total Actual::80", "Total Variance::80"] + +def get_period_date_ranges(filters): + from dateutil.relativedelta import relativedelta + + year_start_date, year_end_date = get_year_start_end_date(filters) + + increment = { + "Monthly": 1, + "Quarterly": 3, + "Half-Yearly": 6, + "Yearly": 12 + }.get(filters["period"]) + + period_date_ranges = [] + for i in xrange(1, 13, increment): + period_end_date = year_start_date + relativedelta(months=increment, + days=-1) + period_date_ranges.append([year_start_date, period_end_date]) + year_start_date = period_end_date + relativedelta(days=1) + + return period_date_ranges + +def get_period_month_ranges(filters): + from dateutil.relativedelta import relativedelta + period_month_ranges = [] + + for start_date, end_date in get_period_date_ranges(filters): + months_in_this_period = [] + while start_date <= end_date: + months_in_this_period.append(start_date.strftime("%B")) + start_date += relativedelta(months=1) + period_month_ranges.append(months_in_this_period) + + return period_month_ranges + + +#Get cost center details +def get_costcenter_details(filters): + return webnotes.conn.sql("""select t.name, td.item_group, td.target_qty, + td.target_amount, t.distribution_id + from `tabTerritory` t, `tabTarget Detail` td + where td.parent=t.name and td.fiscal_year=%s and + ifnull(t.distribution_id, '')!='' order by t.name""" % + ('%s'), (filters.get("fiscal_year")), as_dict=1) + +#Get target distribution details of item group +def get_target_distribution_details(filters): + target_details = {} + abc = [] + for d in webnotes.conn.sql("""select bdd.month, bdd.percentage_allocation \ + from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd, \ + `tabTerritory` t where bdd.parent=bd.name and t.distribution_id=bd.name and \ + bd.fiscal_year=%s """ % ('%s'), (filters.get("fiscal_year")), as_dict=1): + target_details.setdefault(d.month, d) + + return target_details + +#Get achieved details from sales order +def get_achieved_details(filters): + start_date, end_date = get_year_start_end_date(filters) + achieved_details = {} + + for d in webnotes.conn.sql("""select soi.item_code, soi.qty, soi.amount, so.transaction_date, \ + MONTHNAME(so.transaction_date) as month_name \ + from `tabSales Order Item` soi, `tabSales Order` so \ + where soi.parent=so.name and so.docstatus=1 and so.transaction_date>=%s and \ + so.transaction_date<=%s""" % ('%s', '%s'), \ + (start_date, end_date), as_dict=1): + achieved_details.setdefault(d.month_name, d) + + return achieved_details + +def get_territory_item_month_map(filters): + territory_details = get_territory_details(filters) + tdd = get_target_distribution_details(filters) + achieved_details = get_achieved_details(filters) + + tim_map = {} + + for td in territory_details: + for month in tdd: + tim_map.setdefault(td.name, {}).setdefault(td.item_group, {})\ + .setdefault(month, webnotes._dict({ + "target": 0.0, "achieved": 0.0, "variance": 0.0 + })) + + tav_dict = tim_map[td.name][td.item_group][month] + + for ad in achieved_details: + if (filters["target_on"] == "Quantity"): + tav_dict.target = td.target_qty*(tdd[month]["percentage_allocation"]/100) + if ad == month and ''.join(get_item_group(achieved_details[month]["item_code"])) == td.item_group: + tav_dict.achieved += achieved_details[month]["qty"] + + if (filters["target_on"] == "Amount"): + tav_dict.target = td.target_amount*(tdd[month]["percentage_allocation"]/100) + if ad == month and ''.join(get_item_group(achieved_details[month]["item_code"])) == td.item_group: + tav_dict.achieved += achieved_details[month]["amount"] + + return tim_map + +def get_year_start_end_date(filters): + return webnotes.conn.sql("""select year_start_date, + subdate(adddate(year_start_date, interval 1 year), interval 1 day) + as year_end_date + from `tabFiscal Year` + where name=%s""", filters["fiscal_year"])[0] + +def get_item_group(item_name): + """Get Item Group of an item""" + + return webnotes.conn.sql_list("select item_group from `tabItem` where name=%s""" % + ('%s'), (item_name)) \ No newline at end of file diff --git a/accounts/report/budget_variance_report/budget_variance_report.txt b/accounts/report/budget_variance_report/budget_variance_report.txt new file mode 100644 index 0000000000..b89cb4545f --- /dev/null +++ b/accounts/report/budget_variance_report/budget_variance_report.txt @@ -0,0 +1,21 @@ +[ + { + "creation": "2013-06-18 12:56:36", + "docstatus": 0, + "modified": "2013-06-18 12:56:36", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Cost Center", + "report_name": "Budget Variance Report", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "Budget Variance Report" + } +] \ No newline at end of file diff --git a/selling/page/selling_home/selling_home.js b/selling/page/selling_home/selling_home.js index e3663c93e4..0792f0a8e6 100644 --- a/selling/page/selling_home/selling_home.js +++ b/selling/page/selling_home/selling_home.js @@ -170,6 +170,11 @@ wn.module_page["Selling"] = [ route: "query-report/Territory Target Variance (Item Group-Wise)", doctype: "Sales Order" }, + { + "label":wn._("Sales Person Target Variance (Item Group-Wise)"), + route: "query-report/Sales Person Target Variance (Item Group-Wise)", + doctype: "Sales Order" + }, { "label":wn._("Customers Not Buying Since Long Time"), route: "query-report/Customers Not Buying Since Long Time", diff --git a/selling/report/sales_person_target_variance_(item_group_wise)/__init__.py b/selling/report/sales_person_target_variance_(item_group_wise)/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).js b/selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).js new file mode 100644 index 0000000000..09f0d55aed --- /dev/null +++ b/selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).js @@ -0,0 +1,25 @@ +wn.query_reports["Sales Person Target Variance (Item Group-Wise)"] = { + "filters": [ + { + fieldname: "fiscal_year", + label: "Fiscal Year", + fieldtype: "Link", + options: "Fiscal Year", + default: sys_defaults.fiscal_year + }, + { + fieldname: "period", + label: "Period", + fieldtype: "Select", + options: "Monthly\nQuarterly\nHalf-Yearly\nYearly", + default: "Monthly" + }, + { + fieldname: "target_on", + label: "Target On", + fieldtype: "Select", + options: "Quantity\nAmount", + default: "Quantity" + }, + ] +} \ No newline at end of file diff --git a/selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).py b/selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).py new file mode 100644 index 0000000000..3163829131 --- /dev/null +++ b/selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).py @@ -0,0 +1,184 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import unicode_literals +import webnotes +import calendar +from webnotes import _, msgprint +from webnotes.utils import flt +import time + +def execute(filters=None): + if not filters: filters = {} + + columns = get_columns(filters) + period_month_ranges = get_period_month_ranges(filters) + sim_map = get_salesperson_item_month_map(filters) + + data = [] + + for salesperson, salesperson_items in sim_map.items(): + for item_group, monthwise_data in salesperson_items.items(): + row = [salesperson, item_group] + totals = [0, 0, 0] + for relevant_months in period_month_ranges: + period_data = [0, 0, 0] + for month in relevant_months: + month_data = monthwise_data.get(month, {}) + for i, fieldname in enumerate(["target", "achieved", "variance"]): + value = flt(month_data.get(fieldname)) + period_data[i] += value + totals[i] += value + period_data[2] = period_data[0] - period_data[1] + row += period_data + totals[2] = totals[0] - totals[1] + row += totals + data.append(row) + + return columns, sorted(data, key=lambda x: (x[0], x[1])) + +def get_columns(filters): + for fieldname in ["fiscal_year", "period", "target_on"]: + if not filters.get(fieldname): + label = (" ".join(fieldname.split("_"))).title() + msgprint(_("Please specify") + ": " + label, + raise_exception=True) + + columns = ["Sales Person:Link/Sales Person:80", "Item Group:Link/Item Group:80"] + + group_months = False if filters["period"] == "Monthly" else True + + for from_date, to_date in get_period_date_ranges(filters): + for label in ["Target (%s)", "Achieved (%s)", "Variance (%s)"]: + if group_months: + columns.append(label % (from_date.strftime("%b") + " - " + to_date.strftime("%b"))) + else: + columns.append(label % from_date.strftime("%b")) + + return columns + ["Total Target::80", "Total Achieved::80", "Total Variance::80"] + +def get_period_date_ranges(filters): + from dateutil.relativedelta import relativedelta + + year_start_date, year_end_date = get_year_start_end_date(filters) + + increment = { + "Monthly": 1, + "Quarterly": 3, + "Half-Yearly": 6, + "Yearly": 12 + }.get(filters["period"]) + + period_date_ranges = [] + for i in xrange(1, 13, increment): + period_end_date = year_start_date + relativedelta(months=increment, + days=-1) + period_date_ranges.append([year_start_date, period_end_date]) + year_start_date = period_end_date + relativedelta(days=1) + + return period_date_ranges + +def get_period_month_ranges(filters): + from dateutil.relativedelta import relativedelta + period_month_ranges = [] + + for start_date, end_date in get_period_date_ranges(filters): + months_in_this_period = [] + while start_date <= end_date: + months_in_this_period.append(start_date.strftime("%B")) + start_date += relativedelta(months=1) + period_month_ranges.append(months_in_this_period) + + return period_month_ranges + + +#Get sales person & item group details +def get_salesperson_details(filters): + return webnotes.conn.sql("""select sp.name, td.item_group, td.target_qty, + td.target_amount, sp.distribution_id + from `tabSales Person` sp, `tabTarget Detail` td + where td.parent=sp.name and td.fiscal_year=%s and + ifnull(sp.distribution_id, '')!='' order by sp.name""" % + ('%s'), (filters.get("fiscal_year")), as_dict=1) + +#Get target distribution details of item group +def get_target_distribution_details(filters): + target_details = {} + abc = [] + for d in webnotes.conn.sql("""select bdd.month, bdd.percentage_allocation \ + from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd, \ + `tabTerritory` t where bdd.parent=bd.name and t.distribution_id=bd.name and \ + bd.fiscal_year=%s """ % ('%s'), (filters.get("fiscal_year")), as_dict=1): + target_details.setdefault(d.month, d) + + return target_details + +#Get achieved details from sales order +def get_achieved_details(filters): + start_date, end_date = get_year_start_end_date(filters) + achieved_details = {} + + for d in webnotes.conn.sql("""select soi.item_code, soi.qty, soi.amount, so.transaction_date, \ + MONTHNAME(so.transaction_date) as month_name \ + from `tabSales Order Item` soi, `tabSales Order` so \ + where soi.parent=so.name and so.docstatus=1 and so.transaction_date>=%s and \ + so.transaction_date<=%s""" % ('%s', '%s'), \ + (start_date, end_date), as_dict=1): + achieved_details.setdefault(d.month_name, d) + + return achieved_details + +def get_salesperson_item_month_map(filters): + salesperson_details = get_salesperson_details(filters) + tdd = get_target_distribution_details(filters) + achieved_details = get_achieved_details(filters) + + sim_map = {} + + for sd in salesperson_details: + for month in tdd: + sim_map.setdefault(sd.name, {}).setdefault(sd.item_group, {})\ + .setdefault(month, webnotes._dict({ + "target": 0.0, "achieved": 0.0, "variance": 0.0 + })) + + tav_dict = sim_map[sd.name][sd.item_group][month] + + for ad in achieved_details: + if (filters["target_on"] == "Quantity"): + tav_dict.target = sd.target_qty*(tdd[month]["percentage_allocation"]/100) + if ad == month and ''.join(get_item_group(achieved_details[month]["item_code"])) == sd.item_group: + tav_dict.achieved += achieved_details[month]["qty"] + + if (filters["target_on"] == "Amount"): + tav_dict.target = sd.target_amount*(tdd[month]["percentage_allocation"]/100) + if ad == month and ''.join(get_item_group(achieved_details[month]["item_code"])) == sd.item_group: + tav_dict.achieved += achieved_details[month]["amount"] + + return sim_map + +def get_year_start_end_date(filters): + return webnotes.conn.sql("""select year_start_date, + subdate(adddate(year_start_date, interval 1 year), interval 1 day) + as year_end_date + from `tabFiscal Year` + where name=%s""", filters["fiscal_year"])[0] + +def get_item_group(item_name): + """Get Item Group of an item""" + + return webnotes.conn.sql_list("select item_group from `tabItem` where name=%s""" % + ('%s'), (item_name)) \ No newline at end of file diff --git a/selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).txt b/selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).txt new file mode 100644 index 0000000000..955cdec477 --- /dev/null +++ b/selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).txt @@ -0,0 +1,21 @@ +[ + { + "creation": "2013-06-18 12:09:40", + "docstatus": 0, + "modified": "2013-06-18 12:09:40", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Sales Order", + "report_name": "Sales Person Target Variance (Item Group-Wise)", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "Sales Person Target Variance (Item Group-Wise)" + } +] \ No newline at end of file diff --git a/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py b/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py index 844d4f3e05..fe5e628c65 100644 --- a/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py +++ b/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py @@ -18,18 +18,15 @@ from __future__ import unicode_literals import webnotes import calendar from webnotes import _, msgprint -from webnotes.utils import cint, cstr, add_months, flt +from webnotes.utils import flt import time -import calendar def execute(filters=None): if not filters: filters = {} columns = get_columns(filters) period_month_ranges = get_period_month_ranges(filters) - - target_on = "Quantity" if (filters.get("target_on")=="Quantity") else "Amount" - tim_map = get_territory_item_month_map(filters, target_on) + tim_map = get_territory_item_month_map(filters) data = [] @@ -110,8 +107,9 @@ def get_period_month_ranges(filters): #Get territory & item group details def get_territory_details(filters): - return webnotes.conn.sql("""select t.name, td.item_group, td.target_qty, td.target_amount, - t.distribution_id from `tabTerritory` t, `tabTarget Detail` td + return webnotes.conn.sql("""select t.name, td.item_group, td.target_qty, + td.target_amount, t.distribution_id + from `tabTerritory` t, `tabTarget Detail` td where td.parent=t.name and td.fiscal_year=%s and ifnull(t.distribution_id, '')!='' order by t.name""" % ('%s'), (filters.get("fiscal_year")), as_dict=1) @@ -143,34 +141,34 @@ def get_achieved_details(filters): return achieved_details -def get_territory_item_month_map(filters, target_on): +def get_territory_item_month_map(filters): territory_details = get_territory_details(filters) tdd = get_target_distribution_details(filters) achieved_details = get_achieved_details(filters) - ti_map = {} + tim_map = {} for td in territory_details: for month in tdd: - ti_map.setdefault(td.name, {}).setdefault(td.item_group, {})\ + tim_map.setdefault(td.name, {}).setdefault(td.item_group, {})\ .setdefault(month, webnotes._dict({ "target": 0.0, "achieved": 0.0, "variance": 0.0 })) - tav_dict = ti_map[td.name][td.item_group][month] + tav_dict = tim_map[td.name][td.item_group][month] for ad in achieved_details: - if (target_on == "Quantity"): + if (filters["target_on"] == "Quantity"): tav_dict.target = td.target_qty*(tdd[month]["percentage_allocation"]/100) if ad == month and ''.join(get_item_group(achieved_details[month]["item_code"])) == td.item_group: tav_dict.achieved += achieved_details[month]["qty"] - if (target_on == "Amount"): + if (filters["target_on"] == "Amount"): tav_dict.target = td.target_amount*(tdd[month]["percentage_allocation"]/100) if ad == month and ''.join(get_item_group(achieved_details[month]["item_code"])) == td.item_group: tav_dict.achieved += achieved_details[month]["amount"] - return ti_map + return tim_map def get_year_start_end_date(filters): return webnotes.conn.sql("""select year_start_date, From 5b6d03e479603275684169f8f14c337fa811623e Mon Sep 17 00:00:00 2001 From: Saurabh Date: Wed, 19 Jun 2013 12:34:22 +0530 Subject: [PATCH 12/21] [Report][Trend Analyzer] --- controllers/trends.py | 75 ++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/controllers/trends.py b/controllers/trends.py index 8905591193..b00afe8d90 100644 --- a/controllers/trends.py +++ b/controllers/trends.py @@ -66,13 +66,13 @@ def get_data(filters, tab, details): inc = 1 data1 = webnotes.conn.sql(""" select %s from `%s` t1, `%s` t2 %s - where t2.parent = t1.name and t1.company = %s - and t1.fiscal_year = %s and t1.docstatus = 1 %s - group by %s - """ % (query_details, tab[0], tab[1], details["sup_tab"], "%s", - "%s", cond, details["basedon"]), (filters.get("company"), - filters["fiscal_year"]), - as_list=1) + where t2.parent = t1.name and t1.company = %s + and t1.fiscal_year = %s and t1.docstatus = 1 %s + group by %s + """ % (query_details, tab[0], tab[1], details["sup_tab"], "%s", + "%s", cond, details["basedon"]), (filters.get("company"), + filters["fiscal_year"]), + as_list=1) for d in range(len(data1)): #to add blanck column @@ -82,28 +82,23 @@ def get_data(filters, tab, details): #to get distinct value of col specified by group_by in filter row = webnotes.conn.sql("""select DISTINCT(%s) from `%s` t1, `%s` t2 %s - where t2.parent = t1.name and t1.company = %s - and t1.fiscal_year = %s and t1.docstatus = 1 - and %s = %s - """%(sel_col, tab[0], tab[1], details["sup_tab"], "%s", - "%s", details["basedon"], "%s"), - (filters.get("company"), filters.get("fiscal_year"), - data1[d][0]), - as_list=1) + where t2.parent = t1.name and t1.company = %s and t1.fiscal_year = %s + and t1.docstatus = 1 and %s = %s + """%(sel_col, tab[0], tab[1], details["sup_tab"], "%s", "%s", details["basedon"], "%s"), + (filters.get("company"), filters.get("fiscal_year"), data1[d][0]), + as_list=1) for i in range(len(row)): des = ['' for q in range(len(details["columns"]))] #get data for each group_by filter row1 = webnotes.conn.sql(""" select %s , %s from `%s` t1, `%s` t2 %s - where t2.parent = t1.name and t1.company = %s - and t1.fiscal_year = %s and t1.docstatus = 1 - and %s = %s and %s = %s - """%(sel_col, details["query_pwc"], tab[0], tab[1], details["sup_tab"], - "%s", "%s", sel_col, "%s", details["basedon"], "%s"), - (filters.get("company"), filters.get("fiscal_year"), row[i][0], - data1[d][0]), - as_list=1) + where t2.parent = t1.name and t1.company = %s and t1.fiscal_year = %s + and t1.docstatus = 1 and %s = %s and %s = %s + """%(sel_col, details["query_pwc"], tab[0], tab[1], details["sup_tab"], + "%s", "%s", sel_col, "%s", details["basedon"], "%s"), + (filters.get("company"), filters.get("fiscal_year"), row[i][0], data1[d][0]), + as_list=1) des[ind] = row[i] for j in range(1,len(details["columns"])-inc): @@ -112,13 +107,13 @@ def get_data(filters, tab, details): else: data = webnotes.conn.sql(""" select %s from `%s` t1, `%s` t2 %s - where t2.parent = t1.name and t1.company = %s - and t1.fiscal_year = %s and t1.docstatus = 1 - %s group by %s - """%(query_details, tab[0], tab[1], details["sup_tab"], "%s", - "%s", cond,details["basedon"]), (filters.get("company"), - filters.get("fiscal_year")), - as_list=1) + where t2.parent = t1.name and t1.company = %s + and t1.fiscal_year = %s and t1.docstatus = 1 %s + group by %s + """%(query_details, tab[0], tab[1], details["sup_tab"], "%s", + "%s", cond,details["basedon"]), (filters.get("company"), + filters.get("fiscal_year")), + as_list=1) return data @@ -146,8 +141,8 @@ def period_wise_colums_query(filters, trans): pwc.append(month_name[month]+' (Amt):Currency:120') query_details += """ - Sum(CASE WHEN MONTH(t1.%(trans)s)= %(mon_num)s THEN t2.qty ELSE NULL END), - SUM(CASE WHEN MONTH(t1.%(trans)s)= %(mon_num)s THEN t1.grand_total ELSE NULL END), + Sum(IF(MONTH(t1.%(trans)s)= %(mon_num)s, t2.qty, NULL)), + SUM(IF(MONTH(t1.%(trans)s)= %(mon_num)s, t1.grand_total, NULL)), """%{"trans": trans_date,"mon_num": cstr(month+1)} for month in range(0, start_month-1): @@ -155,8 +150,8 @@ def period_wise_colums_query(filters, trans): pwc.append(month_name[month]+' (Amt):Currency:120') query_details += """ - Sum(CASE WHEN MONTH(t1.%(trans)s)= %(mon_num)s THEN t2.qty ELSE NULL END), - SUM(CASE WHEN MONTH(t1.%(trans)s)= %(mon_num)s THEN t1.grand_total ELSE NULL END), + Sum(IF(MONTH(t1.%(trans)s)= %(mon_num)s, t2.qty, NULL)), + SUM(IF(MONTH(t1.%(trans)s)= %(mon_num)s, t1.grand_total, NULL)), """%{"trans": trans_date, "mon_num": cstr(month+1)} elif filters.get("period") == "Quarterly": @@ -169,8 +164,8 @@ def period_wise_colums_query(filters, trans): for d in bet_dates: query_details += """ - SUM(CASE WHEN t1.%(trans)s BETWEEN '%(sd)s' AND '%(ed)s' THEN t2.qty ELSE NULL END), - SUM(CASE WHEN t1.%(trans)s BETWEEN '%(sd)s' AND '%(ed)s' THEN t1.grand_total ELSE NULL END), + SUM(IF(t1.%(trans)s BETWEEN '%(sd)s' AND '%(ed)s', t2.qty, NULL)), + SUM(IF(t1.%(trans)s BETWEEN '%(sd)s' AND '%(ed)s', t1.grand_total, NULL)), """%{"trans": trans_date, "sd": d[0],"ed": d[1]} elif filters.get("period") == "Half-yearly": @@ -183,10 +178,10 @@ def period_wise_colums_query(filters, trans): second_half_end = add_days(add_months(second_half_start,6),-1) query_details = """ - SUM(CASE WHEN t1.%(trans)s BETWEEN '%(fhs)s' AND '%(fhe)s' THEN t2.qty ELSE NULL END), - SUM(CASE WHEN t1.%(trans)s BETWEEN '%(fhs)s' AND '%(fhe)s' THEN t1.grand_total ELSE NULL END), - SUM(CASE WHEN t1.%(trans)s BETWEEN '%(shs)s' AND '%(she)s' THEN t2.qty ELSE NULL END), - SUM(CASE WHEN t1.%(trans)s BETWEEN '%(shs)s' AND '%(she)s' THEN t1.grand_total ELSE NULL END), + SUM(IF(t1.%(trans)s BETWEEN '%(fhs)s' AND '%(fhe)s', t2.qty, NULL)), + SUM(IF(t1.%(trans)s BETWEEN '%(fhs)s' AND '%(fhe)s', t1.grand_total, NULL)), + SUM(IF(t1.%(trans)s BETWEEN '%(shs)s' AND '%(she)s', t2.qty, NULL)), + SUM(IF(t1.%(trans)s BETWEEN '%(shs)s' AND '%(she)s', t1.grand_total, NULL)), """%{"trans": trans_date, "fhs": first_half_start, "fhe": first_half_end,"shs": second_half_start, "she": second_half_end} From bfe9fe7c3b0481e20ae3028b3e69c4b658662a42 Mon Sep 17 00:00:00 2001 From: Saurabh Date: Wed, 19 Jun 2013 12:41:28 +0530 Subject: [PATCH 13/21] [Report][Spliting of Trend Analyzer Completed] --- controllers/trends.py | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/controllers/trends.py b/controllers/trends.py index b00afe8d90..76db44705f 100644 --- a/controllers/trends.py +++ b/controllers/trends.py @@ -27,15 +27,15 @@ def get_columns(filters, trans): webnotes.msgprint("Plese select different values in 'Based On' and 'Group By'", raise_exception=1) else: - bon, query_bon, basedon, sup_tab = basedon_wise_colums_query(filters.get("based_on"), trans) + bonc, query_bon, based, sup_tab = basedon_wise_colums_query(filters.get("based_on"), trans) pwc, query_pwc = period_wise_colums_query(filters, trans) grbc = group_wise_column(filters.get("group_by")) - columns = bon + pwc + ["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] + columns = bonc + pwc + ["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] if grbc: - columns = bon + grbc + pwc +["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] + columns = bonc + grbc + pwc +["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] - details = {"query_bon": query_bon, "query_pwc": query_pwc, "columns": columns, "basedon": basedon, + details = {"query_bon": query_bon, "query_pwc": query_pwc, "columns": columns, "basedon": based, "grbc": grbc, "sup_tab": sup_tab} return details @@ -121,9 +121,8 @@ def period_wise_colums_query(filters, trans): query_details = '' pwc = [] - ysd = webnotes.conn.sql("""select year_start_date from `tabFiscal Year` - where name = '%s' - """%filters.get("fiscal_year"))[0][0] + ysd = webnotes.conn.sql("""select year_start_date from `tabFiscal Year` where name = '%s' + """%filters.get("fiscal_year"))[0][0] year_start_date = ysd.strftime('%Y-%m-%d') start_month = cint(year_start_date.split('-')[1]) @@ -198,56 +197,56 @@ def basedon_wise_colums_query(based_on, trans): if based_on == "Item": bon = ["Item:Link/Item:120", "Item Name:Data:120"] query_details = "t2.item_code, t2.item_name," - basedon = 't2.item_code' + based = 't2.item_code' elif based_on == "Item Group": bon = ["Item Group:Link/Item Group:120"] query_details = "t2.item_group," - basedon = 't2.item_group' + based = 't2.item_group' elif based_on == "Customer": bon = ["Customer:Link/Customer:120", "Territory:Link/Territory:120"] query_details = "t1.customer_name, t1.territory, " - basedon = 't1.customer_name' + based = 't1.customer_name' elif based_on == "Customer Group": bon = ["Customer Group:Link/Customer Group"] query_details = "t1.customer_group," - basedon = 't1.customer_group' + based = 't1.customer_group' elif based_on == 'Supplier': bon = ["Supplier:Link/Supplier:120", "Supplier Type:Link/Supplier Type:120"] query_details = "t1.supplier, t3.supplier_type," - basedon = 't1.supplier' + based = 't1.supplier' sup_tab = '`tabSupplier` t3', elif based_on == 'Supplier Type': bon = ["Supplier Type:Link/Supplier Type:120"] query_details = "t3.supplier_type," - basedon = 't3.supplier_type' + based = 't3.supplier_type' sup_tab ='`tabSupplier` t3', elif based_on == "Territory": bon = ["Territory:Link/Territory:120"] query_details = "t1.territory," - basedon = 't1.territory' + based = 't1.territory' elif based_on == "Project": if trans in ['Sales Invoice', 'Delivery Note', 'Sales Order']: bon = ["Project:Link/Project:120"] query_details = "t1.project_name," - basedon = 't1.project_name' + based = 't1.project_name' elif trans in ['Purchase Order', 'Purchase Invoice', 'Purchase Receipt']: bon = ["Project:Link/Project:120"] query_details = "t2.project_name," - basedon = 't2.project_name' + based = 't2.project_name' else: webnotes.msgprint("Information Not Available", raise_exception=1) - return bon, query_details, basedon, sup_tab + return bon, query_details, based, sup_tab def group_wise_column(group_by): if group_by: From 21f7623d2ec814f052a2d17226389b5b98288d9c Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 19 Jun 2013 14:13:01 +0530 Subject: [PATCH 14/21] [fix][report] in item prices --- stock/report/item_prices/item_prices.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/stock/report/item_prices/item_prices.py b/stock/report/item_prices/item_prices.py index ea0be477df..86ae085ce7 100644 --- a/stock/report/item_prices/item_prices.py +++ b/stock/report/item_prices/item_prices.py @@ -69,10 +69,11 @@ def get_price_list(): from `tabItem Price` where docstatus<2""", as_dict=1) for j in price_list: - if j.selling: - rate.setdefault(j.parent, {}).setdefault("selling", []).append(j.price) - if j.buying: - rate.setdefault(j.parent, {}).setdefault("buying", []).append(j.price) + if j.price: + if j.selling: + rate.setdefault(j.parent, {}).setdefault("selling", []).append(j.price) + if j.buying: + rate.setdefault(j.parent, {}).setdefault("buying", []).append(j.price) item_rate_map = {} From d4f2199269740cc62775b781478172ed13fdf334 Mon Sep 17 00:00:00 2001 From: Saurabh Date: Wed, 19 Jun 2013 14:44:44 +0530 Subject: [PATCH 15/21] [Reports][Trend Analyzer completed] --- controllers/trends.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/controllers/trends.py b/controllers/trends.py index 76db44705f..4edb7845ce 100644 --- a/controllers/trends.py +++ b/controllers/trends.py @@ -17,6 +17,7 @@ from __future__ import unicode_literals import webnotes from webnotes.utils import cint, add_days, add_months, cstr +from datetime import datetime def get_columns(filters, trans): @@ -117,7 +118,12 @@ def get_data(filters, tab, details): return data +def get_mon(date): + """convert srting formated date into date and retrieve month abbrevation""" + return (datetime.strptime(date, '%Y-%m-%d')).strftime("%b") + def period_wise_colums_query(filters, trans): + from datetime import datetime query_details = '' pwc = [] @@ -154,12 +160,15 @@ def period_wise_colums_query(filters, trans): """%{"trans": trans_date, "mon_num": cstr(month+1)} elif filters.get("period") == "Quarterly": - pwc = ["Q1 (Qty):Float:120", "Q1 (Amt):Currency:120", "Q2 (Qty):Float:120", "Q2 (Amt):Currency:120", - "Q3 (Qty):Float:120", "Q3 (Amt):Currency:120", "Q4 (Qty):Float:120", "Q4 (Amt):Currency:120"] first_qsd, second_qsd, third_qsd, fourth_qsd = year_start_date, add_months(year_start_date,3), add_months(year_start_date,6), add_months(year_start_date,9) first_qed, second_qed, third_qed, fourth_qed = add_days(add_months(first_qsd,3),-1), add_days(add_months(second_qsd,3),-1), add_days(add_months(third_qsd,3),-1), add_days(add_months(fourth_qsd,3),-1) bet_dates = [[first_qsd,first_qed],[second_qsd,second_qed],[third_qsd,third_qed],[fourth_qsd,fourth_qed]] + + pwc = [get_mon(first_qsd)+"-"+get_mon(first_qed)+" (Qty):Float:120", get_mon(first_qsd)+"-"+get_mon(first_qed)+"(Amt):Currency:120", + get_mon(second_qsd)+"-"+get_mon(second_qed)+" (Qty):Float:120", get_mon(second_qsd)+"-"+get_mon(second_qed)+" (Amt):Currency:120", + get_mon(third_qsd)+"-"+get_mon(third_qed)+" (Qty):Float:120", get_mon(third_qsd)+"-"+get_mon(third_qed)+" (Amt):Currency:120", + get_mon(fourth_qsd)+"-"+get_mon(fourth_qed)+" (Qty):Float:120", get_mon(fourth_qsd)+"-"+get_mon(fourth_qed)+" (Amt):Currency:120"] for d in bet_dates: query_details += """ @@ -168,14 +177,15 @@ def period_wise_colums_query(filters, trans): """%{"trans": trans_date, "sd": d[0],"ed": d[1]} elif filters.get("period") == "Half-yearly": - pwc = ["Fisrt Half (Qty):Float:120", "Fisrt Half (Amt):Currency:120", "Second Half (Qty):Float:120", - "Second Half (Amt):Currency:120"] first_half_start = year_start_date first_half_end = add_days(add_months(first_half_start,6),-1) second_half_start = add_days(first_half_end,1) second_half_end = add_days(add_months(second_half_start,6),-1) + pwc = [get_mon(first_half_start)+"-"+get_mon(first_half_end)+"(Qty):Float:120", get_mon(first_half_start)+"-"+get_mon(first_half_end)+" (Amt):Currency:120", + get_mon(second_half_start)+"-"+get_mon(second_half_end)+" (Qty):Float:120", get_mon(second_half_start)+"-"+get_mon(second_half_end)+" (Amt):Currency:120"] + query_details = """ SUM(IF(t1.%(trans)s BETWEEN '%(fhs)s' AND '%(fhe)s', t2.qty, NULL)), SUM(IF(t1.%(trans)s BETWEEN '%(fhs)s' AND '%(fhe)s', t1.grand_total, NULL)), From bc2d9e89a78ccd38f0bc067ccbadcf3b181d429e Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 19 Jun 2013 14:58:01 +0530 Subject: [PATCH 16/21] [validation][buying] stock and non-stock items are now allowed in same document --- controllers/buying_controller.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/controllers/buying_controller.py b/controllers/buying_controller.py index 3deda0284b..f02e8482f4 100644 --- a/controllers/buying_controller.py +++ b/controllers/buying_controller.py @@ -54,16 +54,7 @@ class BuyingController(StockController): raise_exception=WrongWarehouseCompany) def validate_stock_or_nonstock_items(self): - items = [d.item_code for d in self.doclist.get({"parentfield": self.fname})] - if self.stock_items: - nonstock_items = list(set(items) - set(self.stock_items)) - if nonstock_items: - webnotes.msgprint(_("Stock and non-stock items can not be entered in the same ") + - self.doc.doctype + _(""". You should make separate documents for them. - Stock Items: """) + ", ".join(self.stock_items) + _(""" - Non-stock Items: """) + ", ".join(nonstock_items), raise_exception=1) - - elif items and not self.stock_items: + if not self.stock_items: tax_for_valuation = [d.account_head for d in self.doclist.get({"parentfield": "purchase_tax_details"}) if d.category in ["Valuation", "Valuation and Total"]] From 92571c692939c17537cdb27bedea89343a038fb1 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Wed, 19 Jun 2013 18:15:20 +0530 Subject: [PATCH 17/21] [Report] Completed Budget variance Report and corrections in Territory Target Varinace & Sales Person Target Variance Report --- .../budget_variance_report.py | 128 ++++++++---------- .../item_wise_purchase_register.py | 1 - ...erson_target_variance_(item_group_wise).py | 31 ++--- ...itory_target_variance_(item_group_wise).py | 30 ++-- 4 files changed, 85 insertions(+), 105 deletions(-) diff --git a/accounts/report/budget_variance_report/budget_variance_report.py b/accounts/report/budget_variance_report/budget_variance_report.py index ac38d9f34d..99e303bd20 100644 --- a/accounts/report/budget_variance_report/budget_variance_report.py +++ b/accounts/report/budget_variance_report/budget_variance_report.py @@ -26,27 +26,27 @@ def execute(filters=None): columns = get_columns(filters) period_month_ranges = get_period_month_ranges(filters) - # tim_map = get_territory_item_month_map(filters) + cam_map = get_costcenter_account_month_map(filters) data = [] - # for territory, territory_items in tim_map.items(): - # for item_group, monthwise_data in territory_items.items(): - # row = [territory, item_group] - # totals = [0, 0, 0] - # for relevant_months in period_month_ranges: - # period_data = [0, 0, 0] - # for month in relevant_months: - # month_data = monthwise_data.get(month, {}) - # for i, fieldname in enumerate(["target", "achieved", "variance"]): - # value = flt(month_data.get(fieldname)) - # period_data[i] += value - # totals[i] += value - # period_data[2] = period_data[0] - period_data[1] - # row += period_data - # totals[2] = totals[0] - totals[1] - # row += totals - # data.append(row) + for cost_center, cost_center_items in cam_map.items(): + for account, monthwise_data in cost_center_items.items(): + row = [cost_center, account] + totals = [0, 0, 0] + for relevant_months in period_month_ranges: + period_data = [0, 0, 0] + for month in relevant_months: + month_data = monthwise_data.get(month, {}) + for i, fieldname in enumerate(["target", "actual", "variance"]): + value = flt(month_data.get(fieldname)) + period_data[i] += value + totals[i] += value + period_data[2] = period_data[0] - period_data[1] + row += period_data + totals[2] = totals[0] - totals[1] + row += totals + data.append(row) return columns, sorted(data, key=lambda x: (x[0], x[1])) @@ -57,7 +57,7 @@ def get_columns(filters): msgprint(_("Please specify") + ": " + label, raise_exception=True) - columns = ["Cost Center:Link/Cost Center:80"] + columns = ["Cost Center:Link/Cost Center:100", "Account:Link/Account:100"] group_months = False if filters["period"] == "Monthly" else True @@ -105,80 +105,64 @@ def get_period_month_ranges(filters): return period_month_ranges -#Get cost center details -def get_costcenter_details(filters): - return webnotes.conn.sql("""select t.name, td.item_group, td.target_qty, - td.target_amount, t.distribution_id - from `tabTerritory` t, `tabTarget Detail` td - where td.parent=t.name and td.fiscal_year=%s and - ifnull(t.distribution_id, '')!='' order by t.name""" % - ('%s'), (filters.get("fiscal_year")), as_dict=1) +#Get cost center & target details +def get_costcenter_target_details(filters): + return webnotes.conn.sql("""select cc.name, cc.distribution_id, + cc.parent_cost_center, bd.account, bd.budget_allocated + from `tabCost Center` cc, `tabBudget Detail` bd + where bd.parent=cc.name and bd.fiscal_year=%s and + cc.company_name=%s and ifnull(cc.distribution_id, '')!='' + order by cc.name""" % ('%s', '%s'), + (filters.get("fiscal_year"), filters.get("company")), as_dict=1) -#Get target distribution details of item group +#Get target distribution details of accounts of cost center def get_target_distribution_details(filters): target_details = {} - abc = [] + for d in webnotes.conn.sql("""select bdd.month, bdd.percentage_allocation \ from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd, \ - `tabTerritory` t where bdd.parent=bd.name and t.distribution_id=bd.name and \ - bd.fiscal_year=%s """ % ('%s'), (filters.get("fiscal_year")), as_dict=1): + `tabCost Center` cc where bdd.parent=bd.name and cc.distribution_id=bd.name and \ + bd.fiscal_year=%s""" % ('%s'), (filters.get("fiscal_year")), as_dict=1): target_details.setdefault(d.month, d) return target_details -#Get achieved details from sales order -def get_achieved_details(filters): - start_date, end_date = get_year_start_end_date(filters) - achieved_details = {} +#Get actual details from gl entry +def get_actual_details(filters): + return webnotes.conn.sql("""select gl.account, gl.debit, gl.credit, + gl.cost_center, MONTHNAME(gl.posting_date) as month_name + from `tabGL Entry` gl, `tabBudget Detail` bd + where gl.fiscal_year=%s and company=%s and is_cancelled='No' + and bd.account=gl.account""" % ('%s', '%s'), + (filters.get("fiscal_year"), filters.get("company")), as_dict=1) - for d in webnotes.conn.sql("""select soi.item_code, soi.qty, soi.amount, so.transaction_date, \ - MONTHNAME(so.transaction_date) as month_name \ - from `tabSales Order Item` soi, `tabSales Order` so \ - where soi.parent=so.name and so.docstatus=1 and so.transaction_date>=%s and \ - so.transaction_date<=%s""" % ('%s', '%s'), \ - (start_date, end_date), as_dict=1): - achieved_details.setdefault(d.month_name, d) - - return achieved_details - -def get_territory_item_month_map(filters): - territory_details = get_territory_details(filters) +def get_costcenter_account_month_map(filters): + costcenter_target_details = get_costcenter_target_details(filters) tdd = get_target_distribution_details(filters) - achieved_details = get_achieved_details(filters) + actual_details = get_actual_details(filters) - tim_map = {} + cam_map = {} - for td in territory_details: + for ccd in costcenter_target_details: for month in tdd: - tim_map.setdefault(td.name, {}).setdefault(td.item_group, {})\ + cam_map.setdefault(ccd.name, {}).setdefault(ccd.account, {})\ .setdefault(month, webnotes._dict({ - "target": 0.0, "achieved": 0.0, "variance": 0.0 + "target": 0.0, "actual": 0.0, "variance": 0.0 })) - tav_dict = tim_map[td.name][td.item_group][month] + tav_dict = cam_map[ccd.name][ccd.account][month] + tav_dict.target = ccd.budget_allocated*(tdd[month]["percentage_allocation"]/100) - for ad in achieved_details: - if (filters["target_on"] == "Quantity"): - tav_dict.target = td.target_qty*(tdd[month]["percentage_allocation"]/100) - if ad == month and ''.join(get_item_group(achieved_details[month]["item_code"])) == td.item_group: - tav_dict.achieved += achieved_details[month]["qty"] - - if (filters["target_on"] == "Amount"): - tav_dict.target = td.target_amount*(tdd[month]["percentage_allocation"]/100) - if ad == month and ''.join(get_item_group(achieved_details[month]["item_code"])) == td.item_group: - tav_dict.achieved += achieved_details[month]["amount"] - - return tim_map + for ad in actual_details: + if ad.month_name == month and ad.account == ccd.account \ + and ad.cost_center == ccd.name: + tav_dict.actual += ad.debit - ad.credit + + return cam_map def get_year_start_end_date(filters): return webnotes.conn.sql("""select year_start_date, subdate(adddate(year_start_date, interval 1 year), interval 1 day) as year_end_date from `tabFiscal Year` - where name=%s""", filters["fiscal_year"])[0] - -def get_item_group(item_name): - """Get Item Group of an item""" - - return webnotes.conn.sql_list("select item_group from `tabItem` where name=%s""" % - ('%s'), (item_name)) \ No newline at end of file + where name=%s""", filters["fiscal_year"])[0] \ No newline at end of file diff --git a/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py index ad9d79504b..f7afb3dfb6 100644 --- a/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py +++ b/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -23,7 +23,6 @@ def execute(filters=None): columns = get_columns() item_list = get_items(filters) aii_account_map = get_aii_accounts() - webnotes.errprint(aii_account_map) data = [] for d in item_list: expense_head = d.expense_head or aii_account_map.get(d.company) diff --git a/selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).py b/selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).py index 3163829131..8f5931d826 100644 --- a/selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).py +++ b/selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).py @@ -117,7 +117,7 @@ def get_salesperson_details(filters): #Get target distribution details of item group def get_target_distribution_details(filters): target_details = {} - abc = [] + for d in webnotes.conn.sql("""select bdd.month, bdd.percentage_allocation \ from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd, \ `tabTerritory` t where bdd.parent=bd.name and t.distribution_id=bd.name and \ @@ -129,17 +129,14 @@ def get_target_distribution_details(filters): #Get achieved details from sales order def get_achieved_details(filters): start_date, end_date = get_year_start_end_date(filters) - achieved_details = {} - - for d in webnotes.conn.sql("""select soi.item_code, soi.qty, soi.amount, so.transaction_date, \ - MONTHNAME(so.transaction_date) as month_name \ - from `tabSales Order Item` soi, `tabSales Order` so \ - where soi.parent=so.name and so.docstatus=1 and so.transaction_date>=%s and \ - so.transaction_date<=%s""" % ('%s', '%s'), \ - (start_date, end_date), as_dict=1): - achieved_details.setdefault(d.month_name, d) - - return achieved_details + + return webnotes.conn.sql("""select soi.item_code, soi.qty, soi.amount, so.transaction_date, + st.sales_person, MONTHNAME(so.transaction_date) as month_name + from `tabSales Order Item` soi, `tabSales Order` so, `tabSales Team` st + where soi.parent=so.name and so.docstatus=1 and + st.parent=so.name and so.transaction_date>=%s and + so.transaction_date<=%s""" % ('%s', '%s'), + (start_date, end_date), as_dict=1) def get_salesperson_item_month_map(filters): salesperson_details = get_salesperson_details(filters) @@ -160,13 +157,15 @@ def get_salesperson_item_month_map(filters): for ad in achieved_details: if (filters["target_on"] == "Quantity"): tav_dict.target = sd.target_qty*(tdd[month]["percentage_allocation"]/100) - if ad == month and ''.join(get_item_group(achieved_details[month]["item_code"])) == sd.item_group: - tav_dict.achieved += achieved_details[month]["qty"] + if ad.month_name == month and ''.join(get_item_group(ad.item_code)) == sd.item_group \ + and ad.sales_person == sd.name: + tav_dict.achieved += ad.qty if (filters["target_on"] == "Amount"): tav_dict.target = sd.target_amount*(tdd[month]["percentage_allocation"]/100) - if ad == month and ''.join(get_item_group(achieved_details[month]["item_code"])) == sd.item_group: - tav_dict.achieved += achieved_details[month]["amount"] + if ad.month_name == month and ''.join(get_item_group(ad.item_code)) == sd.item_group \ + and ad.sales_person == sd.name: + tav_dict.achieved += ad.amount return sim_map diff --git a/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py b/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py index fe5e628c65..079f8e82a2 100644 --- a/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py +++ b/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py @@ -117,11 +117,11 @@ def get_territory_details(filters): #Get target distribution details of item group def get_target_distribution_details(filters): target_details = {} - abc = [] + for d in webnotes.conn.sql("""select bdd.month, bdd.percentage_allocation \ from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd, \ `tabTerritory` t where bdd.parent=bd.name and t.distribution_id=bd.name and \ - bd.fiscal_year=%s """ % ('%s'), (filters.get("fiscal_year")), as_dict=1): + bd.fiscal_year=%s""" % ('%s'), (filters.get("fiscal_year")), as_dict=1): target_details.setdefault(d.month, d) return target_details @@ -129,17 +129,13 @@ def get_target_distribution_details(filters): #Get achieved details from sales order def get_achieved_details(filters): start_date, end_date = get_year_start_end_date(filters) - achieved_details = {} - for d in webnotes.conn.sql("""select soi.item_code, soi.qty, soi.amount, so.transaction_date, \ - MONTHNAME(so.transaction_date) as month_name \ - from `tabSales Order Item` soi, `tabSales Order` so \ - where soi.parent=so.name and so.docstatus=1 and so.transaction_date>=%s and \ - so.transaction_date<=%s""" % ('%s', '%s'), \ - (start_date, end_date), as_dict=1): - achieved_details.setdefault(d.month_name, d) - - return achieved_details + return webnotes.conn.sql("""select soi.item_code, soi.qty, soi.amount, so.transaction_date, + so.territory, MONTHNAME(so.transaction_date) as month_name + from `tabSales Order Item` soi, `tabSales Order` so + where soi.parent=so.name and so.docstatus=1 and so.transaction_date>=%s and + so.transaction_date<=%s""" % ('%s', '%s'), + (start_date, end_date), as_dict=1) def get_territory_item_month_map(filters): territory_details = get_territory_details(filters) @@ -160,13 +156,15 @@ def get_territory_item_month_map(filters): for ad in achieved_details: if (filters["target_on"] == "Quantity"): tav_dict.target = td.target_qty*(tdd[month]["percentage_allocation"]/100) - if ad == month and ''.join(get_item_group(achieved_details[month]["item_code"])) == td.item_group: - tav_dict.achieved += achieved_details[month]["qty"] + if ad.month_name == month and ''.join(get_item_group(ad.item_code)) == td.item_group \ + and ad.territory == td.name: + tav_dict.achieved += ad.qty if (filters["target_on"] == "Amount"): tav_dict.target = td.target_amount*(tdd[month]["percentage_allocation"]/100) - if ad == month and ''.join(get_item_group(achieved_details[month]["item_code"])) == td.item_group: - tav_dict.achieved += achieved_details[month]["amount"] + if ad.month_name == month and ''.join(get_item_group(ad.item_code)) == td.item_group \ + and ad.territory == td.name: + tav_dict.achieved += ad.amount return tim_map From b8ebbcafa997de794ac296d4130e26f8207c59ff Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 20 Jun 2013 13:03:10 +0530 Subject: [PATCH 18/21] [trend analyzer] cleanup --- controllers/trends.py | 105 ++++++++-------- .../quotation_trends/quotation_trends.py | 5 +- stock/doctype/serial_no/serial_no.txt | 116 ++++++++---------- 3 files changed, 100 insertions(+), 126 deletions(-) diff --git a/controllers/trends.py b/controllers/trends.py index 4edb7845ce..c0636cba45 100644 --- a/controllers/trends.py +++ b/controllers/trends.py @@ -16,33 +16,39 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import cint, add_days, add_months, cstr -from datetime import datetime +from webnotes.utils import add_days, add_months, cstr, getdate +from webnotes import _ def get_columns(filters, trans): + validate_filters(filters) + + # based_on_cols, based_on_select, based_on_group_by, addl_tables + bonc, query_bon, based, sup_tab = basedon_wise_colums_query(filters.get("based_on"), trans) + # period_cols, period_select + pwc, query_pwc = period_wise_colums_query(filters, trans) + + # group_by_cols + grbc = group_wise_column(filters.get("group_by")) - if not (filters.get("period") and filters.get("based_on")): - webnotes.msgprint("Value missing in 'Period' or 'Based On'", raise_exception=1) + columns = bonc + pwc + ["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] + if grbc: + columns = bonc + grbc + pwc +["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] - elif filters.get("based_on") == filters.get("group_by"): - webnotes.msgprint("Plese select different values in 'Based On' and 'Group By'", raise_exception=1) - - else: - bonc, query_bon, based, sup_tab = basedon_wise_colums_query(filters.get("based_on"), trans) - pwc, query_pwc = period_wise_colums_query(filters, trans) - grbc = group_wise_column(filters.get("group_by")) - - columns = bonc + pwc + ["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] - if grbc: - columns = bonc + grbc + pwc +["TOTAL(Qty):Float:120", "TOTAL(Amt):Currency:120"] - - details = {"query_bon": query_bon, "query_pwc": query_pwc, "columns": columns, "basedon": based, - "grbc": grbc, "sup_tab": sup_tab} + # conditions + details = {"query_bon": query_bon, "query_pwc": query_pwc, "columns": columns, + "basedon": based, "grbc": grbc, "sup_tab": sup_tab} return details -def get_data(filters, tab, details): +def validate_filters(filters): + for f in ["Fiscal Year", "Based On", "Period", "Company"]: + if not filters.get(f.lower().replace(" ", "_")): + webnotes.msgprint(f + _(" is mandatory"), raise_exception=1) + if filters.get("based_on") == filters.get("group_by"): + webnotes.msgprint("'Based On' and 'Group By' can not be same", raise_exception=1) + +def get_data(filters, tab, details): data = [] inc, cond= '','' query_details = details["query_bon"] + details["query_pwc"] @@ -96,17 +102,17 @@ def get_data(filters, tab, details): row1 = webnotes.conn.sql(""" select %s , %s from `%s` t1, `%s` t2 %s where t2.parent = t1.name and t1.company = %s and t1.fiscal_year = %s and t1.docstatus = 1 and %s = %s and %s = %s - """%(sel_col, details["query_pwc"], tab[0], tab[1], details["sup_tab"], + """ % (sel_col, details["query_pwc"], tab[0], tab[1], details["sup_tab"], "%s", "%s", sel_col, "%s", details["basedon"], "%s"), - (filters.get("company"), filters.get("fiscal_year"), row[i][0], data1[d][0]), - as_list=1) + (filters.get("company"), filters.get("fiscal_year"), + row[i][0], data1[d][0]), as_list=1) des[ind] = row[i] for j in range(1,len(details["columns"])-inc): des[j+inc] = row1[0][j] + data.append(des) else: - data = webnotes.conn.sql(""" select %s from `%s` t1, `%s` t2 %s where t2.parent = t1.name and t1.company = %s and t1.fiscal_year = %s and t1.docstatus = 1 %s @@ -118,20 +124,13 @@ def get_data(filters, tab, details): return data -def get_mon(date): - """convert srting formated date into date and retrieve month abbrevation""" - return (datetime.strptime(date, '%Y-%m-%d')).strftime("%b") +def get_mon(dt): + return getdate(dt).strftime("%b") def period_wise_colums_query(filters, trans): - from datetime import datetime - query_details = '' pwc = [] - ysd = webnotes.conn.sql("""select year_start_date from `tabFiscal Year` where name = '%s' - """%filters.get("fiscal_year"))[0][0] - - year_start_date = ysd.strftime('%Y-%m-%d') - start_month = cint(year_start_date.split('-')[1]) + ysd = webnotes.conn.get_value("Fiscal year", filters.get("fiscal_year"), "year_start_date") if trans in ['Purchase Receipt', 'Delivery Note', 'Purchase Invoice', 'Sales Invoice']: trans_date = 'posting_date' @@ -141,27 +140,13 @@ def period_wise_colums_query(filters, trans): if filters.get("period") == "Monthly": month_name = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] - for month in range(start_month-1,len(month_name)): - pwc.append(month_name[month]+' (Qty):Float:120') - pwc.append(month_name[month]+' (Amt):Currency:120') - - query_details += """ - Sum(IF(MONTH(t1.%(trans)s)= %(mon_num)s, t2.qty, NULL)), - SUM(IF(MONTH(t1.%(trans)s)= %(mon_num)s, t1.grand_total, NULL)), - """%{"trans": trans_date,"mon_num": cstr(month+1)} - - for month in range(0, start_month-1): - pwc.append(month_name[month]+' (Qty):Float:120') - pwc.append(month_name[month]+' (Amt):Currency:120') - - query_details += """ - Sum(IF(MONTH(t1.%(trans)s)= %(mon_num)s, t2.qty, NULL)), - SUM(IF(MONTH(t1.%(trans)s)= %(mon_num)s, t1.grand_total, NULL)), - """%{"trans": trans_date, "mon_num": cstr(month+1)} + for month_idx in range(ysd.month-1,len(month_name)) + range(0, ysd.month-1): + query_details = get_monthly_conditions(month_name, month_idx, trans_date, + pwc, query_details) elif filters.get("period") == "Quarterly": - first_qsd, second_qsd, third_qsd, fourth_qsd = year_start_date, add_months(year_start_date,3), add_months(year_start_date,6), add_months(year_start_date,9) + first_qsd, second_qsd, third_qsd, fourth_qsd = ysd, add_months(ysd,3), add_months(ysd,6), add_months(ysd,9) first_qed, second_qed, third_qed, fourth_qed = add_days(add_months(first_qsd,3),-1), add_days(add_months(second_qsd,3),-1), add_days(add_months(third_qsd,3),-1), add_days(add_months(fourth_qsd,3),-1) bet_dates = [[first_qsd,first_qed],[second_qsd,second_qed],[third_qsd,third_qed],[fourth_qsd,fourth_qed]] @@ -178,7 +163,7 @@ def period_wise_colums_query(filters, trans): elif filters.get("period") == "Half-yearly": - first_half_start = year_start_date + first_half_start = ysd first_half_end = add_days(add_months(first_half_start,6),-1) second_half_start = add_days(first_half_end,1) second_half_end = add_days(add_months(second_half_start,6),-1) @@ -200,6 +185,17 @@ def period_wise_colums_query(filters, trans): query_details += 'SUM(t2.qty), SUM(t1.grand_total)' return pwc, query_details + +def get_monthly_conditions(month_list, month_idx, trans_date, pwc, query_details): + pwc += [month_list[month_idx] + ' (Qty):Float:120', + month_list[month_idx] + ' (Amt):Currency:120'] + + query_details += """ + Sum(IF(MONTH(t1.%(trans_date)s)= %(mon_num)s, t2.qty, NULL)), + SUM(IF(MONTH(t1.%(trans_date)s)= %(mon_num)s, t1.grand_total, NULL)), + """ % {"trans_date": trans_date, "mon_num": cstr(month_idx+1)} + + return query_details def basedon_wise_colums_query(based_on, trans): sup_tab = '' @@ -242,19 +238,16 @@ def basedon_wise_colums_query(based_on, trans): based = 't1.territory' elif based_on == "Project": - if trans in ['Sales Invoice', 'Delivery Note', 'Sales Order']: bon = ["Project:Link/Project:120"] query_details = "t1.project_name," based = 't1.project_name' - elif trans in ['Purchase Order', 'Purchase Invoice', 'Purchase Receipt']: bon = ["Project:Link/Project:120"] query_details = "t2.project_name," based = 't2.project_name' - else: - webnotes.msgprint("Information Not Available", raise_exception=1) + webnotes.msgprint("Project-wise data is not available for Quotation", raise_exception=1) return bon, query_details, based, sup_tab diff --git a/selling/report/quotation_trends/quotation_trends.py b/selling/report/quotation_trends/quotation_trends.py index e341752cd0..c6a54c7588 100644 --- a/selling/report/quotation_trends/quotation_trends.py +++ b/selling/report/quotation_trends/quotation_trends.py @@ -16,7 +16,7 @@ from __future__ import unicode_literals import webnotes -from controllers.trends import get_columns,get_data +from controllers.trends import get_columns, get_data def execute(filters=None): if not filters: filters ={} @@ -27,8 +27,5 @@ def execute(filters=None): details = get_columns(filters, trans) data = get_data(filters, tab, details) - - if not data: - webnotes.msgprint("Data not found for selected criterias") return details["columns"], data \ No newline at end of file diff --git a/stock/doctype/serial_no/serial_no.txt b/stock/doctype/serial_no/serial_no.txt index 8e891b8172..33160c785f 100644 --- a/stock/doctype/serial_no/serial_no.txt +++ b/stock/doctype/serial_no/serial_no.txt @@ -1,14 +1,14 @@ [ { - "creation": "2013-01-29 19:25:41", + "creation": "2013-05-16 10:59:15", "docstatus": 0, - "modified": "2013-01-29 16:27:57", + "modified": "2013-06-20 11:23:01", "modified_by": "Administrator", "owner": "Administrator" }, { "allow_attach": 1, - "allow_rename": 1, + "allow_rename": 0, "autoname": "field:serial_no", "description": "Distinct unit of an Item", "doctype": "DocType", @@ -31,7 +31,9 @@ "parent": "Serial No", "parentfield": "permissions", "parenttype": "DocType", + "permlevel": 0, "read": 1, + "report": 1, "submit": 0 }, { @@ -43,12 +45,14 @@ "fieldname": "details", "fieldtype": "Section Break", "label": "Details", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "column_break0", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "read_only": 0 }, { "default": "In Store", @@ -75,6 +79,7 @@ "no_copy": 1, "oldfieldname": "serial_no", "oldfieldtype": "Data", + "read_only": 0, "reqd": 1, "search_index": 1 }, @@ -88,13 +93,15 @@ "oldfieldname": "item_code", "oldfieldtype": "Link", "options": "Item", + "read_only": 0, "reqd": 1, "search_index": 0 }, { "doctype": "DocField", "fieldname": "column_break1", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "read_only": 0 }, { "doctype": "DocField", @@ -146,12 +153,14 @@ "doctype": "DocField", "fieldname": "purchase_details", "fieldtype": "Section Break", - "label": "Purchase Details" + "label": "Purchase Details", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "column_break2", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -160,7 +169,8 @@ "fieldtype": "Select", "label": "Purchase Document Type", "no_copy": 1, - "options": "\nPurchase Receipt\nStock Entry" + "options": "\nPurchase Receipt\nStock Entry", + "read_only": 0 }, { "doctype": "DocField", @@ -168,7 +178,8 @@ "fieldtype": "Data", "hidden": 0, "label": "Purchase Document No", - "no_copy": 1 + "no_copy": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -179,6 +190,7 @@ "no_copy": 1, "oldfieldname": "purchase_date", "oldfieldtype": "Date", + "read_only": 0, "reqd": 0, "search_index": 0 }, @@ -188,6 +200,7 @@ "fieldtype": "Time", "label": "Incoming Time", "no_copy": 1, + "read_only": 0, "reqd": 1 }, { @@ -200,6 +213,7 @@ "oldfieldname": "purchase_rate", "oldfieldtype": "Currency", "options": "Company:company:default_currency", + "read_only": 0, "reqd": 1, "search_index": 0 }, @@ -207,6 +221,7 @@ "doctype": "DocField", "fieldname": "column_break3", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -220,6 +235,7 @@ "oldfieldname": "warehouse", "oldfieldtype": "Link", "options": "Warehouse", + "read_only": 0, "reqd": 0, "search_index": 1 }, @@ -230,7 +246,8 @@ "in_filter": 1, "label": "Supplier", "no_copy": 1, - "options": "Supplier" + "options": "Supplier", + "read_only": 0 }, { "doctype": "DocField", @@ -254,12 +271,14 @@ "fieldname": "delivery_details", "fieldtype": "Section Break", "label": "Delivery Details", - "oldfieldtype": "Column Break" + "oldfieldtype": "Column Break", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "column_break4", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -318,12 +337,14 @@ "oldfieldname": "is_cancelled", "oldfieldtype": "Select", "options": "\nYes\nNo", + "read_only": 0, "report_hide": 1 }, { "doctype": "DocField", "fieldname": "column_break5", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -378,12 +399,14 @@ "doctype": "DocField", "fieldname": "warranty_amc_details", "fieldtype": "Section Break", - "label": "Warranty / AMC Details" + "label": "Warranty / AMC Details", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "column_break6", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -396,6 +419,7 @@ "oldfieldname": "maintenance_status", "oldfieldtype": "Select", "options": "\nUnder Warranty\nOut of Warranty\nUnder AMC\nOut of AMC", + "read_only": 0, "search_index": 1, "width": "150px" }, @@ -406,12 +430,14 @@ "label": "Warranty Period (Days)", "oldfieldname": "warranty_period", "oldfieldtype": "Int", + "read_only": 0, "width": "150px" }, { "doctype": "DocField", "fieldname": "column_break7", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -422,6 +448,7 @@ "label": "Warranty Expiry Date", "oldfieldname": "warranty_expiry_date", "oldfieldtype": "Date", + "read_only": 0, "width": "150px" }, { @@ -432,6 +459,7 @@ "label": "AMC Expiry Date", "oldfieldname": "amc_expiry_date", "oldfieldtype": "Date", + "read_only": 0, "search_index": 0, "width": "150px" }, @@ -439,13 +467,15 @@ "doctype": "DocField", "fieldname": "more_info", "fieldtype": "Section Break", - "label": "More Info" + "label": "More Info", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "serial_no_details", "fieldtype": "Text Editor", - "label": "Serial No Details" + "label": "Serial No Details", + "read_only": 0 }, { "doctype": "DocField", @@ -454,6 +484,7 @@ "in_filter": 1, "label": "Company", "options": "link:Company", + "read_only": 0, "reqd": 1, "search_index": 1 }, @@ -464,6 +495,7 @@ "in_filter": 1, "label": "Fiscal Year", "options": "link:Fiscal Year", + "read_only": 0, "reqd": 1, "search_index": 1 }, @@ -487,54 +519,10 @@ "read_only": 1, "report_hide": 1 }, - { - "amend": 0, - "cancel": 0, - "create": 0, - "doctype": "DocPerm", - "match": "", - "permlevel": 1, - "report": 0, - "role": "Material Manager", - "write": 0 - }, - { - "amend": 0, - "cancel": 0, - "create": 0, - "doctype": "DocPerm", - "permlevel": 0, - "report": 1, - "role": "Material Manager", - "write": 0 - }, - { - "amend": 0, - "cancel": 0, - "create": 0, - "doctype": "DocPerm", - "match": "", - "permlevel": 1, - "report": 0, - "role": "Material User", - "write": 0 - }, - { - "amend": 0, - "cancel": 0, - "create": 0, - "doctype": "DocPerm", - "permlevel": 0, - "report": 1, - "role": "Material User", - "write": 0 - }, { "cancel": 1, "create": 1, "doctype": "DocPerm", - "permlevel": 0, - "report": 1, "role": "System Manager", "write": 1 }, @@ -542,8 +530,6 @@ "cancel": 1, "create": 1, "doctype": "DocPerm", - "permlevel": 0, - "report": 1, "role": "Material Master Manager", "write": 1 }, @@ -552,17 +538,15 @@ "cancel": 0, "create": 0, "doctype": "DocPerm", - "match": "", - "permlevel": 1, - "role": "System Manager" + "role": "Material Manager", + "write": 0 }, { "amend": 0, "cancel": 0, "create": 0, "doctype": "DocPerm", - "match": "", - "permlevel": 1, - "role": "Sales Master Manager" + "role": "Material User", + "write": 0 } ] \ No newline at end of file From 0930b94264bc09adc3fd269e1ae083991f263e82 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 20 Jun 2013 16:35:09 +0530 Subject: [PATCH 19/21] [target report] cleanup --- accounts/utils.py | 16 +++++--- ...itory_target_variance_(item_group_wise).py | 37 +++++++------------ 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/accounts/utils.py b/accounts/utils.py index eb240e796c..fa93cb0628 100644 --- a/accounts/utils.py +++ b/accounts/utils.py @@ -26,17 +26,23 @@ from utilities import build_filter_conditions class FiscalYearError(webnotes.ValidationError): pass -def get_fiscal_year(date, verbose=1): - return get_fiscal_years(date, verbose=1)[0] +def get_fiscal_year(date=None, fiscal_year=None, verbose=1): + return get_fiscal_years(date, fiscal_year, verbose=1)[0] -def get_fiscal_years(date, verbose=1): +def get_fiscal_years(date=None, fiscal_year=None, verbose=1): # if year start date is 2012-04-01, year end date should be 2013-03-31 (hence subdate) + cond = "" + if fiscal_year: + cond = "name = '%s'" % fiscal_year + else: + cond = "'%s' >= year_start_date and '%s' < adddate(year_start_date, interval 1 year)" % \ + (date, date) fy = webnotes.conn.sql("""select name, year_start_date, subdate(adddate(year_start_date, interval 1 year), interval 1 day) as year_end_date from `tabFiscal Year` - where %s >= year_start_date and %s < adddate(year_start_date, interval 1 year) - order by year_start_date desc""", (date, date)) + where %s + order by year_start_date desc""" % cond) if not fy: error_msg = """%s not in any Fiscal Year""" % formatdate(date) diff --git a/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py b/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py index 079f8e82a2..022d19ecf6 100644 --- a/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py +++ b/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py @@ -20,6 +20,7 @@ import calendar from webnotes import _, msgprint from webnotes.utils import flt import time +from accounts.utils import get_fiscal_year def execute(filters=None): if not filters: filters = {} @@ -54,8 +55,7 @@ def get_columns(filters): for fieldname in ["fiscal_year", "period", "target_on"]: if not filters.get(fieldname): label = (" ".join(fieldname.split("_"))).title() - msgprint(_("Please specify") + ": " + label, - raise_exception=True) + msgprint(_("Please specify") + ": " + label, raise_exception=True) columns = ["Territory:Link/Territory:80", "Item Group:Link/Item Group:80"] @@ -72,8 +72,8 @@ def get_columns(filters): def get_period_date_ranges(filters): from dateutil.relativedelta import relativedelta - - year_start_date, year_end_date = get_year_start_end_date(filters) + year_start_date, year_end_date = get_fiscal_year(fiscal_year = filters["fiscal_year"])[1:] + increment = { "Monthly": 1, @@ -111,8 +111,8 @@ def get_territory_details(filters): td.target_amount, t.distribution_id from `tabTerritory` t, `tabTarget Detail` td where td.parent=t.name and td.fiscal_year=%s and - ifnull(t.distribution_id, '')!='' order by t.name""" % - ('%s'), (filters.get("fiscal_year")), as_dict=1) + ifnull(t.distribution_id, '')!='' order by t.name""", + filters.get("fiscal_year"), as_dict=1) #Get target distribution details of item group def get_target_distribution_details(filters): @@ -128,7 +128,7 @@ def get_target_distribution_details(filters): #Get achieved details from sales order def get_achieved_details(filters): - start_date, end_date = get_year_start_end_date(filters) + start_date, end_date = get_fiscal_year(fiscal_year = filters["fiscal_year"])[1:] return webnotes.conn.sql("""select soi.item_code, soi.qty, soi.amount, so.transaction_date, so.territory, MONTHNAME(so.transaction_date) as month_name @@ -148,35 +148,26 @@ def get_territory_item_month_map(filters): for month in tdd: tim_map.setdefault(td.name, {}).setdefault(td.item_group, {})\ .setdefault(month, webnotes._dict({ - "target": 0.0, "achieved": 0.0, "variance": 0.0 + "target": 0.0, "achieved": 0.0 })) tav_dict = tim_map[td.name][td.item_group][month] for ad in achieved_details: if (filters["target_on"] == "Quantity"): - tav_dict.target = td.target_qty*(tdd[month]["percentage_allocation"]/100) - if ad.month_name == month and ''.join(get_item_group(ad.item_code)) == td.item_group \ + tav_dict.target = flt(td.target_qty) * (tdd[month]["percentage_allocation"]/100) + if ad.month_name == month and get_item_group(ad.item_code) == td.item_group \ and ad.territory == td.name: tav_dict.achieved += ad.qty if (filters["target_on"] == "Amount"): - tav_dict.target = td.target_amount*(tdd[month]["percentage_allocation"]/100) - if ad.month_name == month and ''.join(get_item_group(ad.item_code)) == td.item_group \ + tav_dict.target = flt(td.target_amount) * \ + (tdd[month]["percentage_allocation"]/100) + if ad.month_name == month and get_item_group(ad.item_code) == td.item_group \ and ad.territory == td.name: tav_dict.achieved += ad.amount return tim_map -def get_year_start_end_date(filters): - return webnotes.conn.sql("""select year_start_date, - subdate(adddate(year_start_date, interval 1 year), interval 1 day) - as year_end_date - from `tabFiscal Year` - where name=%s""", filters["fiscal_year"])[0] - def get_item_group(item_name): - """Get Item Group of an item""" - - return webnotes.conn.sql_list("select item_group from `tabItem` where name=%s""" % - ('%s'), (item_name)) \ No newline at end of file + return webnotes.conn.get_value("Item", item_name, "item_group") \ No newline at end of file From b7784eac365876dff9c93f95b6b761dd8826a99c Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 20 Jun 2013 17:19:51 +0530 Subject: [PATCH 20/21] [fix][report] in item prices --- stock/report/item_prices/item_prices.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock/report/item_prices/item_prices.py b/stock/report/item_prices/item_prices.py index 86ae085ce7..c8d0b69db5 100644 --- a/stock/report/item_prices/item_prices.py +++ b/stock/report/item_prices/item_prices.py @@ -101,7 +101,7 @@ def get_valuation_rate(): val_rate_map = {} for d in webnotes.conn.sql("""select item_code, avg(valuation_rate) as val_rate - from tabBin group by item_code""", as_dict=1): + from tabBin where actual_qty > 0 group by item_code""", as_dict=1): val_rate_map.setdefault(d.item_code, d.val_rate) return val_rate_map \ No newline at end of file From 71253bea0f4bd055605aa88363233c78702abca5 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 20 Jun 2013 17:32:00 +0530 Subject: [PATCH 21/21] [fix][report] in item prices --- stock/report/item_prices/item_prices.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stock/report/item_prices/item_prices.py b/stock/report/item_prices/item_prices.py index c8d0b69db5..3bdb746510 100644 --- a/stock/report/item_prices/item_prices.py +++ b/stock/report/item_prices/item_prices.py @@ -100,7 +100,8 @@ def get_valuation_rate(): val_rate_map = {} - for d in webnotes.conn.sql("""select item_code, avg(valuation_rate) as val_rate + for d in webnotes.conn.sql("""select item_code, + sum(actual_qty*valuation_rate)/sum(actual_qty) as val_rate from tabBin where actual_qty > 0 group by item_code""", as_dict=1): val_rate_map.setdefault(d.item_code, d.val_rate)