mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-23 23:19:20 +00:00
Merge pull request #45987 from mihir-kandoi/st31052-3
fix: rename some sla fields
This commit is contained in:
@@ -402,5 +402,6 @@ erpnext.patches.v15_0.sync_auto_reconcile_config
|
|||||||
execute:frappe.db.set_single_value("Accounts Settings", "exchange_gain_loss_posting_date", "Payment")
|
execute:frappe.db.set_single_value("Accounts Settings", "exchange_gain_loss_posting_date", "Payment")
|
||||||
erpnext.patches.v14_0.disable_add_row_in_gross_profit
|
erpnext.patches.v14_0.disable_add_row_in_gross_profit
|
||||||
erpnext.patches.v14_0.update_posting_datetime
|
erpnext.patches.v14_0.update_posting_datetime
|
||||||
|
erpnext.patches.v15_0.rename_sla_fields
|
||||||
erpnext.stock.doctype.stock_ledger_entry.patches.ensure_sle_indexes
|
erpnext.stock.doctype.stock_ledger_entry.patches.ensure_sle_indexes
|
||||||
erpnext.patches.v15_0.update_query_report
|
erpnext.patches.v15_0.update_query_report
|
||||||
|
|||||||
13
erpnext/patches/v15_0/rename_sla_fields.py
Normal file
13
erpnext/patches/v15_0/rename_sla_fields.py
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import frappe
|
||||||
|
from frappe.custom.doctype.custom_field.custom_field import rename_fieldname
|
||||||
|
from frappe.model.utils.rename_field import rename_field
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
doctypes = frappe.get_all("Service Level Agreement", pluck="document_type")
|
||||||
|
for doctype in doctypes:
|
||||||
|
rename_fieldname(doctype + "-resolution_by", "sla_resolution_by")
|
||||||
|
rename_fieldname(doctype + "-resolution_date", "sla_resolution_date")
|
||||||
|
|
||||||
|
rename_field("Issue", "resolution_by", "sla_resolution_by")
|
||||||
|
rename_field("Issue", "resolution_date", "sla_resolution_date")
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
"reset_service_level_agreement",
|
"reset_service_level_agreement",
|
||||||
"cb",
|
"cb",
|
||||||
"agreement_status",
|
"agreement_status",
|
||||||
"resolution_by",
|
"sla_resolution_by",
|
||||||
"service_level_agreement_creation",
|
"service_level_agreement_creation",
|
||||||
"on_hold_since",
|
"on_hold_since",
|
||||||
"total_hold_time",
|
"total_hold_time",
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
"column_break1",
|
"column_break1",
|
||||||
"opening_date",
|
"opening_date",
|
||||||
"opening_time",
|
"opening_time",
|
||||||
"resolution_date",
|
"sla_resolution_date",
|
||||||
"resolution_time",
|
"resolution_time",
|
||||||
"user_resolution_time",
|
"user_resolution_time",
|
||||||
"additional_info",
|
"additional_info",
|
||||||
@@ -176,13 +176,6 @@
|
|||||||
"options": "fa fa-pushpin",
|
"options": "fa fa-pushpin",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"depends_on": "eval: doc.status != 'Replied' && doc.service_level_agreement;",
|
|
||||||
"fieldname": "resolution_by",
|
|
||||||
"fieldtype": "Datetime",
|
|
||||||
"label": "Resolution By",
|
|
||||||
"read_only": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"fieldname": "response",
|
"fieldname": "response",
|
||||||
@@ -287,16 +280,6 @@
|
|||||||
"oldfieldtype": "Time",
|
"oldfieldtype": "Time",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"depends_on": "eval:!doc.__islocal",
|
|
||||||
"fieldname": "resolution_date",
|
|
||||||
"fieldtype": "Datetime",
|
|
||||||
"label": "Resolution Date",
|
|
||||||
"no_copy": 1,
|
|
||||||
"oldfieldname": "resolution_date",
|
|
||||||
"oldfieldtype": "Date",
|
|
||||||
"read_only": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "content_type",
|
"fieldname": "content_type",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
@@ -386,12 +369,29 @@
|
|||||||
"fieldtype": "Duration",
|
"fieldtype": "Duration",
|
||||||
"label": "First Response Time",
|
"label": "First Response Time",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval: doc.status != 'Replied' && doc.service_level_agreement;",
|
||||||
|
"fieldname": "sla_resolution_by",
|
||||||
|
"fieldtype": "Datetime",
|
||||||
|
"label": "Resolution By",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:!doc.__islocal",
|
||||||
|
"fieldname": "sla_resolution_date",
|
||||||
|
"fieldtype": "Datetime",
|
||||||
|
"label": "Resolution Date",
|
||||||
|
"no_copy": 1,
|
||||||
|
"oldfieldname": "resolution_date",
|
||||||
|
"oldfieldtype": "Date",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-ticket",
|
"icon": "fa fa-ticket",
|
||||||
"idx": 7,
|
"idx": 7,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-03-27 13:09:52.921791",
|
"modified": "2025-02-18 21:18:52.797745",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Support",
|
"module": "Support",
|
||||||
"name": "Issue",
|
"name": "Issue",
|
||||||
|
|||||||
@@ -48,13 +48,13 @@ class Issue(Document):
|
|||||||
priority: DF.Link | None
|
priority: DF.Link | None
|
||||||
project: DF.Link | None
|
project: DF.Link | None
|
||||||
raised_by: DF.Data | None
|
raised_by: DF.Data | None
|
||||||
resolution_by: DF.Datetime | None
|
|
||||||
resolution_date: DF.Datetime | None
|
|
||||||
resolution_details: DF.TextEditor | None
|
resolution_details: DF.TextEditor | None
|
||||||
resolution_time: DF.Duration | None
|
resolution_time: DF.Duration | None
|
||||||
response_by: DF.Datetime | None
|
response_by: DF.Datetime | None
|
||||||
service_level_agreement: DF.Link | None
|
service_level_agreement: DF.Link | None
|
||||||
service_level_agreement_creation: DF.Datetime | None
|
service_level_agreement_creation: DF.Datetime | None
|
||||||
|
sla_resolution_by: DF.Datetime | None
|
||||||
|
sla_resolution_date: DF.Datetime | None
|
||||||
status: DF.Literal["Open", "Replied", "On Hold", "Resolved", "Closed"]
|
status: DF.Literal["Open", "Replied", "On Hold", "Resolved", "Closed"]
|
||||||
subject: DF.Data
|
subject: DF.Data
|
||||||
total_hold_time: DF.Duration | None
|
total_hold_time: DF.Duration | None
|
||||||
|
|||||||
@@ -33,48 +33,48 @@ class TestIssue(TestSetUp):
|
|||||||
issue = make_issue(creation, "_Test Customer", 1)
|
issue = make_issue(creation, "_Test Customer", 1)
|
||||||
|
|
||||||
self.assertEqual(issue.response_by, get_datetime("2019-03-04 14:00"))
|
self.assertEqual(issue.response_by, get_datetime("2019-03-04 14:00"))
|
||||||
self.assertEqual(issue.resolution_by, get_datetime("2019-03-04 15:00"))
|
self.assertEqual(issue.sla_resolution_by, get_datetime("2019-03-04 15:00"))
|
||||||
|
|
||||||
# make issue with customer_group specific SLA
|
# make issue with customer_group specific SLA
|
||||||
create_customer("__Test Customer", "_Test SLA Customer Group", "__Test SLA Territory")
|
create_customer("__Test Customer", "_Test SLA Customer Group", "__Test SLA Territory")
|
||||||
issue = make_issue(creation, "__Test Customer", 2)
|
issue = make_issue(creation, "__Test Customer", 2)
|
||||||
|
|
||||||
self.assertEqual(issue.response_by, get_datetime("2019-03-04 14:00"))
|
self.assertEqual(issue.response_by, get_datetime("2019-03-04 14:00"))
|
||||||
self.assertEqual(issue.resolution_by, get_datetime("2019-03-04 15:00"))
|
self.assertEqual(issue.sla_resolution_by, get_datetime("2019-03-04 15:00"))
|
||||||
|
|
||||||
# make issue with territory specific SLA
|
# make issue with territory specific SLA
|
||||||
create_customer("___Test Customer", "__Test SLA Customer Group", "_Test SLA Territory")
|
create_customer("___Test Customer", "__Test SLA Customer Group", "_Test SLA Territory")
|
||||||
issue = make_issue(creation, "___Test Customer", 3)
|
issue = make_issue(creation, "___Test Customer", 3)
|
||||||
|
|
||||||
self.assertEqual(issue.response_by, get_datetime("2019-03-04 14:00"))
|
self.assertEqual(issue.response_by, get_datetime("2019-03-04 14:00"))
|
||||||
self.assertEqual(issue.resolution_by, get_datetime("2019-03-04 15:00"))
|
self.assertEqual(issue.sla_resolution_by, get_datetime("2019-03-04 15:00"))
|
||||||
|
|
||||||
# make issue with default SLA
|
# make issue with default SLA
|
||||||
issue = make_issue(creation=creation, index=4)
|
issue = make_issue(creation=creation, index=4)
|
||||||
|
|
||||||
self.assertEqual(issue.response_by, get_datetime("2019-03-04 16:00"))
|
self.assertEqual(issue.response_by, get_datetime("2019-03-04 16:00"))
|
||||||
self.assertEqual(issue.resolution_by, get_datetime("2019-03-04 18:00"))
|
self.assertEqual(issue.sla_resolution_by, get_datetime("2019-03-04 18:00"))
|
||||||
|
|
||||||
# make issue with default SLA before working hours
|
# make issue with default SLA before working hours
|
||||||
creation = get_datetime("2019-03-04 7:00")
|
creation = get_datetime("2019-03-04 7:00")
|
||||||
issue = make_issue(creation=creation, index=5)
|
issue = make_issue(creation=creation, index=5)
|
||||||
|
|
||||||
self.assertEqual(issue.response_by, get_datetime("2019-03-04 14:00"))
|
self.assertEqual(issue.response_by, get_datetime("2019-03-04 14:00"))
|
||||||
self.assertEqual(issue.resolution_by, get_datetime("2019-03-04 16:00"))
|
self.assertEqual(issue.sla_resolution_by, get_datetime("2019-03-04 16:00"))
|
||||||
|
|
||||||
# make issue with default SLA after working hours
|
# make issue with default SLA after working hours
|
||||||
creation = get_datetime("2019-03-04 20:00")
|
creation = get_datetime("2019-03-04 20:00")
|
||||||
issue = make_issue(creation, index=6)
|
issue = make_issue(creation, index=6)
|
||||||
|
|
||||||
self.assertEqual(issue.response_by, get_datetime("2019-03-06 14:00"))
|
self.assertEqual(issue.response_by, get_datetime("2019-03-06 14:00"))
|
||||||
self.assertEqual(issue.resolution_by, get_datetime("2019-03-06 16:00"))
|
self.assertEqual(issue.sla_resolution_by, get_datetime("2019-03-06 16:00"))
|
||||||
|
|
||||||
# make issue with default SLA next day
|
# make issue with default SLA next day
|
||||||
creation = get_datetime("2019-03-04 14:00")
|
creation = get_datetime("2019-03-04 14:00")
|
||||||
issue = make_issue(creation=creation, index=7)
|
issue = make_issue(creation=creation, index=7)
|
||||||
|
|
||||||
self.assertEqual(issue.response_by, get_datetime("2019-03-04 18:00"))
|
self.assertEqual(issue.response_by, get_datetime("2019-03-04 18:00"))
|
||||||
self.assertEqual(issue.resolution_by, get_datetime("2019-03-06 12:00"))
|
self.assertEqual(issue.sla_resolution_by, get_datetime("2019-03-06 12:00"))
|
||||||
|
|
||||||
frappe.flags.current_time = get_datetime("2019-03-04 15:00")
|
frappe.flags.current_time = get_datetime("2019-03-04 15:00")
|
||||||
issue.reload()
|
issue.reload()
|
||||||
@@ -98,7 +98,7 @@ class TestIssue(TestSetUp):
|
|||||||
issue.save()
|
issue.save()
|
||||||
|
|
||||||
self.assertEqual(issue.on_hold_since, frappe.flags.current_time)
|
self.assertEqual(issue.on_hold_since, frappe.flags.current_time)
|
||||||
self.assertFalse(issue.resolution_by)
|
self.assertFalse(issue.sla_resolution_by)
|
||||||
|
|
||||||
creation = get_datetime("2020-03-04 5:00")
|
creation = get_datetime("2020-03-04 5:00")
|
||||||
frappe.flags.current_time = get_datetime("2020-03-04 5:00")
|
frappe.flags.current_time = get_datetime("2020-03-04 5:00")
|
||||||
@@ -106,7 +106,7 @@ class TestIssue(TestSetUp):
|
|||||||
|
|
||||||
issue.reload()
|
issue.reload()
|
||||||
self.assertEqual(flt(issue.total_hold_time, 2), 2700)
|
self.assertEqual(flt(issue.total_hold_time, 2), 2700)
|
||||||
self.assertEqual(issue.resolution_by, get_datetime("2020-03-04 16:45"))
|
self.assertEqual(issue.sla_resolution_by, get_datetime("2020-03-04 16:45"))
|
||||||
|
|
||||||
creation = get_datetime("2020-03-04 5:05")
|
creation = get_datetime("2020-03-04 5:05")
|
||||||
create_communication(issue.name, "test@admin.com", "Sent", creation)
|
create_communication(issue.name, "test@admin.com", "Sent", creation)
|
||||||
@@ -140,8 +140,8 @@ class TestIssue(TestSetUp):
|
|||||||
issue.status = "Closed"
|
issue.status = "Closed"
|
||||||
issue.save()
|
issue.save()
|
||||||
|
|
||||||
self.assertEqual(issue.resolution_by, get_datetime("2021-11-22 06:00:00"))
|
self.assertEqual(issue.sla_resolution_by, get_datetime("2021-11-22 06:00:00"))
|
||||||
self.assertEqual(issue.resolution_date, get_datetime("2021-11-22 01:00:00"))
|
self.assertEqual(issue.sla_resolution_date, get_datetime("2021-11-22 01:00:00"))
|
||||||
self.assertEqual(issue.agreement_status, "Fulfilled")
|
self.assertEqual(issue.agreement_status, "Fulfilled")
|
||||||
|
|
||||||
def test_issue_open_after_closed(self):
|
def test_issue_open_after_closed(self):
|
||||||
@@ -153,7 +153,7 @@ class TestIssue(TestSetUp):
|
|||||||
create_communication(issue.name, "test@example.com", "Received", frappe.flags.current_time)
|
create_communication(issue.name, "test@example.com", "Received", frappe.flags.current_time)
|
||||||
self.assertEqual(issue.agreement_status, "First Response Due")
|
self.assertEqual(issue.agreement_status, "First Response Due")
|
||||||
self.assertEqual(issue.response_by, get_datetime("2021-11-01 17:00"))
|
self.assertEqual(issue.response_by, get_datetime("2021-11-01 17:00"))
|
||||||
self.assertEqual(issue.resolution_by, get_datetime("2021-11-01 19:00"))
|
self.assertEqual(issue.sla_resolution_by, get_datetime("2021-11-01 19:00"))
|
||||||
|
|
||||||
# Replied on → 2 pm
|
# Replied on → 2 pm
|
||||||
frappe.flags.current_time = get_datetime("2021-11-01 14:00")
|
frappe.flags.current_time = get_datetime("2021-11-01 14:00")
|
||||||
@@ -173,7 +173,7 @@ class TestIssue(TestSetUp):
|
|||||||
# Hold Time + 1 Hrs
|
# Hold Time + 1 Hrs
|
||||||
self.assertEqual(issue.total_hold_time, 3600)
|
self.assertEqual(issue.total_hold_time, 3600)
|
||||||
# Resolution By should increase by one hrs
|
# Resolution By should increase by one hrs
|
||||||
self.assertEqual(issue.resolution_by, get_datetime("2021-11-01 20:00"))
|
self.assertEqual(issue.sla_resolution_by, get_datetime("2021-11-01 20:00"))
|
||||||
|
|
||||||
# Replied on → 4 pm, Open → 1 hr, Resolution Due → 8 pm
|
# Replied on → 4 pm, Open → 1 hr, Resolution Due → 8 pm
|
||||||
frappe.flags.current_time = get_datetime("2021-11-01 16:00")
|
frappe.flags.current_time = get_datetime("2021-11-01 16:00")
|
||||||
@@ -190,9 +190,9 @@ class TestIssue(TestSetUp):
|
|||||||
# Hold Time + 6 Hrs
|
# Hold Time + 6 Hrs
|
||||||
self.assertEqual(issue.total_hold_time, 3600 + 21600)
|
self.assertEqual(issue.total_hold_time, 3600 + 21600)
|
||||||
# Resolution By should increase by 6 hrs
|
# Resolution By should increase by 6 hrs
|
||||||
self.assertEqual(issue.resolution_by, get_datetime("2021-11-02 02:00"))
|
self.assertEqual(issue.sla_resolution_by, get_datetime("2021-11-02 02:00"))
|
||||||
self.assertEqual(issue.agreement_status, "Fulfilled")
|
self.assertEqual(issue.agreement_status, "Fulfilled")
|
||||||
self.assertEqual(issue.resolution_date, frappe.flags.current_time)
|
self.assertEqual(issue.sla_resolution_date, frappe.flags.current_time)
|
||||||
|
|
||||||
# Customer Open → 3 am i.e after resolution by is crossed
|
# Customer Open → 3 am i.e after resolution by is crossed
|
||||||
frappe.flags.current_time = get_datetime("2021-11-02 03:00")
|
frappe.flags.current_time = get_datetime("2021-11-02 03:00")
|
||||||
@@ -201,17 +201,17 @@ class TestIssue(TestSetUp):
|
|||||||
# Since issue was Resolved, Resolution By should be increased by 5 hrs (3am - 10pm)
|
# Since issue was Resolved, Resolution By should be increased by 5 hrs (3am - 10pm)
|
||||||
self.assertEqual(issue.total_hold_time, 3600 + 21600 + 18000)
|
self.assertEqual(issue.total_hold_time, 3600 + 21600 + 18000)
|
||||||
# Resolution By should increase by 5 hrs
|
# Resolution By should increase by 5 hrs
|
||||||
self.assertEqual(issue.resolution_by, get_datetime("2021-11-02 07:00"))
|
self.assertEqual(issue.sla_resolution_by, get_datetime("2021-11-02 07:00"))
|
||||||
self.assertEqual(issue.agreement_status, "Resolution Due")
|
self.assertEqual(issue.agreement_status, "Resolution Due")
|
||||||
self.assertFalse(issue.resolution_date)
|
self.assertFalse(issue.sla_resolution_date)
|
||||||
|
|
||||||
# We Closed → 4 am, SLA should be Fulfilled
|
# We Closed → 4 am, SLA should be Fulfilled
|
||||||
frappe.flags.current_time = get_datetime("2021-11-02 04:00")
|
frappe.flags.current_time = get_datetime("2021-11-02 04:00")
|
||||||
issue.status = "Closed"
|
issue.status = "Closed"
|
||||||
issue.save()
|
issue.save()
|
||||||
self.assertEqual(issue.resolution_by, get_datetime("2021-11-02 07:00"))
|
self.assertEqual(issue.sla_resolution_by, get_datetime("2021-11-02 07:00"))
|
||||||
self.assertEqual(issue.agreement_status, "Fulfilled")
|
self.assertEqual(issue.agreement_status, "Fulfilled")
|
||||||
self.assertEqual(issue.resolution_date, frappe.flags.current_time)
|
self.assertEqual(issue.sla_resolution_date, frappe.flags.current_time)
|
||||||
|
|
||||||
def test_recording_of_assignment_on_first_reponse_failure(self):
|
def test_recording_of_assignment_on_first_reponse_failure(self):
|
||||||
from frappe.desk.form.assign_to import add as add_assignment
|
from frappe.desk.form.assign_to import add as add_assignment
|
||||||
|
|||||||
@@ -514,7 +514,7 @@ def apply(doc, method=None):
|
|||||||
def remove_sla_if_applied(doc):
|
def remove_sla_if_applied(doc):
|
||||||
doc.service_level_agreement = None
|
doc.service_level_agreement = None
|
||||||
doc.response_by = None
|
doc.response_by = None
|
||||||
doc.resolution_by = None
|
doc.sla_resolution_by = None
|
||||||
|
|
||||||
|
|
||||||
def process_sla(doc, sla):
|
def process_sla(doc, sla):
|
||||||
@@ -557,7 +557,7 @@ def handle_status_change(doc, apply_sla_for_resolution):
|
|||||||
# In case issue was closed and after few days it has been opened
|
# In case issue was closed and after few days it has been opened
|
||||||
# The hold time should be calculated from resolution_date
|
# The hold time should be calculated from resolution_date
|
||||||
|
|
||||||
on_hold_since = doc.resolution_date or doc.on_hold_since
|
on_hold_since = doc.sla_resolution_date or doc.on_hold_since
|
||||||
if on_hold_since:
|
if on_hold_since:
|
||||||
current_hold_hours = time_diff_in_seconds(now_time, on_hold_since)
|
current_hold_hours = time_diff_in_seconds(now_time, on_hold_since)
|
||||||
doc.total_hold_time = (doc.total_hold_time or 0) + current_hold_hours
|
doc.total_hold_time = (doc.total_hold_time or 0) + current_hold_hours
|
||||||
@@ -582,7 +582,7 @@ def handle_status_change(doc, apply_sla_for_resolution):
|
|||||||
# Open to Closed
|
# Open to Closed
|
||||||
if is_open_status(prev_status) and is_fulfilled_status(doc.status):
|
if is_open_status(prev_status) and is_fulfilled_status(doc.status):
|
||||||
# Issue is closed -> Set resolution_date
|
# Issue is closed -> Set resolution_date
|
||||||
doc.resolution_date = now_time
|
doc.sla_resolution_date = now_time
|
||||||
set_resolution_time(doc)
|
set_resolution_time(doc)
|
||||||
|
|
||||||
# Closed to Open
|
# Closed to Open
|
||||||
@@ -606,7 +606,7 @@ def handle_status_change(doc, apply_sla_for_resolution):
|
|||||||
calculate_hold_hours()
|
calculate_hold_hours()
|
||||||
# Issue is closed -> Set resolution_date
|
# Issue is closed -> Set resolution_date
|
||||||
if apply_sla_for_resolution:
|
if apply_sla_for_resolution:
|
||||||
doc.resolution_date = now_time
|
doc.sla_resolution_date = now_time
|
||||||
set_resolution_time(doc)
|
set_resolution_time(doc)
|
||||||
|
|
||||||
|
|
||||||
@@ -713,7 +713,7 @@ def get_support_days(service_level):
|
|||||||
def set_resolution_time(doc):
|
def set_resolution_time(doc):
|
||||||
start_date_time = get_datetime(doc.get("service_level_agreement_creation") or doc.creation)
|
start_date_time = get_datetime(doc.get("service_level_agreement_creation") or doc.creation)
|
||||||
if doc.meta.has_field("resolution_time"):
|
if doc.meta.has_field("resolution_time"):
|
||||||
doc.resolution_time = time_diff_in_seconds(doc.resolution_date, start_date_time)
|
doc.resolution_time = time_diff_in_seconds(doc.sla_resolution_date, start_date_time)
|
||||||
|
|
||||||
# total time taken by a user to close the issue apart from wait_time
|
# total time taken by a user to close the issue apart from wait_time
|
||||||
if not doc.meta.has_field("user_resolution_time"):
|
if not doc.meta.has_field("user_resolution_time"):
|
||||||
@@ -737,7 +737,7 @@ def set_resolution_time(doc):
|
|||||||
pending_time.append(wait_time)
|
pending_time.append(wait_time)
|
||||||
|
|
||||||
total_pending_time = sum(pending_time)
|
total_pending_time = sum(pending_time)
|
||||||
resolution_time_in_secs = time_diff_in_seconds(doc.resolution_date, start_date_time)
|
resolution_time_in_secs = time_diff_in_seconds(doc.sla_resolution_date, start_date_time)
|
||||||
doc.user_resolution_time = resolution_time_in_secs - total_pending_time
|
doc.user_resolution_time = resolution_time_in_secs - total_pending_time
|
||||||
|
|
||||||
|
|
||||||
@@ -791,8 +791,8 @@ def reset_service_level_agreement(doctype: str, docname: str, reason, user):
|
|||||||
|
|
||||||
|
|
||||||
def reset_resolution_metrics(doc):
|
def reset_resolution_metrics(doc):
|
||||||
if doc.meta.has_field("resolution_date"):
|
if doc.meta.has_field("sla_resolution_date"):
|
||||||
doc.resolution_date = None
|
doc.sla_resolution_date = None
|
||||||
|
|
||||||
if doc.meta.has_field("resolution_time"):
|
if doc.meta.has_field("resolution_time"):
|
||||||
doc.resolution_time = None
|
doc.resolution_time = None
|
||||||
@@ -859,8 +859,8 @@ def on_communication_update(doc, status):
|
|||||||
def reset_expected_response_and_resolution(doc):
|
def reset_expected_response_and_resolution(doc):
|
||||||
if doc.meta.has_field("first_responded_on") and not doc.get("first_responded_on"):
|
if doc.meta.has_field("first_responded_on") and not doc.get("first_responded_on"):
|
||||||
doc.response_by = None
|
doc.response_by = None
|
||||||
if doc.meta.has_field("resolution_by") and not doc.get("resolution_date"):
|
if doc.meta.has_field("sla_resolution_by") and not doc.get("sla_resolution_date"):
|
||||||
doc.resolution_by = None
|
doc.sla_resolution_by = None
|
||||||
|
|
||||||
|
|
||||||
def set_response_by(doc, start_date_time, priority):
|
def set_response_by(doc, start_date_time, priority):
|
||||||
@@ -877,12 +877,14 @@ def set_response_by(doc, start_date_time, priority):
|
|||||||
|
|
||||||
|
|
||||||
def set_resolution_by(doc, start_date_time, priority):
|
def set_resolution_by(doc, start_date_time, priority):
|
||||||
if doc.meta.has_field("resolution_by"):
|
if doc.meta.has_field("sla_resolution_by"):
|
||||||
doc.resolution_by = get_expected_time_for(
|
doc.sla_resolution_by = get_expected_time_for(
|
||||||
parameter="resolution", service_level=priority, start_date_time=start_date_time
|
parameter="resolution", service_level=priority, start_date_time=start_date_time
|
||||||
)
|
)
|
||||||
if doc.meta.has_field("total_hold_time") and doc.get("total_hold_time"):
|
if doc.meta.has_field("total_hold_time") and doc.get("total_hold_time"):
|
||||||
doc.resolution_by = add_to_date(doc.resolution_by, seconds=round(doc.get("total_hold_time")))
|
doc.sla_resolution_by = add_to_date(
|
||||||
|
doc.sla_resolution_by, seconds=round(doc.get("total_hold_time"))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def record_assigned_users_on_failure(doc):
|
def record_assigned_users_on_failure(doc):
|
||||||
@@ -941,7 +943,7 @@ def get_service_level_agreement_fields():
|
|||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "resolution_by",
|
"fieldname": "sla_resolution_by",
|
||||||
"fieldtype": "Datetime",
|
"fieldtype": "Datetime",
|
||||||
"label": "Resolution By",
|
"label": "Resolution By",
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
@@ -955,7 +957,7 @@ def get_service_level_agreement_fields():
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:!doc.__islocal",
|
"depends_on": "eval:!doc.__islocal",
|
||||||
"fieldname": "resolution_date",
|
"fieldname": "sla_resolution_date",
|
||||||
"fieldtype": "Datetime",
|
"fieldtype": "Datetime",
|
||||||
"label": "Resolution Date",
|
"label": "Resolution Date",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
@@ -975,9 +977,9 @@ def update_agreement_status(doc, apply_sla_for_resolution):
|
|||||||
if apply_sla_for_resolution:
|
if apply_sla_for_resolution:
|
||||||
if doc.meta.has_field("first_responded_on") and not doc.get("first_responded_on"):
|
if doc.meta.has_field("first_responded_on") and not doc.get("first_responded_on"):
|
||||||
doc.agreement_status = "First Response Due"
|
doc.agreement_status = "First Response Due"
|
||||||
elif doc.meta.has_field("resolution_date") and not doc.get("resolution_date"):
|
elif doc.meta.has_field("sla_resolution_date") and not doc.get("sla_resolution_date"):
|
||||||
doc.agreement_status = "Resolution Due"
|
doc.agreement_status = "Resolution Due"
|
||||||
elif get_datetime(doc.get("resolution_date")) <= get_datetime(doc.get("resolution_by")):
|
elif get_datetime(doc.get("sla_resolution_date")) <= get_datetime(doc.get("sla_resolution_by")):
|
||||||
doc.agreement_status = "Fulfilled"
|
doc.agreement_status = "Fulfilled"
|
||||||
else:
|
else:
|
||||||
doc.agreement_status = "Failed"
|
doc.agreement_status = "Failed"
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ class TestServiceLevelAgreement(IntegrationTestCase):
|
|||||||
|
|
||||||
self.assertEqual(lead.service_level_agreement, lead_sla.name)
|
self.assertEqual(lead.service_level_agreement, lead_sla.name)
|
||||||
self.assertEqual(lead.response_by, datetime.datetime(2019, 3, 4, 16, 0))
|
self.assertEqual(lead.response_by, datetime.datetime(2019, 3, 4, 16, 0))
|
||||||
self.assertEqual(lead.resolution_by, datetime.datetime(2019, 3, 4, 18, 0))
|
self.assertEqual(lead.sla_resolution_by, datetime.datetime(2019, 3, 4, 18, 0))
|
||||||
|
|
||||||
frappe.flags.current_time = datetime.datetime(2019, 3, 4, 15, 0)
|
frappe.flags.current_time = datetime.datetime(2019, 3, 4, 15, 0)
|
||||||
lead.reload()
|
lead.reload()
|
||||||
@@ -268,7 +268,7 @@ class TestServiceLevelAgreement(IntegrationTestCase):
|
|||||||
|
|
||||||
lead.reload()
|
lead.reload()
|
||||||
self.assertEqual(flt(lead.total_hold_time, 2), 3000)
|
self.assertEqual(flt(lead.total_hold_time, 2), 3000)
|
||||||
self.assertEqual(lead.resolution_by, datetime.datetime(2020, 3, 4, 16, 50))
|
self.assertEqual(lead.sla_resolution_by, datetime.datetime(2020, 3, 4, 16, 50))
|
||||||
|
|
||||||
def test_failed_sla_for_response_only(self):
|
def test_failed_sla_for_response_only(self):
|
||||||
doctype = "Lead"
|
doctype = "Lead"
|
||||||
|
|||||||
Reference in New Issue
Block a user