Beispiel #1
0
 def _get_draftdoc_by_name(self, wfdoc_name):
     result = None
     search_dict = {"name": wfdoc_name}
     dfraft_repo = DomainRepo("Draftdata")
     lst = dfraft_repo.list_domain_obj(**search_dict)
     if  len(lst) == 1 : result = lst[0]              
     return result 
Beispiel #2
0
 def _get_wfdoc_by_name(self, wfdoc_name):
     '''search by primary key id, hence expected to get one object'''
     result = None
     search_dict = {"name": wfdoc_name}
     wfdoc_repo = DomainRepo("Wfdoc")
     lst = wfdoc_repo.list_domain_obj(**search_dict)
     if  len(lst) == 1 : result = lst[0]              
     return result
Beispiel #3
0
 def _list_wfdocObj(self):
     wfdoc_repo = DomainRepo("Wfdoc")
     search_f = {"associated_doctype_name": self.doctype_name}
     #if wfc_filter: 
     #    search_f = {"associated_doctype_name": self.doctype_name,
     #            "doc_data": wfc_filter}
     wfdocObj_list = wfdoc_repo.list_domain_obj(**search_f)
     return wfdocObj_list
Beispiel #4
0
 def _get_doctype_obj_from_name(self):
     '''search by primary key name, hence expected to get one object'''
     result = None
     search_dict = {"name": self.doctype_name}
     doctype_repo = DomainRepo("Doctype")
     lst = doctype_repo.list_domain_obj(**search_dict)
     if not lst:
         conf_lst = doctype_repo.list_domain_obj()
         raise rexc.DocCategoryNotConfigured(self.doctype_name, conf_lst)
     if  len(lst) == 1 : result = lst[0]              
     return result
Beispiel #5
0
 def _list_from_holddoc_filtered_by_logged_in_user_roles(self, wfc_filter=None):
     wfdoctype_repo = DomainRepo('Holddoc')
     search_f = {"associated_doctype_name": self.doctype_name}
     lst = wfdoctype_repo.list_dict(**search_f)
     if wfc_filter: lst = self._filter_by_wfc_on_doc_data(lst, wfc_filter)
     holddocs_filter_by_role = []
     for urole in self.wfc.roles:
         for hold_doc in lst:
             if urole == hold_doc.get('target_role'):
                 holddocs_filter_by_role.append(hold_doc)                
     return holddocs_filter_by_role
Beispiel #6
0
 def _delete_all_holddoc_for_a_wfdoc(self, wfdocObj):
     '''may not be required any more '''
     search_string = {"wfdoc_name": wfdocObj.name}
     holddoc_repo = DomainRepo("Holddoc")
     result = holddoc_repo.delete(**search_string)#TODO: should be no doc found when not present
     return result
 
 
             
     
         
 
     
Beispiel #7
0
 def get_full_wfdoctype_as_dict(self):
     wfdoctypeObj = None
     wfdoctype_repo = DomainRepo('Doctype')
     wfdoctypeObj = wfdoctype_repo.list_domain_obj(**{"name": self.doctype_name})       
     if wfdoctypeObj: wfdoctypeObj = wfdoctypeObj[0]
     datadocfields = []
     for fObj in wfdoctypeObj.datadocfields:
         fdict = fObj.to_dict()
         fdict.pop('associated_doctype')
         fdict.pop('associated_doctype_name')            
         datadocfields.append(fdict)
     wfdoctype_dict = wfdoctypeObj.to_dict()
     wfdoctype_dict.update({"datadocfields": datadocfields})
     return utils.lower_case_keys(wfdoctype_dict)
Beispiel #8
0
 def _create_with_audit(self, wfdocObj, docid, input_data):
     wfdoc_repo = DomainRepo("Wfdoc")
     msg = wfdoc_repo.add_list_of_domain_obj([wfdocObj])
     try:
         audit_msg = self._create_audit_record(wfdocObj, 'Create', input_data)
         msg.update({"audit_msg": audit_msg})
         if audit_msg.get('status').lower().strip() in ['failed', 'Failed', 'error']:
             raise rexc.AuditRecordCreationFailed(docid, audit_msg.get('message') )
     except (rexc.AuditRecordCreationFailed, rexc.FlexFlowException, Exception)  as e:
         status = wfdoc_repo.delete(**{"name": docid})
         #status_roll_back_holddoc = holddoc_repo.delete(**search_filter)
         rollback_msg = {"status": status, "message": str(e) }
         msg.update({"rollback_msg": rollback_msg})
         raise rexc.AuditRecordCreationFailed(docid, audit_msg.get('message'), str(e) )
     return msg
Beispiel #9
0
 def _get_detail_holddoc_for_a_wfdoc(self, wfdoc_dict):
     hodl_doc_dict = None
     holddoc_repo = DomainRepo('Holddoc')
     for urole in self.wfc.roles: #for multiple roles, only the first match is considered
         search_f = {#"associated_doctype_name": self.doctype_name, #TODO: reinforce once update restapi takes <doctype> as param
                 "wfdoc_name": wfdoc_dict.get('name'),
                 "target_role": urole, 
                 "name": urole+wfdoc_dict.get('name')}
         print('serach string ...........', search_f)
         result = holddoc_repo.list_dict(**search_f)
         if result: 
             hodl_doc_dict = result[0]
             print('got result from holddoc...........', hodl_doc_dict)
             break
     return hodl_doc_dict
Beispiel #10
0
 def _unhide_or_hide_action_to_roles(self, wfdocObj, intended_action, new_born):
     holddoc_repo = DomainRepo("Holddoc")
     self._delete_prev_holddoc_by_unhide_roles(wfdocObj, intended_action, holddoc_repo)
     hide_to_roles = self._get_hide_to_roles_from_wfdoc(wfdocObj, intended_action)        
     if isinstance(hide_to_roles, list) and len(hide_to_roles) > 0:
         for urole in hide_to_roles:           
             self._create_holddoc_for_current_role(urole, intended_action, wfdocObj, holddoc_repo, new_born)
Beispiel #11
0
 def test_models(self):
     m.dbdriver.delete(m.Holddoc)
     m.dbdriver.delete(m.Wfdocaudit)
     m.dbdriver.delete(m.Wfdoc)
     m.dbdriver.delete(m.Wfaction)
     m.dbdriver.delete(m.Wfstatus)
     m.dbdriver.delete(m.Datadocfield)
     m.dbdriver.delete(m.Doctype)
     docrepo = DomainRepo("Wfdoc")
     ###########ADDING SINGLE RECORD
     record = m.Wfstatus(name="Status1")
     msg = m.dbdriver.insert(record)
     #print(msg)
     self.assertTrue('has been registered' in msg)
     ############UPDATING THE RECORD
     data = {"name": "Status1111"}
     msg = m.dbdriver.update(m.Wfstatus, data, name='Status1')
     self.assertTrue(msg['status'] == "success")
     msg = m.dbdriver.list_as_dict(m.Wfstatus, name="Status1111")
     self.assertTrue(msg[0]['name'] == 'Status1111')
     #DELETE A SINGLE RECORD FILTERED BY NAME
     msg = m.dbdriver.delete(m.Wfstatus, name="Status1111")
     self.assertTrue("has been  deleted successfully" in msg)
     #########INSERT BULK
     lod = [{"name": "status2"}, {"name": "status3"}, {"name": "status4"}]
     msg = m.dbdriver.insert_bulk(m.Wfstatus, lod)
     msg = m.dbdriver.list_as_dict(m.Wfstatus)
     self.assertTrue(len(msg) == 3)
     ###########DELETE ALL
     msg = m.dbdriver.delete(m.Wfstatus)
     self.assertTrue("has been  deleted successfully" in msg)
Beispiel #12
0
 def _create_audit_record(self, wfdocObj, intended_action, input_data:dict):
     WfdocauditObj = ent.Wfdocaudit(name=str(uuid.uuid4()), #self.wfc.request_id,
                                    wfdoc=wfdocObj, 
                                    username=self.wfc.username, 
                                    email=self.wfc.email, 
                                    time_stamp=self.wfc.time_stamp, 
                                    client_address=self.wfc.client_address, 
                                    org=self.wfc.org, 
                                    orgunit=self.wfc.orgunit, 
                                    department=self.wfc.department,                                       
                                    roles=self.wfc.roles, 
                                    action=intended_action,
                                    data=input_data)
     wfdocaudit_repo = DomainRepo('Wfdocaudit')
     msg = wfdocaudit_repo.add_list_of_domain_obj([WfdocauditObj])
     #print(msg)
     return msg
Beispiel #13
0
 def _create_draft_or_roll_back(self, wfdocObj, draft_data):
     draft_create_msg = {}
     draftdataObj = ent.Draftdata(name=wfdocObj.name, drafted_by=self.wfc.email,
                                target_role = self.wfc.roles,
                                wfdoc=wfdocObj, doc_data=draft_data)
     try:
         draftdoc_repo = DomainRepo("Draftdata")
         draft_search_string = {"name": wfdocObj.name}#delete before creating
         prev_draf_cleared_status = draftdoc_repo.delete(**draft_search_string)
         status = draftdoc_repo.add_list_of_domain_obj([draftdataObj])            
         wfdoc_update_msg = self._update_wfdoc_draft_status(wfdocObj, self.wfc.roles)
         draft_create_msg.update({"draft_create_msg": status, 
                                  "wfdoc_update_msg": wfdoc_update_msg,
                                  "prev_draf_cleared_status": prev_draf_cleared_status})
     except (rexc.FlexFlowException, Exception)  as e:
         delete_stat = draftdoc_repo.delete(**{"name": wfdocObj.name})
         reset_wfdoc_stat = self._update_wfdoc_draft_status(wfdocObj)            
         draft_create_msg.update({"delete_stat": delete_stat,
                                  "reset_wfdoc_stat": reset_wfdoc_stat,
                                  "rollback_msg": str(e)})
         raise rexc.FlexFlowException
     return draft_create_msg
Beispiel #14
0
 def _updadate_with_audit(self, wfdocObj, intended_action, changed_data ):
     ''' also takes care "has_draft_for_roles" role back'''
     wfdoc_repo = DomainRepo("Wfdoc")
     draftdata_repo = DomainRepo("Draftdata")
     target_doc_name = {"name": wfdocObj.name}
     msg = wfdoc_repo.update_from_dict(changed_data, **target_doc_name)
     try:
         draft_search_string = {"name": wfdocObj.name}            
         audit_msg = self._create_audit_record(wfdocObj, intended_action,  changed_data)
         draf_cleared_status = draftdata_repo.delete(**draft_search_string)
         msg.update({"audit_msg": audit_msg, "draf_cleared_status": draf_cleared_status})
         if audit_msg.get('status').lower().strip() in ['failed', 'Failed', 'error']:
             raise rexc.AuditRecordCreationFailed(target_doc_name, audit_msg.get('message') )
     except Exception as e:
         updated_data_dict = {"current_status": wfdocObj.current_status,
                              "prev_status": wfdocObj.prev_status,
                              "has_draft_for_roles": wfdocObj.has_draft_for_roles,
                              "doc_data": wfdocObj.doc_data}
         rollback_msg = wfdoc_repo.update_from_dict(updated_data_dict, **target_doc_name)
         msg.update({"rollback_msg": rollback_msg})
         raise rexc.AuditRecordCreationFailed(target_doc_name, audit_msg.get('message'), str(e) )
     return msg    
Beispiel #15
0
 def _update_wfdoc_draft_status(self, wfdocObj, draft_for_role=None):
     wfdoc_repo = DomainRepo("Wfdoc")
     target_wfdoc_name = {"name": wfdocObj.name}
     updated_wfdoc_draft_roles = {"has_draft_for_roles": draft_for_role}
     ustatus = wfdoc_repo.update_from_dict(updated_wfdoc_draft_roles, **target_wfdoc_name) 
     return ustatus
Beispiel #16
0
 def _register_doctype_n_actions(self):
     m.dbdriver.delete(m.Wfdoc)
     m.dbdriver.delete(m.Wfaction)
     m.dbdriver.delete(m.Wfstatus)
     m.dbdriver.delete(m.Datadocfield)
     m.dbdriver.delete(m.Doctype)
     doctype1 = ent.Doctype("doctype1", "dk1")
     doctype2 = ent.Doctype("doctype2", "invoiceno")
     lodobj = [doctype1, doctype2]
     doctype_repo = DomainRepo("Doctype")
     doctype_repo.add_list_of_domain_obj(lodobj)
     ####DEFINING FIELDS FOR DOCTYPE2
     f1_dict = {
         "name": "invoiceno",
         "associated_doctype": {
             "name": "doctype2"
         },
         "ftype": "str",
         "flength": 100,
         "status_needed_edit": [""]
     }  #this should be status not role
     f2_dict = {
         "name": "dk2",
         "associated_doctype": {
             "name": "doctype2"
         },
         "ftype": "str",
         "flength": 10,
         "status_needed_edit": ["Created"]
     }
     docf_repo = repos.DomainRepo("Datadocfield")
     docf_repo.add_form_lod([f1_dict, f2_dict])
     wfcaction_create = {
         "name": "Create",
         "associated_doctype": {
             "name": "doctype2"
         },
         "need_prev_status": "NewBorn",
         "need_current_status": "NewBorn",
         "leads_to_status": "Created",
         "permitted_to_roles": [
             "role1",
         ]
     }
     wfaction1_dict = {
         "name": "wfaction1",
         "associated_doctype": {
             "name": "doctype2"
         },
         "need_prev_status": "",
         "need_current_status": "Created",
         "leads_to_status": "s1",
         "permitted_to_roles": [
             "r1",
         ]
     }
     wfaction2_dict = {
         "name": "wfaction2",
         "associated_doctype": {
             "name": "doctype2"
         },
         "need_prev_status": "Created",
         "need_current_status": "s1",
         "leads_to_status": "s2",
         "permitted_to_roles": [
             "r2",
         ]
     }
     wfaction3_dict = {
         "name": "wfaction3",
         "associated_doctype": {
             "name": "doctype2"
         },
         "need_prev_status": "s1",
         "need_current_status": "s2",
         "leads_to_status": "s3",
         "permitted_to_roles": [
             "r3",
         ]
     }
     wfactionCreate = ent.Wfaction.from_dict(wfcaction_create)
     wfaction1 = ent.Wfaction.from_dict(wfaction1_dict)
     wfaction2 = ent.Wfaction.from_dict(wfaction2_dict)
     wfaction3 = ent.Wfaction.from_dict(wfaction3_dict)
     lodobj = [wfactionCreate, wfaction1, wfaction2, wfaction3]
     action_repo = DomainRepo("Wfaction")
     action_repo.add_list_of_domain_obj(lodobj)
 def _register_doctype_n_actions(self):
     doctype1 = ent.Doctype("doctype1", "dk1", ['role1'])
     doctype2 = ent.Doctype("doctype2", "dk2", ['role1'])
     lodobj = [doctype1, doctype2]
     doctype_repo = DomainRepo("Doctype")
     doctype_repo.add_list_of_domain_obj(lodobj)
     ####DEFINING FIELDS FOR DOCTYPE2
     f1_dict = {
         "name": "dk1",
         "associated_doctype": {
             "name": "doctype2"
         },
         "ftype": "str",
         "flength": 25,
         "status_needed_edit": ["s1", "Created",
                                "s2"],  #this should be status not role
         "wfc_filter": "",
         "wfc_filter_to_roles": []
     }
     f2_dict = {
         "name": "dk2",
         "associated_doctype": {
             "name": "doctype2"
         },
         "ftype": "str",
         "flength": 10,
         "status_needed_edit": [""],
         "wfc_filter": "",
         "wfc_filter_to_roles": []
     }
     f3_dict = {
         "name": "tsp",
         "associated_doctype": {
             "name": "doctype2"
         },
         "ftype": "str",
         "flength": 10,
         "status_needed_edit": [""],
         "wfc_filter": "org",
         "wfc_filter_to_roles": ['r1']
     }
     f4_dict = {
         "name": "division",
         "associated_doctype": {
             "name": "doctype2"
         },
         "ftype": "str",
         "flength": 10,
         "status_needed_edit": [""],
         "wfc_filter": "ou",
         "wfc_filter_to_roles": ['r3']
     }
     docf_repo = repos.DomainRepo("Datadocfield")
     docf_repo.add_form_lod([f1_dict, f2_dict, f3_dict, f4_dict])
     wfcaction_create = {
         "name": "Create",
         "associated_doctype": {
             "name": "doctype2"
         },
         #"need_prev_status": "NewBorn",
         "need_current_status": ["NewBorn"],
         "leads_to_status": "Created",
         "permitted_to_roles": [
             "r1",
         ],
         "hide_to_roles": ["r7"],
         "undo_prev_hide_for": [],
     }
     wfaction1_dict = {
         "name": "wfaction1",
         "associated_doctype": {
             "name": "doctype2"
         },
         #"need_prev_status": "NewBorn",
         "need_current_status": ["Created"],
         "leads_to_status": "s1",
         "permitted_to_roles": [
             "r1",
         ],
         "hide_to_roles": ["r4", "r5"],
         "undo_prev_hide_for": [],
     }
     wfaction2_dict = {
         "name": "wfaction2",
         "associated_doctype": {
             "name": "doctype2"
         },
         #"need_prev_status": "Created",
         "need_current_status": ["s1"],
         "leads_to_status": "s2",
         "permitted_to_roles": [
             "r2",
         ],
         "hide_to_roles": ["r5", "r6"],
         "undo_prev_hide_for": [
             "r4",
         ],  #r4 hold doc shold be deleted but r5 to be retained
     }
     wfaction3_dict = {
         "name": "wfaction3",
         "associated_doctype": {
             "name": "doctype2"
         },
         #"need_prev_status": "s1",
         "need_current_status": ["s2"],
         "leads_to_status": "s3",
         "permitted_to_roles": [
             "r3",
         ],
         "hide_to_roles": [
             "r1",
         ],
         "undo_prev_hide_for": ["r5", "r6"],
     }
     wfaction4_dict = {
         "name": "wfaction4",
         "associated_doctype": {
             "name": "doctype2"
         },
         #"need_prev_status": "s2",
         "need_current_status": ["s3"],
         "leads_to_status": "s4",
         "permitted_to_roles": [
             "r3",
         ],
         "hide_to_roles": [
             "r5",
         ],
         "undo_prev_hide_for": [],
     }
     wfactionCreate = ent.Wfaction.from_dict(wfcaction_create)
     wfaction1 = ent.Wfaction.from_dict(wfaction1_dict)
     wfaction2 = ent.Wfaction.from_dict(wfaction2_dict)
     wfaction3 = ent.Wfaction.from_dict(wfaction3_dict)
     lodobj = [wfactionCreate, wfaction1, wfaction2, wfaction3]
     action_repo = DomainRepo("Wfaction")
     action_repo.add_list_of_domain_obj(lodobj)
 def test_workflow(self):
     m.dbdriver.delete(m.Draftdata)
     m.dbdriver.delete(m.Holddoc)
     m.dbdriver.delete(m.Wfdocaudit)
     m.dbdriver.delete(m.Wfdoc)
     m.dbdriver.delete(m.Wfaction)
     m.dbdriver.delete(m.Wfstatus)
     m.dbdriver.delete(m.Datadocfield)
     m.dbdriver.delete(m.Doctype)
     self._register_doctype_n_actions()
     testconf.testwfc.roles = ['r1']
     wf = Workflow('doctype2', wfc=testconf.testwfc)
     ##create should fail  when primary key fields in datadoc is not in rule
     try:
         msg = wf.create_doc({
             "dk1": "dv1",
             "dk2-nonprim": "dv22",
         })
     except Exception as e:
         self.assertTrue(e.status == "PrimaryKeyNotPresentInDataDict")
     ##Converts data type  when  fields dk1 is not string
     #wf.create_doc({"dk1": 100, "dk2": "dv2222", })
     ##Fail  when  fields dk3 is not present in the rule at all
     try:
         msg = wf.create_doc({
             "dk3": "not defined in the rule",
             "dk2": "dv22",
             "dk1": 100,
             "tsp": "tata",
             "division": "divison1"
         })
     except Exception as e:
         self.assertTrue(e.status == "UnknownFieldNameInDataDoc")
     ### WORKFLOW IS ABLE TO CREATE DOC
     testconf.testwfc.roles = ['r1']
     testconf.testwfc.org = 'org1'
     msg = wf.create_doc({
         "dk1": "dv1",
         "dk2": "dv22",
         "tsp": "org1",
         "division": "divison1"
     })
     self.assertTrue(msg['message'] == "has been registered")
     ####ABLE TO RETRIEVE THE BY THE PRIMKEY AS DEFINED IN THE DOCTYPE
     doc_repo = DomainRepo("Wfdoc")
     wfdocObj_list = doc_repo.list_domain_obj(name="dv22")
     self.assertTrue(wfdocObj_list[0].name == "dv22")
     ####UPDATE DOC STATUS AS PER THE ACTION RULE,
     testconf.testwfc.request_id = str(uuid.uuid4())
     wf = Workflow('doctype2', wfc=testconf.testwfc)
     msg = wf.action_change_status("dv22", "wfaction1",
                                   {"dk1": "changed_data_on_action1"})
     ### check that self._validate_editable_fields(wfdocObj, data) working
     self.assertTrue(msg['status'] == "success")
     ###wdoc should be able to understand that dk2 is editable and dk1 is not
     self.assertTrue("dk2" not in [
         f.name for f in wfdocObj_list[0].editable_fields_at_current_status
     ])
     self.assertTrue("dk1" in [
         f.name for f in wfdocObj_list[0].editable_fields_at_current_status
     ])
     ###USE ROLE "hide_to_roles": ["r4", "r5"] to see that data is showing from holddoc
     #data still should show previous data {"dk1": "dv1", "dk2": "dv22", }
     testconf.testwfc.roles = ['r4']
     testconf.testwfc.request_id = str(uuid.uuid4())
     wf = Workflow('doctype2', wfc=testconf.testwfc)
     result = wf.list_wfdoc()
     self.assertTrue(result[0].get('doc_data').get('dk1') ==
                     'dv1')  # data is showing from holddoc for role r4
     ####same for r5
     testconf.testwfc.roles = ['r5']
     testconf.testwfc.request_id = str(uuid.uuid4())
     wf = Workflow('doctype2', wfc=testconf.testwfc)
     result = wf.list_wfdoc()
     self.assertTrue(result[0].get('doc_data').get('dk1') == 'dv1')
     #########FOR R6 AND R1 THE UPDATED DATA IS VISIBLE
     testconf.testwfc.roles = ['r1', 'r6']
     testconf.testwfc.request_id = str(uuid.uuid4())
     wf = Workflow('doctype2', wfc=testconf.testwfc)
     result = wf.list_wfdoc()
     self.assertTrue(
         result[0].get('doc_data').get('dk1') == 'changed_data_on_action1')
     ####SHOULD FAIL FOR INCORRECT ROLE
     testconf.testwfc.roles = ['r1']
     testconf.testwfc.request_id = str(uuid.uuid4())
     wf = Workflow('doctype2', wfc=testconf.testwfc)
     try:
         msg = wf.action_change_status("dv22", "wfaction2")
     except rexc.RoleNotPermittedForThisAction as err:
         self.assertTrue(err.status == "RoleNotPermittedForThisAction")
     ###SHOULD PASS THE ROLE AND THE RULE
     testconf.testwfc.request_id = str(uuid.uuid4())
     testconf.testwfc.roles = ['r2']
     wf = Workflow('doctype2', wfc=testconf.testwfc)
     msg = wf.action_change_status("dv22", "wfaction2",
                                   {"dk1": "changed_data_on_action2"})
     self.assertTrue(msg['status'] == "success")
     ##during action1 "hide_to_roles": ["r4", "r5"], and in action2 "undo_prev_hide_for": ["r4",],
     ####should be able to see latest data
     ##########hold for R4 has now been removed
     ####should be able to see latest data
     testconf.testwfc.roles = ['r4']
     testconf.testwfc.request_id = str(uuid.uuid4())
     wf = Workflow('doctype2', wfc=testconf.testwfc)
     result = wf.list_wfdoc()
     self.assertTrue(
         result[0].get('doc_data').get('dk1') == 'changed_data_on_action2')
     ##########hold for R5 stil remains
     testconf.testwfc.roles = ['r5']
     testconf.testwfc.request_id = str(uuid.uuid4())
     wf = Workflow('doctype2', wfc=testconf.testwfc)
     result = wf.list_wfdoc()
     self.assertTrue(
         result[0].get('doc_data').get('dk1') == 'dv1'
     )  # data remained what it was before action1 which is the data at create stage
     ####HAVE A TEST FOR RULE STATUS VALIDATION FAILURE
     testconf.testwfc.request_id = str(uuid.uuid4())
     testconf.testwfc.roles = ['r1']
     wf = Workflow('doctype2', wfc=testconf.testwfc)
     try:
         msg = wf.action_change_status("dv22", "wfaction1")
     except rexc.WorkflowActionRuleViolation as err:
         self.assertTrue(err.status == "WorkflowActionRuleViolation")
     ####WFDOC SHOULD HAVE actions_for_current_stattus
     actions_for_current_status = [
         a.name for a in wfdocObj_list[0].actions_for_current_status
     ]
     self.assertTrue(actions_for_current_status == ['wfaction1'])
     ###fail due to data having non editable field dk1
     ###develop logic to check if the data has actually changed
     testconf.testwfc.request_id = str(uuid.uuid4())
     testconf.testwfc.roles = ['r3']
     wf = Workflow('doctype2', wfc=testconf.testwfc)
     try:
         wf.action_change_status("dv22", "wfaction3", {
             "dk1": "dv1",
             "dk2": "dv22"
         })
     except Exception as e:
         self.assertTrue(e.status == "EditNotAllowedForThisField")
     ###get full wfdoc dict including current action list and editable field list
     msg = wf.get_full_wfdoc_as_dict('dv22')
     self.assertTrue('dk1' in msg.get('current_edit_fields'))
     self.assertTrue('wfaction3' in msg.get('current_actions'))
     ###WITH R5 ROLE SEE HOLDDOC IS CREATED
     #         testconf.testwfc.request_id = str(uuid.uuid4())
     #         testconf.testwfc.roles= ['r3']
     #         wf = Workflow('doctype2', wfc=testconf.testwfc)
     ##############################################################
     ############document was created as tsp="org1", division="division1"
     ###field to wfc mapping was tsp field maps to  org for role r1
     ###and divison maps to ou for role r3
     testconf.testwfc.org = "org2"
     testconf.testwfc.orgunit = "divison1"
     testconf.testwfc.roles = ['r3']
     testconf.testwfc.request_id = str(uuid.uuid4())
     wf = Workflow('doctype2', wfc=testconf.testwfc)
     result = wf.list_wfdoc()
     self.assertTrue(
         result[0].get('doc_data').get('division') == 'divison1')
     ####division1 cant see when the  doc is created for  divison2
     testconf.testwfc.roles = ['r1']
     testconf.testwfc.org = 'org1'
     msg = wf.create_doc({
         "dk1": "dv1",
         "dk2": "dkdiv2",
         "tsp": "org1",
         "division": "divison2"
     })
     testconf.testwfc.org = "org2"
     testconf.testwfc.orgunit = "divison1"
     testconf.testwfc.roles = ['r3']
     testconf.testwfc.request_id = str(uuid.uuid4())
     wf = Workflow('doctype2', wfc=testconf.testwfc)
     result = wf.list_wfdoc()
     self.assertTrue(not len(result) == 2)
     ###TSPorg2 cant see doc created by tsp=org1
     testconf.testwfc.roles = ['r1']
     testconf.testwfc.org = 'tsporg2'
     wf = Workflow('doctype2', wfc=testconf.testwfc)
     result = wf.list_wfdoc()
     self.assertTrue(not result)
     ###AT THIS STAGE ACTION 3 IS PERMITTED TO ROLE3
     ###Role3 should be able to put some data in save as draft
     testconf.testwfc.org = "org2"
     testconf.testwfc.orgunit = "divison1"
     testconf.testwfc.roles = ['r3']
     testconf.testwfc.request_id = str(uuid.uuid4())
     wf = Workflow('doctype2', wfc=testconf.testwfc)
     draft_data = {"dk1": "want_to_save_as_draft"}
     result = wf.save_as_draft("dv22", draft_data)
     self.assertTrue(
         result.get('draft_create_msg').get('status') == "success")
     self.assertTrue(
         result.get('wfdoc_update_msg').get('status') == "success")
     ##get draft data for  same role
     result = wf.get_draft_data_for_role('dv22')
     self.assertTrue(result.get('dk1') == 'want_to_save_as_draft')
     ##other are not seeing the draft doc even when queried
     testconf.testwfc.roles = ['r2']
     testconf.testwfc.request_id = str(uuid.uuid4())
     wf = Workflow('doctype2', wfc=testconf.testwfc)
     result = wf.get_draft_data_for_role('dv22')
     self.assertTrue(not result)
     #list draft doc
     result = wf.list_wfdocs_superimposed_by_draft(
     )  #?????????????????????????????????
     #TODO: check why this is failing ???????
     #self.assertTrue(result[0].get('doc_data').get('dk1') == "want_to_save_as_draft")
     ##update or action  from draft
     testconf.testwfc.roles = ['r3']
     testconf.testwfc.request_id = str(uuid.uuid4())
     wf = Workflow('doctype2', wfc=testconf.testwfc)
     result = wf.action_from_draft('dv22', "wfaction3")
     self.assertTrue("want_to_save_as_draft" in result.get('message'))
 def test_entities(self):
     m.dbdriver.delete(m.Holddoc)
     m.dbdriver.delete(m.Wfdocaudit)
     m.dbdriver.delete(m.Wfdoc)
     m.dbdriver.delete(m.Wfaction)
     m.dbdriver.delete(m.Wfstatus)
     m.dbdriver.delete(m.Datadocfield)
     m.dbdriver.delete(m.Doctype)
     docrepo = DomainRepo("Wfdoc")
     ###########REGISTER DOCTYPE
     doctype1 = ent.Doctype("doctype1", "dk1", ["r1"])
     doctype2 = ent.Doctype("doctype2", "dk2", ["r1"])
     lodobj = [doctype1, doctype2]
     doctype_repo = DomainRepo("Doctype")
     msg = doctype_repo.add_list_of_domain_obj(lodobj)
     self.assertTrue(msg['message'] == "has been registered")
     ########REGISTER ACTION RULES
     wfaction1_dict = {
         "name": "wfaction1",
         "associated_doctype": {
             "name": "doctype1"
         },
         "need_prev_status": "s0",
         "need_current_status": "s1",
         "leads_to_status": "s2",
         "permitted_to_roles": [
             "r1",
         ],
         "hide_to_roles": [
             "r5",
         ]
     }
     wfaction2_dict = {
         "name": "wfaction2",
         "associated_doctype": {
             "name": "doctype2"
         },
         "need_prev_status": "s1",
         "need_current_status": "s2",
         "leads_to_status": "s3",
         "permitted_to_roles": [
             "r2",
         ],
         "hide_to_roles": [
             "r5",
         ]
     }
     wfaction3_dict = {
         "name": "wfaction3",
         "associated_doctype": {
             "name": "doctype2"
         },
         "need_prev_status": "s2",
         "need_current_status": "s3",
         "leads_to_status": "s4",
         "permitted_to_roles": [
             "r3",
         ],
         "hide_to_roles": [
             "r5",
         ]
     }
     wfaction1 = ent.Wfaction.from_dict(wfaction1_dict)
     wfaction2 = ent.Wfaction.from_dict(wfaction2_dict)
     wfaction3 = ent.Wfaction.from_dict(wfaction3_dict)
     lodobj = [wfaction1, wfaction2, wfaction3]
     action_repo = DomainRepo("Wfaction")
     msg = action_repo.add_list_of_domain_obj(lodobj)
     self.assertTrue(msg['message'] == "has been registered")
     ############RETRIEVE ACTION1 FROM REPO
     doctype_list_sobj = doctype_repo.list_obj()
     self.assertTrue(isinstance(doctype_list_sobj[0], m.Doctype))
     doctype_list_dobj = doctype_repo.list_domain_obj()
     self.assertTrue(isinstance(doctype_list_dobj[0], ent.Doctype))
     action_list_dict = action_repo.list_dict()
     self.assertTrue(
         isinstance(action_list_dict[0]['associated_doctype'], dict))
     action_list_sobj = action_repo.list_obj()
     self.assertTrue(isinstance(action_list_sobj[0], m.Wfaction))
     action_list_dobj = action_repo.list_domain_obj()
     self.assertTrue(isinstance(action_list_dobj[0], ent.Wfaction))
     seearchf = {"associated_doctype": {"name": "doctype2"}}
     action_list_filtered_by_doctype = action_repo.list_domain_obj(
         **seearchf)
     self.assertTrue(action_list_filtered_by_doctype[0].associated_doctype.
                     name == 'doctype2')
     self.assertTrue(action_list_filtered_by_doctype[1].associated_doctype.
                     name == 'doctype2')
     ####UPDATE RELATTIONSHIP FIELD ACTION1 DOCTYPE FROM 1 TO 2
     wfaction1_dict.update({"associated_doctype": {"name": "doctype2"}})
     searchf = {"name": "wfaction1"}
     msg = action_repo.update_from_dict(wfaction1_dict, **searchf)
     self.assertTrue(msg['status'] == "success")
     action_list_filtered_by_doctype = action_repo.list_domain_obj(
         **seearchf)
     self.assertTrue(len(action_list_filtered_by_doctype) == 3)
     ####DEFINING FIELDS FOR DOCTYPE2
     f1_dict = {
         "name": "field1",
         "associated_doctype": {
             "name": "doctype2"
         },
         "ftype": "str",
         "flength": 2,
         "status_needed_edit": ["s3"]
     }
     f2_dict = {
         "name": "field2",
         "associated_doctype": {
             "name": "doctype2"
         },
         "ftype": "int",
         "flength": 2,
         "status_needed_edit": [""]
     }
     docf_repo = repos.DomainRepo("Datadocfield")
     msg = docf_repo.add_form_lod([f1_dict, f2_dict])
     self.assertTrue(msg['status'] == "success")
     datadocfields_repo = repos.DomainRepo("Datadocfield")
     searh_filter = {"associated_doctype": {"name": "doctype2"}}
     result = datadocfields_repo.list_domain_obj(**searh_filter)
     fnames = [item.name for item in result]
     self.assertTrue("field1" in fnames)
     ###CHECK THE ID ATTRIBUTE FROM SQL OBJ HAS BEEN PASSED TO DOMAINOBJ
     #self.assertTrue(hasattr(action_list_filtered_by_doctype[0], 'id'))
     doc_data1 = {"field1": "v1", "field2": 10}
     primval_datadoc = doc_data1["field1"]
     wfdoc_dict1 = {
         "name": primval_datadoc,
         "associated_doctype": {
             "name": "doctype2"
         },
         "prev_status": "s2",
         "current_status": "s3",
         "doc_data": doc_data1,
     }
     wfdoc_lod = [wfdoc_dict1]
     wfdoc_repo = repos.DomainRepo("Wfdoc")
     msg = wfdoc_repo.add_form_lod(wfdoc_lod)
     #######RETRIEVE DOC USING PRIMKEY
     wfdoc_list = wfdoc_repo.list_domain_obj(**{"name": "v1"})
     ##########SEE THE COMNNETS above IN CASE OF INPUT TYPE EXCEPTION
     self.assertTrue(len(wfdoc_list[0].wfactions) == 3)
     self.assertTrue((wfdoc_list[0].doc_data == doc_data1))
     #####FROM DICT CREATE DOMAIN OBJ AND THEN SAVE TO REPO
     doc_data1 = {"field1": "v2", "field2": 10}
     primval_datadoc = doc_data1["field1"]
     wfdoc_dict2 = {
         "name": primval_datadoc,
         "associated_doctype": {
             "name": "doctype2"
         },
         "prev_status": "s2",
         "current_status": "s3",
         "doc_data": doc_data1,
     }
     wfdoc2 = ent.Wfdoc.from_dict(wfdoc_dict2)
     ###ADD THE DOMAIN OBJECT TO THE DOMAIN REPO
     msg = wfdoc_repo.add_list_of_domain_obj([wfdoc2])
     self.assertTrue(msg['message'] == "has been registered")
     ###SEE DOCTYPE2 HAVE THE DOCDATAFIELDS
     doctype2Obj_list = doctype_repo.list_domain_obj(**{"name": "doctype2"})
     ###CREATE DOC ONCE ITS FIELDS ARE DEFINED ABOVE
     doc_data3 = {"field1": "v3", "field2": 10}
     wfdoc_dict3 = {
         "name": 'v3',
         "associated_doctype": {
             "name": "doctype2"
         },
         "prev_status": "",
         "current_status": "Created",
         "doc_data": doc_data3,
     }
     ###FAIL FOR FIELD NAME MISTACH
     try:
         ent.Wfdoc.from_dict(wfdoc_dict3)
     except rexc.UnknownFieldNameInDataDoc as e:
         self.assertTrue(e.status == "UnknownFieldNameInDataDoc")
     ##FAILURE FOR FIELD LENGTH LARGER THAN CONFIGURED
     doc_data3 = {"field1": "v44444", "field2": 10}
     wfdoc_dict3.update({"doc_data": doc_data3})
     try:
         ent.Wfdoc.from_dict(wfdoc_dict3)
     except rexc.DataLengthViolation as e:
         self.assertTrue(e.status == "DataLengthViolation")
     ####FAIL FOR FIELD TYPE, FIELD2 SHOULD BE INT TYPE
     wfdoc_dict3.update({
         "name": "v3",
         "doc_data": {
             "field1": "v3",
             "field2": "v2"
         }
     })
     try:
         ent.Wfdoc.from_dict(wfdoc_dict3)
     except rexc.DataTypeViolation as e:
         self.assertTrue(e.status == "DataTypeViolation")
     ###########CHECK SUCCESS
     wfdoc_dict3.update({
         "name": "v3",
         "doc_data": {
             "field1": "v3",
             "field2": 10
         }
     })
     docobj = ent.Wfdoc.from_dict(wfdoc_dict3)
     self.assertTrue(docobj.name == "v3")
Beispiel #20
0
 def _list_from_wfdoc(self, wfc_filter:dict=None):
     wfdoc_repo = DomainRepo('Wfdoc')
     search_f = {"associated_doctype_name": self.doctype_name}
     lst = wfdoc_repo.list_dict(**search_f)
     if wfc_filter: lst = self._filter_by_wfc_on_doc_data(lst, wfc_filter)
     return lst
    def _register_doctype_n_actions(self):
        m.dbdriver.delete(m.Draftdata)
        m.dbdriver.delete(m.Holddoc)
        m.dbdriver.delete(m.Wfdocaudit)
        m.dbdriver.delete(m.Wfdoc)
        m.dbdriver.delete(m.Wfaction)
        m.dbdriver.delete(m.Wfstatus)
        m.dbdriver.delete(m.Datadocfield)
        m.dbdriver.delete(m.Doctype)
        tspinvoice = ent.Doctype("tspinvoice", "InvoiceNo", ['role1'])
        lodobj = [tspinvoice]
        doctype_repo = DomainRepo("Doctype")
        doctype_repo.add_list_of_domain_obj(lodobj)
        ####DEFINING FIELDS FOR tspinvoice
        InvoiceNo = {
            "name": "InvoiceNo",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "str",
            "flength": 25,
            "status_needed_edit": ["",
                                   "NewBorn"],  #this should be status not role
            "wfc_filter": "",
            "wfc_filter_to_roles": []
        }
        Action = {
            "name": "Action",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "str",
            "flength": 25,
            "status_needed_edit": [""],
            "wfc_filter": "",
            "wfc_filter_to_roles": []
        }
        TSP = {
            "name": "TSP",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "str",
            "flength": 25,
            "status_needed_edit": [""],
            "wfc_filter": "org",
            "wfc_filter_to_roles": ['r1']
        }
        Division = {
            "name": "Division",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "str",
            "flength": 25,
            "status_needed_edit": [""],
            "wfc_filter": "ou",
            "wfc_filter_to_roles": ['r3']
        }
        InfoID = {
            "name": "InfoID",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "str",
            "flength": 25,
            "status_needed_edit": [""],
            "wfc_filter": "",
            "wfc_filter_to_roles": ['']
        }
        CircuitID = {
            "name": "CircuitID",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "str",
            "flength": 25,
            "status_needed_edit": [""],
            "wfc_filter": "",
            "wfc_filter_to_roles": ['']
        }
        Speed = {
            "name": "Speed",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "str",
            "flength": 25,
            "status_needed_edit": [""],
            "wfc_filter": "",
            "wfc_filter_to_roles": []
        }
        ARC = {
            "name": "ARC",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "str",
            "flength": 25,
            "status_needed_edit": [""],
            "wfc_filter": "",
            "wfc_filter_to_roles": []
        }
        ServiceType = {
            "name": "ServiceType",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "str",
            "flength": 25,
            "status_needed_edit": [""],
            "wfc_filter": "",
            "wfc_filter_to_roles": []
        }
        SiteID = {
            "name": "SiteID",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "str",
            "flength": 25,
            "status_needed_edit": [""],
            "wfc_filter": "",
            "wfc_filter_to_roles": []
        }
        FullSiteAddress = {
            "name": "FullSiteAddress",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "str",
            "flength": 50,
            "status_needed_edit": [""],
            "wfc_filter": "",
            "wfc_filter_to_roles": []
        }
        GSTNo = {
            "name": "GSTNo",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "str",
            "flength": 25,
            "status_needed_edit": [""],
            "wfc_filter": "",
            "wfc_filter_to_roles": []
        }
        BillingDateFrom = {
            "name": "BillingDateFrom",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "str",
            "flength": 25,
            "status_needed_edit": [""],
            "wfc_filter": "",
            "wfc_filter_to_roles": []
        }
        BillingDateTO = {
            "name": "BillingDateTO",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "str",
            "flength": 25,
            "status_needed_edit": [""],
            "wfc_filter": "",
            "wfc_filter_to_roles": []
        }
        InvoiceDate = {
            "name": "InvoiceDate",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "str",
            "flength": 25,
            "status_needed_edit": [""],
            "wfc_filter": "",
            "wfc_filter_to_roles": []
        }
        TaxName = {
            "name": "TaxName",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "str",
            "flength": 25,
            "status_needed_edit": [""],
            "wfc_filter": "",
            "wfc_filter_to_roles": []
        }
        Total = {
            "name": "Total",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "int",
            "flength": 25,
            "status_needed_edit": [""],
            "wfc_filter": "",
            "wfc_filter_to_roles": []
        }
        REMARKS = {
            "name": "REMARKS",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            "ftype": "str",
            "flength": 100,
            "status_needed_edit": [""],
            "wfc_filter": "",
            "wfc_filter_to_roles": []
        }

        docf_repo = DomainRepo("Datadocfield")
        docf_repo.add_form_lod([
            InvoiceNo, Action, TSP, Division, InfoID, CircuitID, Speed, ARC,
            ServiceType, SiteID, FullSiteAddress, GSTNo, BillingDateFrom,
            BillingDateTO, InvoiceDate, TaxName, Total, REMARKS
        ])
        wfcaction_create = {
            "name": "Create",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            #"need_prev_status": "NewBorn",
            "need_current_status": ["NewBorn"],
            "leads_to_status": "Created",
            "permitted_to_roles": [
                "role1",
            ],
            "hide_to_roles": ["r7"],
            "undo_prev_hide_for": [],
        }
        wfaction1_dict = {
            "name": "wfaction1",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            #"need_prev_status": "NewBorn",
            "need_current_status": ["Created"],
            "leads_to_status": "s1",
            "permitted_to_roles": [
                "r1",
            ],
            "hide_to_roles": ["r4", "r5"],
            "undo_prev_hide_for": [],
        }
        wfaction2_dict = {
            "name": "wfaction2",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            #"need_prev_status": "Created",
            "need_current_status": ["s1"],
            "leads_to_status": "s2",
            "permitted_to_roles": [
                "r2",
            ],
            "hide_to_roles": ["r5", "r6"],
            "undo_prev_hide_for": [
                "r4",
            ],  #r4 hold doc shold be deleted but r5 to be retained
        }
        wfaction3_dict = {
            "name": "wfaction3",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            #"need_prev_status": "s1",
            "need_current_status": ["s2"],
            "leads_to_status": "s3",
            "permitted_to_roles": [
                "r3",
            ],
            "hide_to_roles": [
                "r1",
            ],
            "undo_prev_hide_for": ["r5", "r6"],
        }
        wfaction4_dict = {
            "name": "wfaction4",
            "associated_doctype": {
                "name": "tspinvoice"
            },
            #"need_prev_status": "s2",
            "need_current_status": ["s3"],
            "leads_to_status": "s4",
            "permitted_to_roles": [
                "r3",
            ],
            "hide_to_roles": [
                "r5",
            ],
            "undo_prev_hide_for": [],
        }
        wfactionCreate = ent.Wfaction.from_dict(wfcaction_create)
        wfaction1 = ent.Wfaction.from_dict(wfaction1_dict)
        wfaction2 = ent.Wfaction.from_dict(wfaction2_dict)
        wfaction3 = ent.Wfaction.from_dict(wfaction3_dict)
        lodobj = [wfactionCreate, wfaction1, wfaction2, wfaction3]
        action_repo = DomainRepo("Wfaction")
        action_repo.add_list_of_domain_obj(lodobj)
    def test_workflow(self):
        m.dbdriver.delete(m.Wfdoc)
        m.dbdriver.delete(m.Wfaction)
        m.dbdriver.delete(m.Wfstatus)
        m.dbdriver.delete(m.Datadocfield)
        m.dbdriver.delete(m.Doctype)
        self._register_doctype_n_actions()
        wf = Workflow('doctype2', 'r1')

        ##create should fail  when primary key fields in datadoc is not in rule
        try:
            wf.create_doc({
                "dk1": "dv1",
                "dk2-nonprim": "dv2",
            }, 'r1')
        except Exception as e:
            self.assertTrue(e.status == "PrimaryKeyNotPresentInDataDict")
        ##Fail  when  fields dk1 is not string
        try:
            wf.create_doc({
                "dk1": 100,
                "dk2": "dv2",
            }, 'r1')
        except Exception as e:
            self.assertTrue(e.status == "DataTypeViolation")
        ##Fail  when  fields dk3 is not present in the rule at all
        try:
            wf.create_doc({
                "dk3": "not defined in the rule",
                "dk2": "dv2",
            }, 'r1')
        except Exception as e:
            self.assertTrue(e.status == "UnknownFieldNameInDataDoc")
        ### WORKFLOW IS ABLE TO CREATE DOC
        msg = wf.create_doc({
            "dk1": "dv1",
            "dk2": "dv2",
        }, 'r1')
        self.assertTrue(msg['message'] == "has been registered")
        ####ABLE TO RETRIEVE THE BY THE PRIMKEY AS DEFINED IN THE DOCTYPE
        doc_repo = DomainRepo("Wfdoc")
        wfdocObj_list = doc_repo.list_domain_obj(name="dv2")
        self.assertTrue(wfdocObj_list[0].name == "dv2")
        ####UPDATE DOC STATUS AS PER THE ACTION RULE
        msg = wf.action_change_status("dv2", "wfaction1", {"dk2": "dv2"})
        ### check that self._validate_editable_fields(wfdocObj, data) working
        self.assertTrue(msg['status'] == "success")
        ###wdoc should be able to understand that dk2 is editable and dk1 is not
        self.assertTrue(
            "dk2" in wfdocObj_list[0].editable_fields_at_current_status)
        self.assertTrue(
            "dk1" not in wfdocObj_list[0].editable_fields_at_current_status)
        ####SHOULD FAIL FOR INCORRECT ROLE
        wf = Workflow('doctype2', 'r1')
        try:
            msg = wf.action_change_status("dv2", "wfaction2")
        except rexc.RoleNotPermittedForThisAction as err:
            self.assertTrue(err.status == "RoleNotPermittedForThisAction")
        ###SHOULD PASS THE ROLE AND THE RULE
        wf = Workflow('doctype2', 'r2')
        msg = wf.action_change_status("dv2", "wfaction2")
        self.assertTrue(msg['status'] == "success")
        ####HAVE A TEST FOR RULE STATUS VALIDATION FAILURE
        try:
            msg = wf.action_change_status("dv2", "wfaction1")
        except rexc.WorkflowActionRuleViolation as err:
            self.assertTrue(err.status == "WorkflowActionRuleViolation")
        ####WFDOC SHOULD HAVE actions_for_current_stattus
        actions_for_current_status = wfdocObj_list[
            0].actions_for_current_status
        self.assertTrue(actions_for_current_status == ['wfaction1'])
        ###fail due to data having non editable field dk1
        ###develop logic to check if the data has actually changed
        wf = Workflow('doctype2', 'r3')
        try:
            wf.action_change_status("dv2", "wfaction3", {
                "dk1": "dv1",
                "dk2": "dv2"
            })
        except Exception as e:
            self.assertTrue(e.status == "EditNotAllowedForThisField")