diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js index e2e699758a9..9dc3834618a 100644 --- a/erpnext/support/doctype/issue/issue.js +++ b/erpnext/support/doctype/issue/issue.js @@ -47,8 +47,13 @@ frappe.ui.form.on("Issue", { priority: function(frm) { if (frm.doc.service_level_agreement) { - frm.call('change_sla_priority', { - "priority": frm.doc.priority + frappe.show_alert({ + indicator: 'green', + message: __('Changing Priority.') + }); + frm.call('change_service_level_agreement_and_priority', { + "priority": frm.doc.priority, + "service_level_agreement": frm.doc.service_level_agreement }).then(() => { frappe.msgprint(__("Issue Priority changed to {0}.", [frm.doc.priority])) frm.refresh(); @@ -56,6 +61,20 @@ frappe.ui.form.on("Issue", { } }, + service_level_agreement: function(frm) { + frappe.show_alert({ + indicator: 'green', + message: __('Changing Service Level Agreement.') + }); + frm.call('change_service_level_agreement_and_priority', { + "priority": frm.doc.priority, + "service_level_agreement": frm.doc.service_level_agreement + }).then(() => { + frappe.msgprint(__("Service Level Agreement changed to {0}.", [frm.doc.service_level_agreement])) + frm.refresh(); + }); + }, + timeline_refresh: function(frm) { // create button for "Help Article" if(frappe.model.can_create('Help Article')) { diff --git a/erpnext/support/doctype/issue/issue.json b/erpnext/support/doctype/issue/issue.json index 29cad627b4c..df8197f30ee 100644 --- a/erpnext/support/doctype/issue/issue.json +++ b/erpnext/support/doctype/issue/issue.json @@ -152,8 +152,7 @@ "fieldname": "service_level_agreement", "fieldtype": "Link", "label": "Service Level Agreement", - "options": "Service Level Agreement", - "read_only": 1 + "options": "Service Level Agreement" }, { "fieldname": "response_by", @@ -308,6 +307,7 @@ "label": "Attachment" }, { + "default": "0", "fieldname": "via_customer_portal", "fieldtype": "Check", "label": "Via Customer Portal" @@ -316,28 +316,28 @@ "default": "Ongoing", "fieldname": "agreement_fulfilled", "fieldtype": "Select", - "label": "Agreement Fulfilled", + "label": "Service Level Agreement Fulfilled", "options": "Ongoing\nFulfilled\nFailed", "read_only": 1 }, { "description": "in hours", "fieldname": "response_by_variance", - "fieldtype": "Int", + "fieldtype": "Float", "label": "Response By Variance", "read_only": 1 }, { "description": "in hours", "fieldname": "resolution_by_variance", - "fieldtype": "Int", + "fieldtype": "Float", "label": "Resolution By Variance", "read_only": 1 } ], "icon": "fa fa-ticket", "idx": 7, - "modified": "2019-05-10 22:31:09.391044", + "modified": "2019-05-19 11:02:10.962090", "modified_by": "Administrator", "module": "Support", "name": "Issue", @@ -357,6 +357,7 @@ ], "quick_entry": 1, "search_fields": "status,customer,subject,raised_by", + "sort_field": "modified", "sort_order": "ASC", "timeline_field": "customer", "title_field": "subject", diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py index ee4a1285132..91333b6370f 100644 --- a/erpnext/support/doctype/issue/issue.py +++ b/erpnext/support/doctype/issue/issue.py @@ -130,13 +130,18 @@ class Issue(Document): def before_insert(self): self.set_response_and_resolution_time(priority=self.priority) - def set_response_and_resolution_time(self, priority): - service_level_agreement = get_active_service_level_agreement_for(priority=priority, customer=self.customer) - if service_level_agreement: - self.service_level_agreement = service_level_agreement.name - else: + def set_response_and_resolution_time(self, priority=None, service_level_agreement=None): + service_level_agreement = get_active_service_level_agreement_for(priority=priority, + customer=self.customer, service_level_agreement=service_level_agreement) + + if not service_level_agreement: return + if service_level_agreement.customer and self.customer and not service_level_agreement.customer == self.customer: + frappe.throw(_("This Service Level Agreement is specific to Customer {0}".format(service_level_agreement.customer))) + + self.service_level_agreement = service_level_agreement.name + service_level = frappe.get_doc("Service Level", service_level_agreement.service_level) priority = service_level.get_service_level_priority(priority) priority.update({ @@ -156,8 +161,8 @@ class Issue(Document): self.resolution_by_variance = round(time_diff_in_hours(self.resolution_by, now_datetime())) @frappe.whitelist() - def change_sla_priority(self, priority): - self.set_response_and_resolution_time(priority=priority) + def change_service_level_agreement_and_priority(self, priority, service_level_agreement): + self.set_response_and_resolution_time(priority=priority, service_level_agreement=service_level_agreement) self.save(ignore_permissions=True) def get_expected_time_for(parameter, service_level, start_date_time): @@ -241,16 +246,18 @@ def set_service_level_agreement_variance(issue=None): filters = {"status": "Open", "agreement_fulfilled": "Ongoing"} if issue: - filters = {"status": issue} + filters = {"name": issue} issues = frappe.get_list("Issue", filters=filters) for issue in issues: doc = frappe.get_doc("Issue", issue.name) - if not doc.first_responded_on and not doc.agreement_fulfilled == "Ongoing": - variance = round(time_diff_in_hours(doc.response_by, now_datetime())) + if not doc.first_responded_on: + variance = round(time_diff_in_hours(doc.response_by, now_datetime()), 2) + print(variance) frappe.db.set_value("Issue", doc.name, "response_by_variance", variance) - if not doc.resolution_dateand and not doc.agreement_fulfilled == "Ongoing": - variance = round(time_diff_in_hours(self.resolution_by, now_datetime())) + if not doc.resolution_date: + variance = round(time_diff_in_hours(doc.resolution_by, now_datetime()), 2) + print(variance) frappe.db.set_value("Issue", doc.name, "resolution_by_variance", variance) def get_list_context(context=None): diff --git a/erpnext/support/doctype/service_level_agreement/service_level_agreement.js b/erpnext/support/doctype/service_level_agreement/service_level_agreement.js index 4f334f212cc..1d486f48346 100644 --- a/erpnext/support/doctype/service_level_agreement/service_level_agreement.js +++ b/erpnext/support/doctype/service_level_agreement/service_level_agreement.js @@ -26,13 +26,4 @@ frappe.ui.form.on('Service Level Agreement', { } }); }, - - validate: function(frm) { - frm.doc.sla_name = null; - var sla_name = 'Default Service Level Agreement'; - if (frm.doc.customer){ - sla_name = frm.doc.customer; - } - frm.doc.sla_name = sla_name; - }, }); diff --git a/erpnext/support/doctype/service_level_agreement/service_level_agreement.json b/erpnext/support/doctype/service_level_agreement/service_level_agreement.json index b63e2af46e2..67e82f468bf 100644 --- a/erpnext/support/doctype/service_level_agreement/service_level_agreement.json +++ b/erpnext/support/doctype/service_level_agreement/service_level_agreement.json @@ -1,11 +1,11 @@ { - "autoname": "format:SLA-{sla_name}", + "autoname": "format:SLA-{service_level_agreement_name}", "creation": "2018-12-26 21:08:15.448812", "doctype": "DocType", "editable_grid": 1, "engine": "InnoDB", "field_order": [ - "sla_name", + "service_level_agreement_name", "customer", "default_service_level_agreement", "holiday_list", @@ -17,6 +17,7 @@ "agreement_status", "column_break_7", "end_date", + "ignore_start_and_end_date", "response_and_resolution_time_section", "priorities", "support_and_resolution_section_break", @@ -33,6 +34,7 @@ "set_only_once": 1 }, { + "default": "0", "depends_on": "eval: !doc.customer", "fieldname": "default_service_level_agreement", "fieldtype": "Check", @@ -75,7 +77,7 @@ "label": "Agreement Details" }, { - "depends_on": "eval: !doc.default_service_level_agreement", + "depends_on": "eval: !doc.default_service_level_agreement && !doc.ignore_start_and_end_date", "fieldname": "start_date", "fieldtype": "Date", "label": "Start Date" @@ -94,7 +96,7 @@ "fieldtype": "Column Break" }, { - "depends_on": "eval: !doc.default_service_level_agreement", + "depends_on": "eval: !doc.default_service_level_agreement && !doc.ignore_start_and_end_date", "fieldname": "end_date", "fieldtype": "Date", "label": "End Date" @@ -124,14 +126,21 @@ "options": "Service Level Priority" }, { - "fieldname": "sla_name", + "fieldname": "service_level_agreement_name", "fieldtype": "Data", "label": "Service Level Agreement Name", - "read_only": 1, + "reqd": 1, "unique": 1 + }, + { + "default": "0", + "fieldname": "ignore_start_and_end_date", + "fieldtype": "Check", + "label": "Ignore Start and End Date", + "set_only_once": 1 } ], - "modified": "2019-05-06 22:00:44.623128", + "modified": "2019-05-19 09:41:55.498800", "modified_by": "Administrator", "module": "Support", "name": "Service Level Agreement", diff --git a/erpnext/support/doctype/service_level_agreement/service_level_agreement.py b/erpnext/support/doctype/service_level_agreement/service_level_agreement.py index e0cbc59aac7..876aaf5bb21 100644 --- a/erpnext/support/doctype/service_level_agreement/service_level_agreement.py +++ b/erpnext/support/doctype/service_level_agreement/service_level_agreement.py @@ -10,20 +10,17 @@ from frappe import _ class ServiceLevelAgreement(Document): def validate(self): - if not (self.customer or self.default_service_level_agreement): - frappe.throw(_("Select a Customer or set as Default Service Level Agreement.")) - if self.default_service_level_agreement: if frappe.db.exists("Service Level Agreement", {"default_service_level_agreement": "1", "name": ["!=", self.name]}): frappe.throw(_("A Default Service Level Agreement already exists.")) else: - if not (self.start_date and self.end_date): + if not (self.start_date and self.end_date and self.ignore_start_and_end_date): frappe.throw(_("Enter Start and End Date for the Agreement.")) - if self.start_date >= self.end_date: + if self.start_date >= self.end_date and not self.ignore_start_and_end_date: frappe.throw(_("Start Date of Agreement can't be greater than or equal to End Date.")) - if self.end_date < frappe.utils.getdate(): + if self.end_date < frappe.utils.nowdate() and not self.ignore_start_and_end_date: frappe.throw(_("End Date of Agreement can't be less than today.")) def check_agreement_status(): @@ -38,14 +35,16 @@ def check_agreement_status(): "agreement_status", "Expired") @frappe.whitelist() -def get_active_service_level_agreement_for(priority, customer=None): +def get_active_service_level_agreement_for(priority, customer=None, service_level_agreement=None): - if customer and frappe.db.exists("Service Level Agreement", {"customer": customer}): + if customer and frappe.db.exists("Service Level Agreement", {"customer": customer}) and not service_level_agreement: or_filter = {"customer": customer} + elif service_level_agreement: + or_filter = {"name": service_level_agreement} else: or_filter = {"default_service_level_agreement": 1} agreement = frappe.get_list("Service Level Agreement", filters={"agreement_status": "Active"}, - or_filters=or_filter, fields=["name", "service_level"]) + or_filters=or_filter, fields=["name", "service_level", "customer"]) return agreement[0] if agreement else None \ No newline at end of file