diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py index a51a4954c9..acd087768d 100644 --- a/erpnext/projects/doctype/task/task.py +++ b/erpnext/projects/doctype/task/task.py @@ -85,3 +85,12 @@ def get_project(doctype, txt, searchfield, start, page_len, filters): limit %(start)s, %(page_len)s """ % {'key': searchfield, 'txt': "%%%s%%" % txt, 'mcond':get_match_cond(doctype), 'start': start, 'page_len': page_len}) + + +@frappe.whitelist() +def set_multiple_status(names, status): + names = json.loads(names) + for name in names: + task = frappe.get_doc("Task", name) + task.status = status + task.save() diff --git a/erpnext/projects/doctype/task/task_list.js b/erpnext/projects/doctype/task/task_list.js index 4406085e69..9150501c38 100644 --- a/erpnext/projects/doctype/task/task_list.js +++ b/erpnext/projects/doctype/task/task_list.js @@ -1,4 +1,15 @@ frappe.listview_settings['Task'] = { add_fields: ["project", "status", "priority", "exp_end_date"], - filters:[["status","=", "Open"]] + onload: function(listview) { + var method = "erpnext.projects.doctype.task.task.set_multiple_status"; + + listview.page.add_menu_item(__("Set as Open"), function() { + listview.call_for_selected_items(method, {"status": "Open"}); + }); + + listview.page.add_menu_item(__("Set as Closed"), function() { + listview.call_for_selected_items(method, {"status": "Closed"}); + }); + } + }; diff --git a/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py b/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py index 3360ddb563..2b88a508fd 100644 --- a/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py +++ b/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py @@ -18,11 +18,11 @@ def execute(filters=None): company_condition = ' and company=%(company)s' for si in frappe.db.sql("""select posting_date, customer, base_grand_total from `tabSales Invoice` - where docstatus=1 and posting_date <= %(to_date)s - {company_condition} order by posting_date""".format(company_condition=company_condition), + where docstatus=1 and posting_date <= %(to_date)s + {company_condition} order by posting_date""".format(company_condition=company_condition), filters, as_dict=1): - - key = si.posting_date[:7] + + key = si.posting_date.strftime("%Y-%m-%d") if not si.customer in customers: new_customers_in.setdefault(key, [0, 0.0]) new_customers_in[key][0] += 1 @@ -32,14 +32,14 @@ def execute(filters=None): repeat_customers_in.setdefault(key, [0, 0.0]) repeat_customers_in[key][0] += 1 repeat_customers_in[key][1] += si.base_grand_total - + # time series from_year, from_month, temp = filters.get("from_date").split("-") to_year, to_month, temp = filters.get("to_date").split("-") - + from_year, from_month, to_year, to_month = \ cint(from_year), cint(from_month), cint(to_year), cint(to_month) - + out = [] for year in xrange(from_year, to_year+1): for month in xrange(from_month if year==from_year else 1, (to_month+1) if year==to_year else 13): @@ -48,19 +48,18 @@ def execute(filters=None): new = new_customers_in.get(key, [0,0.0]) repeat = repeat_customers_in.get(key, [0,0.0]) - out.append([year, calendar.month_name[month], + out.append([year, calendar.month_name[month], new[0], repeat[0], new[0] + repeat[0], new[1], repeat[1], new[1] + repeat[1]]) - + return [ - _("Year"), _("Month"), - _("New Customers") + ":Int", - _("Repeat Customers") + ":Int", + _("Year"), _("Month"), + _("New Customers") + ":Int", + _("Repeat Customers") + ":Int", _("Total") + ":Int", - _("New Customer Revenue") + ":Currency:150", - _("Repeat Customer Revenue") + ":Currency:150", + _("New Customer Revenue") + ":Currency:150", + _("Repeat Customer Revenue") + ":Currency:150", _("Total Revenue") + ":Currency:150" ], out - - - \ No newline at end of file + +