Merge pull request #8472 from hrwX/assn-fix

Feat(Assignment Rule): Apply Assignment Rule based on day of the week
This commit is contained in:
mergify[bot] 2019-10-06 08:20:13 +00:00 committed by GitHub
commit b58ce7e963
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 139 additions and 6 deletions

View file

@ -18,6 +18,8 @@
"unassign_condition",
"section_break_10",
"close_condition",
"sb",
"assignment_days",
"assign_to_users_section",
"rule",
"users",
@ -115,9 +117,21 @@
"fieldname": "close_condition",
"fieldtype": "Code",
"label": "Close Condition"
},
{
"fieldname": "sb",
"fieldtype": "Section Break",
"label": "Assignment Days"
},
{
"fieldname": "assignment_days",
"fieldtype": "Table",
"label": "Assignment Days",
"options": "Assignment Rule Day",
"reqd": 1
}
],
"modified": "2019-09-10 14:45:53.657667",
"modified": "2019-09-25 14:52:12.214514",
"modified_by": "Administrator",
"module": "Automation",
"name": "Assignment Rule",

View file

@ -8,8 +8,16 @@ import frappe
from frappe.model.document import Document
from frappe.desk.form import assign_to
import frappe.cache_manager
from frappe import _
class AssignmentRule(Document):
def validate(self):
assignment_days = self.get_assignment_days()
if not len(set(assignment_days)) == len(assignment_days):
repeated_days = get_repeated(assignment_days)
frappe.throw(_("Assignment Day {0} has been repeated.".format(frappe.bold(repeated_days))))
def on_update(self): # pylint: disable=no-self-use
frappe.cache_manager.clear_doctype_map('Assignment Rule', self.name)
@ -118,6 +126,17 @@ class AssignmentRule(Document):
return False
def get_assignment_days(self):
return [d.day for d in self.get('assignment_days', [])]
def is_rule_not_applicable_today(self):
today = frappe.flags.assignment_day or frappe.utils.get_weekday()
assignment_days = self.get_assignment_days()
if assignment_days and not today in assignment_days:
return True
return False
def get_assignments(doc):
return frappe.get_all('ToDo', fields = ['name', 'assignment_rule'], filters = dict(
reference_type = doc.get('doctype'),
@ -181,6 +200,9 @@ def apply(doc, method=None, doctype=None, name=None):
# so when the value switches from L1 to L2, L1 team must be unassigned, then L2 can be assigned.
clear = False
for assignment_rule in assignment_rule_docs:
if assignment_rule.is_rule_not_applicable_today():
continue
clear = assignment_rule.apply_unassign(doc, assignments)
if clear:
break
@ -188,6 +210,9 @@ def apply(doc, method=None, doctype=None, name=None):
# apply rule only if there are no existing assignments
if clear:
for assignment_rule in assignment_rule_docs:
if assignment_rule.is_rule_not_applicable_today():
continue
new_apply = assignment_rule.apply_assign(doc)
if new_apply:
break
@ -196,6 +221,9 @@ def apply(doc, method=None, doctype=None, name=None):
assignments = get_assignments(doc)
if assignments:
for assignment_rule in assignment_rule_docs:
if assignment_rule.is_rule_not_applicable_today():
continue
if not new_apply:
reopen = reopen_closed_assignment(doc)
if reopen:
@ -207,3 +235,14 @@ def apply(doc, method=None, doctype=None, name=None):
def get_assignment_rules():
return [d.document_type for d in frappe.db.get_all('Assignment Rule', fields=['document_type'], filters=dict(disabled = 0))]
def get_repeated(values):
unique_list = []
diff = []
for value in values:
if value not in unique_list:
unique_list.append(str(value))
else:
if value not in diff:
diff.append(str(value))
return " ".join(diff)

View file

@ -6,10 +6,21 @@ from __future__ import unicode_literals
import frappe
import unittest
from frappe.utils import random_string
from frappe.test_runner import make_test_records
class TestAutoAssign(unittest.TestCase):
def setUp(self):
self.assignment_rule = get_assignment_rule()
make_test_records("User")
days = [
dict(day = 'Sunday'),
dict(day = 'Monday'),
dict(day = 'Tuesday'),
dict(day = 'Wednesday'),
dict(day = 'Thursday'),
dict(day = 'Friday'),
dict(day = 'Saturday'),
]
self.assignment_rule = get_assignment_rule([days, days])
clear_assignments()
def test_round_robin(self):
@ -142,21 +153,52 @@ class TestAutoAssign(unittest.TestCase):
status = 'Open'
), 'owner'), 'test@example.com')
def check_assignment_rule_scheduling(self):
frappe.db.sql("DELETE FROM `tabAssignment Rule`")
days_1 = [dict(day = 'Sunday'), dict(day = 'Monday'), dict(day = 'Tuesday')]
days_2 = [dict(day = 'Wednesday'), dict(day = 'Thursday'), dict(day = 'Friday'), dict(day = 'Saturday')]
get_assignment_rule([days_1, days_2], ['public == 1', 'public == 1'])
frappe.flags.assignment_day = "Monday"
note = make_note(dict(public=1))
self.assertIn(frappe.db.get_value('ToDo', dict(
reference_type = 'Note',
reference_name = note.name,
status = 'Open'
), 'owner'), ['test@example.com', 'test1@example.com', 'test2@example.com'])
frappe.flags.assignment_day = "Friday"
note = make_note(dict(public=1))
self.assertIn(frappe.db.get_value('ToDo', dict(
reference_type = 'Note',
reference_name = note.name,
status = 'Open'
), 'owner'), ['test3@example.com'])
def clear_assignments():
frappe.db.sql("delete from tabToDo where reference_type = 'Note'")
def get_assignment_rule():
def get_assignment_rule(days, assign=None):
frappe.delete_doc_if_exists('Assignment Rule', 'For Note 1')
if not assign:
assign = ['public == 1', 'notify_on_login == 1']
assignment_rule = frappe.get_doc(dict(
name = 'For Note 1',
doctype = 'Assignment Rule',
priority = 0,
document_type = 'Note',
assign_condition = 'public == 1',
assign_condition = assign[0],
unassign_condition = 'public == 0 or notify_on_login == 1',
close_condition = '"Closed" in content',
rule = 'Round Robin',
assignment_days = days[0],
users = [
dict(user = 'test@example.com'),
dict(user = 'test1@example.com'),
@ -172,15 +214,15 @@ def get_assignment_rule():
doctype = 'Assignment Rule',
priority = 1,
document_type = 'Note',
assign_condition = 'notify_on_login == 1',
assign_condition = assign[1],
unassign_condition = 'notify_on_login == 0',
rule = 'Round Robin',
assignment_days = days[1],
users = [
dict(user = 'test3@example.com')
]
)).insert()
return assignment_rule
def make_note(values=None):

View file

@ -0,0 +1,28 @@
{
"creation": "2019-09-21 16:52:01.705351",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"day"
],
"fields": [
{
"fieldname": "day",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Day",
"options": "Monday\nTuesday\nWednesday\nThursday\nFriday\nSaturday\nSunday"
}
],
"istable": 1,
"modified": "2019-09-21 16:55:09.376291",
"modified_by": "Administrator",
"module": "Automation",
"name": "Assignment Rule Day",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View file

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
# import frappe
from frappe.model.document import Document
class AssignmentRuleDay(Document):
pass