feat: Issue Analytics Script Report (#23604)
* feat: Issue Analytics Report * feat: add more filters, code clean-up * fix: add report link to desk page * test: Issue Analytics Report * fix: sider issues * fix: test * debug: travis * debug: travis * fix: travis * fix: travis Co-authored-by: Marica <maricadsouza221197@gmail.com> Co-authored-by: Nabin Hait <nabinhait@gmail.com>
This commit is contained in:
parent
c3d82a889a
commit
ea19434af4
@ -28,7 +28,7 @@
|
|||||||
{
|
{
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"label": "Reports",
|
"label": "Reports",
|
||||||
"links": "[\n {\n \"dependencies\": [\n \"Issue\"\n ],\n \"doctype\": \"Issue\",\n \"is_query_report\": true,\n \"label\": \"First Response Time for Issues\",\n \"name\": \"First Response Time for Issues\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Issue\"\n ],\n \"doctype\": \"Issue\",\n \"is_query_report\": true,\n \"label\": \"Issue Summary\",\n \"name\": \"Issue Summary\",\n \"type\": \"report\"\n }\n]"
|
"links": "[\n {\n \"dependencies\": [\n \"Issue\"\n ],\n \"doctype\": \"Issue\",\n \"is_query_report\": true,\n \"label\": \"First Response Time for Issues\",\n \"name\": \"First Response Time for Issues\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Issue\"\n ],\n \"doctype\": \"Issue\",\n \"is_query_report\": true,\n \"label\": \"Issue Analytics\",\n \"name\": \"Issue Analytics\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Issue\"\n ],\n \"doctype\": \"Issue\",\n \"is_query_report\": true,\n \"label\": \"Issue Summary\",\n \"name\": \"Issue Summary\",\n \"type\": \"report\"\n }\n]"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"category": "Modules",
|
"category": "Modules",
|
||||||
@ -43,7 +43,7 @@
|
|||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"label": "Support",
|
"label": "Support",
|
||||||
"modified": "2020-10-12 18:40:22.252915",
|
"modified": "2021-01-13 20:15:03.064256",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Support",
|
"module": "Support",
|
||||||
"name": "Support",
|
"name": "Support",
|
||||||
|
@ -214,7 +214,7 @@ class Issue(Document):
|
|||||||
|
|
||||||
def before_insert(self):
|
def before_insert(self):
|
||||||
if frappe.db.get_single_value("Support Settings", "track_service_level_agreement"):
|
if frappe.db.get_single_value("Support Settings", "track_service_level_agreement"):
|
||||||
self.set_response_and_resolution_time()
|
self.set_response_and_resolution_time(priority=self.priority, service_level_agreement=self.service_level_agreement)
|
||||||
|
|
||||||
def set_response_and_resolution_time(self, priority=None, service_level_agreement=None):
|
def set_response_and_resolution_time(self, priority=None, service_level_agreement=None):
|
||||||
service_level_agreement = get_active_service_level_agreement_for(priority=priority,
|
service_level_agreement = get_active_service_level_agreement_for(priority=priority,
|
||||||
|
@ -135,15 +135,19 @@ class TestIssue(unittest.TestCase):
|
|||||||
self.assertEqual(flt(issue.total_hold_time, 2), 2700)
|
self.assertEqual(flt(issue.total_hold_time, 2), 2700)
|
||||||
|
|
||||||
|
|
||||||
def make_issue(creation=None, customer=None, index=0):
|
def make_issue(creation=None, customer=None, index=0, priority=None, issue_type=None):
|
||||||
issue = frappe.get_doc({
|
issue = frappe.get_doc({
|
||||||
"doctype": "Issue",
|
"doctype": "Issue",
|
||||||
"subject": "Service Level Agreement Issue {0}".format(index),
|
"subject": "Service Level Agreement Issue {0}".format(index),
|
||||||
"customer": customer,
|
"customer": customer,
|
||||||
"raised_by": "test@example.com",
|
"raised_by": "test@example.com",
|
||||||
"description": "Service Level Agreement Issue",
|
"description": "Service Level Agreement Issue",
|
||||||
|
"issue_type": issue_type,
|
||||||
|
"priority": priority,
|
||||||
"creation": creation,
|
"creation": creation,
|
||||||
"service_level_agreement_creation": creation
|
"opening_date": creation,
|
||||||
|
"service_level_agreement_creation": creation,
|
||||||
|
"company": "_Test Company"
|
||||||
}).insert(ignore_permissions=True)
|
}).insert(ignore_permissions=True)
|
||||||
|
|
||||||
return issue
|
return issue
|
||||||
|
0
erpnext/support/report/issue_analytics/__init__.py
Normal file
0
erpnext/support/report/issue_analytics/__init__.py
Normal file
141
erpnext/support/report/issue_analytics/issue_analytics.js
Normal file
141
erpnext/support/report/issue_analytics/issue_analytics.js
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
frappe.query_reports["Issue Analytics"] = {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
fieldname: "company",
|
||||||
|
label: __("Company"),
|
||||||
|
fieldtype: "Link",
|
||||||
|
options: "Company",
|
||||||
|
default: frappe.defaults.get_user_default("Company"),
|
||||||
|
reqd: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "based_on",
|
||||||
|
label: __("Based On"),
|
||||||
|
fieldtype: "Select",
|
||||||
|
options: ["Customer", "Issue Type", "Issue Priority", "Assigned To"],
|
||||||
|
default: "Customer",
|
||||||
|
reqd: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "from_date",
|
||||||
|
label: __("From Date"),
|
||||||
|
fieldtype: "Date",
|
||||||
|
default: frappe.defaults.get_global_default("year_start_date"),
|
||||||
|
reqd: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname:"to_date",
|
||||||
|
label: __("To Date"),
|
||||||
|
fieldtype: "Date",
|
||||||
|
default: frappe.defaults.get_global_default("year_end_date"),
|
||||||
|
reqd: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "range",
|
||||||
|
label: __("Range"),
|
||||||
|
fieldtype: "Select",
|
||||||
|
options: [
|
||||||
|
{ "value": "Weekly", "label": __("Weekly") },
|
||||||
|
{ "value": "Monthly", "label": __("Monthly") },
|
||||||
|
{ "value": "Quarterly", "label": __("Quarterly") },
|
||||||
|
{ "value": "Yearly", "label": __("Yearly") }
|
||||||
|
],
|
||||||
|
default: "Monthly",
|
||||||
|
reqd: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "status",
|
||||||
|
label: __("Status"),
|
||||||
|
fieldtype: "Select",
|
||||||
|
options:[
|
||||||
|
{label: __('Open'), value: 'Open'},
|
||||||
|
{label: __('Replied'), value: 'Replied'},
|
||||||
|
{label: __('Resolved'), value: 'Resolved'},
|
||||||
|
{label: __('Closed'), value: 'Closed'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "priority",
|
||||||
|
label: __("Issue Priority"),
|
||||||
|
fieldtype: "Link",
|
||||||
|
options: "Issue Priority"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "customer",
|
||||||
|
label: __("Customer"),
|
||||||
|
fieldtype: "Link",
|
||||||
|
options: "Customer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "project",
|
||||||
|
label: __("Project"),
|
||||||
|
fieldtype: "Link",
|
||||||
|
options: "Project"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "assigned_to",
|
||||||
|
label: __("Assigned To"),
|
||||||
|
fieldtype: "Link",
|
||||||
|
options: "User"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
after_datatable_render: function(datatable_obj) {
|
||||||
|
$(datatable_obj.wrapper).find(".dt-row-0").find('input[type=checkbox]').click();
|
||||||
|
},
|
||||||
|
get_datatable_options(options) {
|
||||||
|
return Object.assign(options, {
|
||||||
|
checkboxColumn: true,
|
||||||
|
events: {
|
||||||
|
onCheckRow: function(data) {
|
||||||
|
if (data && data.length) {
|
||||||
|
row_name = data[2].content;
|
||||||
|
row_values = data.slice(3).map(function(column) {
|
||||||
|
return column.content;
|
||||||
|
})
|
||||||
|
entry = {
|
||||||
|
'name': row_name,
|
||||||
|
'values': row_values
|
||||||
|
}
|
||||||
|
|
||||||
|
let raw_data = frappe.query_report.chart.data;
|
||||||
|
let new_datasets = raw_data.datasets;
|
||||||
|
|
||||||
|
var found = false;
|
||||||
|
|
||||||
|
for(var i=0; i < new_datasets.length; i++){
|
||||||
|
if (new_datasets[i].name == row_name){
|
||||||
|
found = true;
|
||||||
|
new_datasets.splice(i,1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found){
|
||||||
|
new_datasets.push(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_data = {
|
||||||
|
labels: raw_data.labels,
|
||||||
|
datasets: new_datasets
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
frappe.query_report.chart.update(new_data)
|
||||||
|
},500)
|
||||||
|
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
frappe.query_report.chart.draw(true);
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
|
frappe.query_report.raw_chart_data = new_data;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
26
erpnext/support/report/issue_analytics/issue_analytics.json
Normal file
26
erpnext/support/report/issue_analytics/issue_analytics.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"add_total_row": 1,
|
||||||
|
"columns": [],
|
||||||
|
"creation": "2020-10-09 19:52:10.227317",
|
||||||
|
"disable_prepared_report": 0,
|
||||||
|
"disabled": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Report",
|
||||||
|
"filters": [],
|
||||||
|
"idx": 0,
|
||||||
|
"is_standard": "Yes",
|
||||||
|
"modified": "2020-10-11 19:43:19.358625",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Support",
|
||||||
|
"name": "Issue Analytics",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"prepared_report": 0,
|
||||||
|
"ref_doctype": "Issue",
|
||||||
|
"report_name": "Issue Analytics",
|
||||||
|
"report_type": "Script Report",
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"role": "Support Team"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
222
erpnext/support/report/issue_analytics/issue_analytics.py
Normal file
222
erpnext/support/report/issue_analytics/issue_analytics.py
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
import json
|
||||||
|
from six import iteritems
|
||||||
|
from frappe import _, scrub
|
||||||
|
from frappe.utils import getdate, flt, add_to_date, add_days
|
||||||
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
|
|
||||||
|
def execute(filters=None):
|
||||||
|
return IssueAnalytics(filters).run()
|
||||||
|
|
||||||
|
class IssueAnalytics(object):
|
||||||
|
def __init__(self, filters=None):
|
||||||
|
"""Issue Analytics Report"""
|
||||||
|
self.filters = frappe._dict(filters or {})
|
||||||
|
self.get_period_date_ranges()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.get_columns()
|
||||||
|
self.get_data()
|
||||||
|
self.get_chart_data()
|
||||||
|
|
||||||
|
return self.columns, self.data, None, self.chart
|
||||||
|
|
||||||
|
def get_columns(self):
|
||||||
|
self.columns = []
|
||||||
|
|
||||||
|
if self.filters.based_on == 'Customer':
|
||||||
|
self.columns.append({
|
||||||
|
'label': _('Customer'),
|
||||||
|
'options': 'Customer',
|
||||||
|
'fieldname': 'customer',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'width': 200
|
||||||
|
})
|
||||||
|
|
||||||
|
elif self.filters.based_on == 'Assigned To':
|
||||||
|
self.columns.append({
|
||||||
|
'label': _('User'),
|
||||||
|
'fieldname': 'user',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'options': 'User',
|
||||||
|
'width': 200
|
||||||
|
})
|
||||||
|
|
||||||
|
elif self.filters.based_on == 'Issue Type':
|
||||||
|
self.columns.append({
|
||||||
|
'label': _('Issue Type'),
|
||||||
|
'fieldname': 'issue_type',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'options': 'Issue Type',
|
||||||
|
'width': 200
|
||||||
|
})
|
||||||
|
|
||||||
|
elif self.filters.based_on == 'Issue Priority':
|
||||||
|
self.columns.append({
|
||||||
|
'label': _('Issue Priority'),
|
||||||
|
'fieldname': 'priority',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'options': 'Issue Priority',
|
||||||
|
'width': 200
|
||||||
|
})
|
||||||
|
|
||||||
|
for end_date in self.periodic_daterange:
|
||||||
|
period = self.get_period(end_date)
|
||||||
|
self.columns.append({
|
||||||
|
'label': _(period),
|
||||||
|
'fieldname': scrub(period),
|
||||||
|
'fieldtype': 'Int',
|
||||||
|
'width': 120
|
||||||
|
})
|
||||||
|
|
||||||
|
self.columns.append({
|
||||||
|
'label': _('Total'),
|
||||||
|
'fieldname': 'total',
|
||||||
|
'fieldtype': 'Int',
|
||||||
|
'width': 120
|
||||||
|
})
|
||||||
|
|
||||||
|
def get_data(self):
|
||||||
|
self.get_issues()
|
||||||
|
self.get_rows()
|
||||||
|
|
||||||
|
def get_period(self, date):
|
||||||
|
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
||||||
|
|
||||||
|
if self.filters.range == 'Weekly':
|
||||||
|
period = 'Week ' + str(date.isocalendar()[1])
|
||||||
|
elif self.filters.range == 'Monthly':
|
||||||
|
period = str(months[date.month - 1])
|
||||||
|
elif self.filters.range == 'Quarterly':
|
||||||
|
period = 'Quarter ' + str(((date.month - 1) // 3) + 1)
|
||||||
|
else:
|
||||||
|
year = get_fiscal_year(date, self.filters.company)
|
||||||
|
period = str(year[0])
|
||||||
|
|
||||||
|
if getdate(self.filters.from_date).year != getdate(self.filters.to_date).year and self.filters.range != 'Yearly':
|
||||||
|
period += ' ' + str(date.year)
|
||||||
|
|
||||||
|
return period
|
||||||
|
|
||||||
|
def get_period_date_ranges(self):
|
||||||
|
from dateutil.relativedelta import relativedelta, MO
|
||||||
|
from_date, to_date = getdate(self.filters.from_date), getdate(self.filters.to_date)
|
||||||
|
|
||||||
|
increment = {
|
||||||
|
'Monthly': 1,
|
||||||
|
'Quarterly': 3,
|
||||||
|
'Half-Yearly': 6,
|
||||||
|
'Yearly': 12
|
||||||
|
}.get(self.filters.range, 1)
|
||||||
|
|
||||||
|
if self.filters.range in ['Monthly', 'Quarterly']:
|
||||||
|
from_date = from_date.replace(day=1)
|
||||||
|
elif self.filters.range == 'Yearly':
|
||||||
|
from_date = get_fiscal_year(from_date)[1]
|
||||||
|
else:
|
||||||
|
from_date = from_date + relativedelta(from_date, weekday=MO(-1))
|
||||||
|
|
||||||
|
self.periodic_daterange = []
|
||||||
|
for dummy in range(1, 53):
|
||||||
|
if self.filters.range == 'Weekly':
|
||||||
|
period_end_date = add_days(from_date, 6)
|
||||||
|
else:
|
||||||
|
period_end_date = add_to_date(from_date, months=increment, days=-1)
|
||||||
|
|
||||||
|
if period_end_date > to_date:
|
||||||
|
period_end_date = to_date
|
||||||
|
|
||||||
|
self.periodic_daterange.append(period_end_date)
|
||||||
|
|
||||||
|
from_date = add_days(period_end_date, 1)
|
||||||
|
if period_end_date == to_date:
|
||||||
|
break
|
||||||
|
|
||||||
|
def get_issues(self):
|
||||||
|
filters = self.get_common_filters()
|
||||||
|
self.field_map = {
|
||||||
|
'Customer': 'customer',
|
||||||
|
'Issue Type': 'issue_type',
|
||||||
|
'Issue Priority': 'priority',
|
||||||
|
'Assigned To': '_assign'
|
||||||
|
}
|
||||||
|
|
||||||
|
self.entries = frappe.db.get_all('Issue',
|
||||||
|
fields=[self.field_map.get(self.filters.based_on), 'name', 'opening_date'],
|
||||||
|
filters=filters,
|
||||||
|
debug=1
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_common_filters(self):
|
||||||
|
filters = {}
|
||||||
|
filters['opening_date'] = ('between', [self.filters.from_date, self.filters.to_date])
|
||||||
|
|
||||||
|
if self.filters.get('assigned_to'):
|
||||||
|
filters['_assign'] = ('like', '%' + self.filters.get('assigned_to') + '%')
|
||||||
|
|
||||||
|
for entry in ['company', 'status', 'priority', 'customer', 'project']:
|
||||||
|
if self.filters.get(entry):
|
||||||
|
filters[entry] = self.filters.get(entry)
|
||||||
|
|
||||||
|
return filters
|
||||||
|
|
||||||
|
def get_rows(self):
|
||||||
|
self.data = []
|
||||||
|
self.get_periodic_data()
|
||||||
|
|
||||||
|
for entity, period_data in iteritems(self.issue_periodic_data):
|
||||||
|
if self.filters.based_on == 'Customer':
|
||||||
|
row = {'customer': entity}
|
||||||
|
elif self.filters.based_on == 'Assigned To':
|
||||||
|
row = {'user': entity}
|
||||||
|
elif self.filters.based_on == 'Issue Type':
|
||||||
|
row = {'issue_type': entity}
|
||||||
|
elif self.filters.based_on == 'Issue Priority':
|
||||||
|
row = {'priority': entity}
|
||||||
|
|
||||||
|
total = 0
|
||||||
|
for end_date in self.periodic_daterange:
|
||||||
|
period = self.get_period(end_date)
|
||||||
|
amount = flt(period_data.get(period, 0.0))
|
||||||
|
row[scrub(period)] = amount
|
||||||
|
total += amount
|
||||||
|
|
||||||
|
row['total'] = total
|
||||||
|
|
||||||
|
self.data.append(row)
|
||||||
|
|
||||||
|
def get_periodic_data(self):
|
||||||
|
self.issue_periodic_data = frappe._dict()
|
||||||
|
|
||||||
|
for d in self.entries:
|
||||||
|
period = self.get_period(d.get('opening_date'))
|
||||||
|
|
||||||
|
if self.filters.based_on == 'Assigned To':
|
||||||
|
if d._assign:
|
||||||
|
for entry in json.loads(d._assign):
|
||||||
|
self.issue_periodic_data.setdefault(entry, frappe._dict()).setdefault(period, 0.0)
|
||||||
|
self.issue_periodic_data[entry][period] += 1
|
||||||
|
|
||||||
|
else:
|
||||||
|
field = self.field_map.get(self.filters.based_on)
|
||||||
|
value = d.get(field)
|
||||||
|
if not value:
|
||||||
|
value = _('Not Specified')
|
||||||
|
|
||||||
|
self.issue_periodic_data.setdefault(value, frappe._dict()).setdefault(period, 0.0)
|
||||||
|
self.issue_periodic_data[value][period] += 1
|
||||||
|
|
||||||
|
def get_chart_data(self):
|
||||||
|
length = len(self.columns)
|
||||||
|
labels = [d.get('label') for d in self.columns[1:length-1]]
|
||||||
|
self.chart = {
|
||||||
|
'data': {
|
||||||
|
'labels': labels,
|
||||||
|
'datasets': []
|
||||||
|
},
|
||||||
|
'type': 'line'
|
||||||
|
}
|
211
erpnext/support/report/issue_analytics/test_issue_analytics.py
Normal file
211
erpnext/support/report/issue_analytics/test_issue_analytics.py
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import unittest
|
||||||
|
import frappe
|
||||||
|
from frappe.utils import getdate, add_months
|
||||||
|
from erpnext.support.report.issue_analytics.issue_analytics import execute
|
||||||
|
from erpnext.support.doctype.issue.test_issue import make_issue, create_customer
|
||||||
|
from erpnext.support.doctype.service_level_agreement.test_service_level_agreement import create_service_level_agreements_for_issues
|
||||||
|
from frappe.desk.form.assign_to import add as add_assignment
|
||||||
|
|
||||||
|
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
||||||
|
|
||||||
|
class TestIssueAnalytics(unittest.TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(self):
|
||||||
|
frappe.db.sql("delete from `tabIssue` where company='_Test Company'")
|
||||||
|
frappe.db.set_value("Support Settings", None, "track_service_level_agreement", 1)
|
||||||
|
|
||||||
|
current_month_date = getdate()
|
||||||
|
last_month_date = add_months(current_month_date, -1)
|
||||||
|
self.current_month = str(months[current_month_date.month - 1]).lower() + '_' + str(current_month_date.year)
|
||||||
|
self.last_month = str(months[last_month_date.month - 1]).lower() + '_' + str(last_month_date.year)
|
||||||
|
|
||||||
|
def test_issue_analytics(self):
|
||||||
|
create_service_level_agreements_for_issues()
|
||||||
|
create_issue_types()
|
||||||
|
create_records()
|
||||||
|
|
||||||
|
self.compare_result_for_customer()
|
||||||
|
self.compare_result_for_issue_type()
|
||||||
|
self.compare_result_for_issue_priority()
|
||||||
|
self.compare_result_for_assignment()
|
||||||
|
|
||||||
|
def compare_result_for_customer(self):
|
||||||
|
filters = {
|
||||||
|
'company': '_Test Company',
|
||||||
|
'based_on': 'Customer',
|
||||||
|
'from_date': add_months(getdate(), -1),
|
||||||
|
'to_date': getdate(),
|
||||||
|
'range': 'Monthly'
|
||||||
|
}
|
||||||
|
|
||||||
|
report = execute(filters)
|
||||||
|
|
||||||
|
expected_data = [
|
||||||
|
{
|
||||||
|
'customer': '__Test Customer 2',
|
||||||
|
self.last_month: 1.0,
|
||||||
|
self.current_month: 0.0,
|
||||||
|
'total': 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'customer': '__Test Customer 1',
|
||||||
|
self.last_month: 0.0,
|
||||||
|
self.current_month: 1.0,
|
||||||
|
'total': 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'customer': '__Test Customer',
|
||||||
|
self.last_month: 1.0,
|
||||||
|
self.current_month: 1.0,
|
||||||
|
'total': 2.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
self.assertEqual(expected_data, report[1]) # rows
|
||||||
|
self.assertEqual(len(report[0]), 4) # cols
|
||||||
|
|
||||||
|
def compare_result_for_issue_type(self):
|
||||||
|
filters = {
|
||||||
|
'company': '_Test Company',
|
||||||
|
'based_on': 'Issue Type',
|
||||||
|
'from_date': add_months(getdate(), -1),
|
||||||
|
'to_date': getdate(),
|
||||||
|
'range': 'Monthly'
|
||||||
|
}
|
||||||
|
|
||||||
|
report = execute(filters)
|
||||||
|
|
||||||
|
expected_data = [
|
||||||
|
{
|
||||||
|
'issue_type': 'Discomfort',
|
||||||
|
self.last_month: 1.0,
|
||||||
|
self.current_month: 0.0,
|
||||||
|
'total': 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'issue_type': 'Service Request',
|
||||||
|
self.last_month: 0.0,
|
||||||
|
self.current_month: 1.0,
|
||||||
|
'total': 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'issue_type': 'Bug',
|
||||||
|
self.last_month: 1.0,
|
||||||
|
self.current_month: 1.0,
|
||||||
|
'total': 2.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
self.assertEqual(expected_data, report[1]) # rows
|
||||||
|
self.assertEqual(len(report[0]), 4) # cols
|
||||||
|
|
||||||
|
def compare_result_for_issue_priority(self):
|
||||||
|
filters = {
|
||||||
|
'company': '_Test Company',
|
||||||
|
'based_on': 'Issue Priority',
|
||||||
|
'from_date': add_months(getdate(), -1),
|
||||||
|
'to_date': getdate(),
|
||||||
|
'range': 'Monthly'
|
||||||
|
}
|
||||||
|
|
||||||
|
report = execute(filters)
|
||||||
|
|
||||||
|
expected_data = [
|
||||||
|
{
|
||||||
|
'priority': 'Medium',
|
||||||
|
self.last_month: 1.0,
|
||||||
|
self.current_month: 1.0,
|
||||||
|
'total': 2.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'priority': 'Low',
|
||||||
|
self.last_month: 1.0,
|
||||||
|
self.current_month: 0.0,
|
||||||
|
'total': 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'priority': 'High',
|
||||||
|
self.last_month: 0.0,
|
||||||
|
self.current_month: 1.0,
|
||||||
|
'total': 1.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
self.assertEqual(expected_data, report[1]) # rows
|
||||||
|
self.assertEqual(len(report[0]), 4) # cols
|
||||||
|
|
||||||
|
def compare_result_for_assignment(self):
|
||||||
|
filters = {
|
||||||
|
'company': '_Test Company',
|
||||||
|
'based_on': 'Assigned To',
|
||||||
|
'from_date': add_months(getdate(), -1),
|
||||||
|
'to_date': getdate(),
|
||||||
|
'range': 'Monthly'
|
||||||
|
}
|
||||||
|
|
||||||
|
report = execute(filters)
|
||||||
|
|
||||||
|
expected_data = [
|
||||||
|
{
|
||||||
|
'user': 'test@example.com',
|
||||||
|
self.last_month: 1.0,
|
||||||
|
self.current_month: 1.0,
|
||||||
|
'total': 2.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'user': 'test1@example.com',
|
||||||
|
self.last_month: 2.0,
|
||||||
|
self.current_month: 1.0,
|
||||||
|
'total': 3.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
self.assertEqual(expected_data, report[1]) # rows
|
||||||
|
self.assertEqual(len(report[0]), 4) # cols
|
||||||
|
|
||||||
|
|
||||||
|
def create_issue_types():
|
||||||
|
for entry in ['Bug', 'Service Request', 'Discomfort']:
|
||||||
|
if not frappe.db.exists('Issue Type', entry):
|
||||||
|
frappe.get_doc({
|
||||||
|
'doctype': 'Issue Type',
|
||||||
|
'__newname': entry
|
||||||
|
}).insert()
|
||||||
|
|
||||||
|
|
||||||
|
def create_records():
|
||||||
|
create_customer("__Test Customer", "_Test SLA Customer Group", "__Test SLA Territory")
|
||||||
|
create_customer("__Test Customer 1", "_Test SLA Customer Group", "__Test SLA Territory")
|
||||||
|
create_customer("__Test Customer 2", "_Test SLA Customer Group", "__Test SLA Territory")
|
||||||
|
|
||||||
|
current_month_date = getdate()
|
||||||
|
last_month_date = add_months(current_month_date, -1)
|
||||||
|
|
||||||
|
issue = make_issue(current_month_date, "__Test Customer", 2, "High", "Bug")
|
||||||
|
add_assignment({
|
||||||
|
"assign_to": ["test@example.com"],
|
||||||
|
"doctype": "Issue",
|
||||||
|
"name": issue.name
|
||||||
|
})
|
||||||
|
|
||||||
|
issue = make_issue(last_month_date, "__Test Customer", 2, "Low", "Bug")
|
||||||
|
add_assignment({
|
||||||
|
"assign_to": ["test1@example.com"],
|
||||||
|
"doctype": "Issue",
|
||||||
|
"name": issue.name
|
||||||
|
})
|
||||||
|
|
||||||
|
issue = make_issue(current_month_date, "__Test Customer 1", 2, "Medium", "Service Request")
|
||||||
|
add_assignment({
|
||||||
|
"assign_to": ["test1@example.com"],
|
||||||
|
"doctype": "Issue",
|
||||||
|
"name": issue.name
|
||||||
|
})
|
||||||
|
|
||||||
|
issue = make_issue(last_month_date, "__Test Customer 2", 2, "Medium", "Discomfort")
|
||||||
|
add_assignment({
|
||||||
|
"assign_to": ["test@example.com", "test1@example.com"],
|
||||||
|
"doctype": "Issue",
|
||||||
|
"name": issue.name
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user