def test_update_child_qty_rate_with_workflow(self): from frappe.model.workflow import apply_workflow workflow = make_sales_order_workflow() so = make_sales_order(item_code= "_Test Item", qty=1, rate=150, do_not_submit=1) apply_workflow(so, 'Approve') frappe.set_user("Administrator") user = '******' test_user = frappe.get_doc('User', user) test_user.add_roles("Sales User", "Test Junior Approver") frappe.set_user(user) # user shouldn't be able to edit since grand_total will become > 200 if qty is doubled trans_item = json.dumps([{'item_code' : '_Test Item', 'rate' : 150, 'qty' : 2, 'docname': so.items[0].name}]) self.assertRaises(frappe.ValidationError, update_child_qty_rate, 'Sales Order', trans_item, so.name) frappe.set_user("Administrator") user2 = '*****@*****.**' test_user2 = frappe.get_doc('User', user2) test_user2.add_roles("Sales User", "Test Approver") frappe.set_user(user2) # Test Approver is allowed to edit with grand_total > 200 update_child_qty_rate("Sales Order", trans_item, so.name) so.reload() self.assertEqual(so.items[0].qty, 2) frappe.set_user("Administrator") test_user.remove_roles("Sales User", "Test Junior Approver", "Test Approver") test_user2.remove_roles("Sales User", "Test Junior Approver", "Test Approver") workflow.is_active = 0 workflow.save()
def advance_wf(name): doc = frappe.get_doc("Sales Order", name) if ( doc and doc.delivery_status == "Fully Delivered" and doc.workflow_state == "Ready to Deliver" ): apply_workflow(doc, "Complete")
def test_approve(self, doc=None): '''test simple workflow''' todo = doc or self.test_default_condition() apply_workflow(todo, 'Approve') # default condition is set self.assertEqual(todo.workflow_state, 'Approved') self.assertEqual(todo.status, 'Closed') return todo
def test_approve(self, doc=None): '''test simple workflow''' todo = doc or self.test_default_condition() apply_workflow(todo, 'Approve') # default condition is set self.assertEqual(todo.workflow_state, 'Approved') self.assertEqual(todo.status, 'Closed') return todo
def test_approve(self, doc=None): """test simple workflow""" todo = doc or self.test_default_condition() apply_workflow(todo, "Approve") # default condition is set self.assertEqual(todo.workflow_state, "Approved") self.assertEqual(todo.status, "Closed") return todo
def test_update_docstatus(self): todo = create_new_todo() apply_workflow(todo, 'Approve') self.workflow.states[1].doc_status = 0 self.workflow.save() todo.reload() self.assertEqual(todo.docstatus, 0) self.workflow.states[1].doc_status = 1 self.workflow.save() todo.reload() self.assertEqual(todo.docstatus, 1)
def advance_wf(name): doc = frappe.get_doc("Sales Order", name) workflow_state = compose( lambda x: x.get("state"), excepts(StopIteration, first, lambda: {}), partial(filter, lambda x: x.get("action") == "Complete"), frappe.model.workflow.get_transitions, )(doc, workflow) if (doc and doc.delivery_status == "Fully Delivered" and doc.get(workflow.workflow_state_field) == workflow_state): apply_workflow(doc, "Complete")
def enqueue_approve(kwargs): from frappe.model.workflow import apply_workflow data = kwargs for i in data: if not i.get("salary_slip_id") or i.get("salary_slip_id") == "Total": continue doc = frappe.get_doc("Salary Slip", i.get("salary_slip_id")) if doc.workflow_state == "Pending": try: apply_workflow(doc, "Approve") frappe.db.commit() except Exception as e: frappe.log_error(e)
def update_sales_orders(sales_orders, action, lab_tech=None): transition = compose(lambda doc: apply_workflow(doc, action), partial(frappe.get_doc, "Sales Order")) mapf(transition, json.loads(sales_orders)) if lab_tech and action == "Proceed to Deliver": update = compose(lambda x: frappe.db.set_value( "Sales Order", x, "os_lab_tech", lab_tech)) mapf(update, json.loads(sales_orders))
def cancel_lrpt_doc(self): for item in self.lrpt_items: if item.reference_doctype == "Therapy Plan": cancel_tharapy_plan_doc(self.patient, item.reference_docname) frappe.db.set_value("Therapy Plan Detail", item.child_name, "is_cancelled", 1) else: if not item.reference_docname: frappe.db.set_value("Lab Prescription", item.child_name, "is_cancelled", 1) frappe.db.set_value("Radiology Procedure Prescription", item.child_name, "is_cancelled", 1) frappe.db.set_value("Procedure Prescription", item.child_name, "is_cancelled", 1) continue doc = frappe.get_doc(item.reference_doctype, item.reference_docname) if doc.docstatus < 2: try: apply_workflow(doc, "Not Serviced") if doc.meta.get_field("status"): doc.status = "Not Serviced" doc.save(ignore_permissions=True) doc.reload() if ( doc.workflow_state == "Not Serviced" or doc.workflow_state == "Submitted but Not Serviced" ): frappe.db.set_value("Lab Prescription", item.child_name, "is_cancelled", 1) frappe.db.set_value("Radiology Procedure Prescription", item.child_name, "is_cancelled", 1) frappe.db.set_value("Procedure Prescription", item.child_name, "is_cancelled", 1) except Exception: traceback = frappe.get_traceback() frappe.log_error(traceback) return self.name
def update_sales_orders(sales_orders, action, lab_tech=None): workflow_name = frappe.model.meta.get_workflow_name("Sales Order") if not workflow_name: frappe.throw(NO_WORKFLOW_MSG) if workflow_name != "Optic Store Sales Order": frappe.throw( frappe._("Operation not allowed for Workflow: {}".format( frappe.bold(workflow_name)))) transition = compose(lambda doc: apply_workflow(doc, action), partial(frappe.get_doc, "Sales Order")) mapf(transition, json.loads(sales_orders)) if lab_tech and action == "Proceed to Deliver": update = compose(lambda x: frappe.db.set_value( "Sales Order", x, "os_lab_tech", lab_tech)) mapf(update, json.loads(sales_orders))
def confirm_action(doctype, docname, user, action): if not verify_request(): return logged_in_user = frappe.session.user if logged_in_user == 'Guest' and user: # to allow user to apply action without login frappe.set_user(user) doc = frappe.get_doc(doctype, docname) newdoc = apply_workflow(doc, action) frappe.db.commit() return_success_page(newdoc) # reset session user frappe.set_user(logged_in_user)
def confirm_action(doctype, docname, user, action): if not verify_request(): return logged_in_user = frappe.session.user if logged_in_user == 'Guest' and user: # to allow user to apply action without login frappe.set_user(user) doc = frappe.get_doc(doctype, docname) newdoc = apply_workflow(doc, action) frappe.db.commit() return_success_page(newdoc) # reset session user frappe.set_user(logged_in_user)
def test_get_common_transition_actions(self): todo1 = create_new_todo() todo2 = create_new_todo() todo3 = create_new_todo() todo4 = create_new_todo() actions = get_common_transition_actions([todo1, todo2, todo3, todo4], 'ToDo') self.assertSetEqual(set(actions), set(['Approve', 'Reject'])) apply_workflow(todo1, 'Reject') apply_workflow(todo2, 'Reject') apply_workflow(todo3, 'Approve') actions = get_common_transition_actions([todo1, todo2, todo3], 'ToDo') self.assertListEqual(actions, []) actions = get_common_transition_actions([todo1, todo2], 'ToDo') self.assertListEqual(actions, ['Review'])
def test_get_common_transition_actions(self): todo1 = create_new_todo() todo2 = create_new_todo() todo3 = create_new_todo() todo4 = create_new_todo() actions = get_common_transition_actions([todo1, todo2, todo3, todo4], "ToDo") self.assertSetEqual(set(actions), set(["Approve", "Reject"])) apply_workflow(todo1, "Reject") apply_workflow(todo2, "Reject") apply_workflow(todo3, "Approve") actions = get_common_transition_actions([todo1, todo2, todo3], "ToDo") self.assertListEqual(actions, []) actions = get_common_transition_actions([todo1, todo2], "ToDo") self.assertListEqual(actions, ["Review"])
def run_testcase(self, testcase, test_suite, testcase_srno, total_testcases, suite_srno, total_suites, run_name): try: start_time = time.time() function_result = None # Populate generic test result fields test_result_doc = frappe.new_doc("Test Result") test_result_doc.test_run_name = run_name test_result_doc.test_suite = test_suite test_result_doc.action = "Test Case" testcase_doc = frappe.get_doc("Test Case", testcase) testcase_doc.testcase_type = testcase_doc.testcase_type.upper() test_result_doc.test_case = testcase_doc.name test_result_doc.test_data_id = testcase_doc.test_data test_result_doc.test_case_status = "Passed" test_result_doc.test_case_execution = "Executed" # test result fields ended print("Update function execution") print("Update function:" + test_result_doc.test_case) print( "\033[0;36;96m>> ({suite_srno}/{total_suites}) {testcase}:{testcase_type} [{testcase_srno}/{total_testcases}] :" .format(suite_srno=str(suite_srno), total_suites=str(total_suites), testcase=str(testcase), testcase_type=testcase_doc.testcase_type, testcase_srno=str(testcase_srno), total_testcases=str(total_testcases))) testdata_generator = TestDataGenerator() # Test Data record doc if testcase_doc.test_data: testdata_doc = frappe.get_doc("Test Data", testcase_doc.test_data) # cannot use insert scripts in test case data generation as doctype.name will not be recorded if (testdata_doc.use_script == 1): test_result_doc.test_case_execution = "Execution Failed" test_result_doc.execution_result = "The test data - " + testdata_doc.name + \ " selected is genereted using script for which record name cannot be recorded" test_result_doc.test_case_status = "Failed" # check if test case is create and test data already created then recreate the data testdata_doc_test_record_name = frappe.db.get_value( 'Test Run Log', { 'test_run_name': run_name, 'test_data': testcase_doc.test_data }, 'test_record') if (testdata_doc_test_record_name and testcase_doc.testcase_type == "CREATE"): testdata_doc_test_record_name = None create_test_run_log(run_name, testcase_doc.test_data, None) # get record document new_record_doc = testdata_generator.create_testdata( testcase_doc.test_data, run_name) error_message = None if (testcase_doc.testcase_type == "CREATE"): try: if new_record_doc: try: new_record_doc.save() testdata_doc_test_record_name = new_record_doc.name create_test_run_log(run_name, testcase_doc.test_data, new_record_doc.name) testdata_generator.set_record_name_child_table( new_record_doc, testdata_doc, True, run_name) print("\033[0;33;93m >>> Test Data created") except frappe.DuplicateEntryError as e: new_record_doc = resolve_duplicate_entry_error( e, testdata_doc, run_name) testdata_doc_test_record_name = new_record_doc.name create_test_run_log(run_name, testcase_doc.test_data, new_record_doc.name) testdata_generator.set_record_name_child_table( new_record_doc, testdata_doc, True, run_name) print("\033[0;33;93m >>> Test Data created") else: frappe.throw( 'Test Data {test_data} generated None doc. Please check Test Data {test_data}' .format(test_data=testcase_doc.test_data)) except Exception as e: frappe.log_error(frappe.get_traceback(), ('barista-CREATE-' + testcase_doc.name + '-' + str(e))[:error_log_title_len]) error_message = str(e) print('\033[0;31;91m Error occurred ---', str(e)) elif (testcase_doc.testcase_type == "UPDATE"): try: print("Update function execution") create_new = False if testcase_doc.testcase_doctype != testdata_doc.doctype_name: value_from_test_record_doc = frappe.db.get_value( testdata_doc.doctype_name, testdata_doc_test_record_name, testcase_doc.test_data_docfield) all_existing_docs = frappe.get_all( testcase_doc.testcase_doctype, filters={ testcase_doc.test_case_docfield: value_from_test_record_doc }) if len(all_existing_docs) == 1: existing_doc_name = all_existing_docs[0]['name'] new_record_doc = frappe.get_doc( testcase_doc.testcase_doctype, existing_doc_name) else: test_result_doc.test_case_execution = "Execution Failed" test_result_doc.execution_result = "The Test Case DocType - {testcase_doctype} with reference field {test_case_docfield} value {testdata_doc_test_record_name} records found {all_existing_docs}".format( testcase_doctype=testcase_doc.testcase_doctype, test_case_docfield=testcase_doc. test_case_docfield, testdata_doc_test_record_name= testdata_doc_test_record_name, all_existing_docs=str(len(all_existing_docs))) test_result_doc.test_case_status = "Failed" frappe.throw(test_result_doc.execution_result) # create the record if already not created if (new_record_doc and new_record_doc.name == None): try: new_record_doc.save() except frappe.UniqueValidationError as e: new_record_doc = resolve_unique_validation_error( e, testdata_doc, run_name) testdata_doc_test_record_name = new_record_doc.name create_test_run_log(run_name, testdata_doc.name, new_record_doc.name) # now take the fields to be updated update_fields = frappe.get_list( "Testdatafield", filters={"parent": testcase_doc.name}) fields = frappe.get_meta( testcase_doc.testcase_doctype).fields for update_field in update_fields: update_field_doc = frappe.get_doc( "Testdatafield", update_field['name']) for field in fields: if field.fieldname == update_field_doc.docfield_fieldname: field_doc = field break print("Field Name:" + update_field_doc.docfield_fieldname) if update_field_doc.docfield_fieldname == "name": new_name = update_field_doc.docfield_value print("Field Value:" + new_name) if update_field_doc.docfield_code_value == "Code": new_name = eval(update_field_doc.docfield_code) rd.rename_doc(update_field_doc.doctype_name, testdata_doc_test_record_name, new_name, force=True) testdata_doc_test_record_name = new_name new_record_doc = frappe.get_doc( update_field_doc.doctype_name, new_name) create_test_run_log(run_name, testdata_doc.name, new_record_doc.name) elif new_record_doc and update_field_doc.docfield_fieldname == "docstatus": new_record_doc.set( update_field_doc.docfield_fieldname, int(update_field_doc.docfield_value)) elif new_record_doc: if (field_doc.fieldtype == "Table"): # if it is table then user will have to add multiple rows for multiple records. # each test data field will link to one record. child_testdata_doc = frappe.get_doc( "Test Data", update_field_doc.linkfield_name) if (child_testdata_doc.doctype_type == "Transaction"): create_new = True child_doc = testdata_generator.create_testdata( update_field_doc.linkfield_name, run_name) child_doc.parentfield = field_doc.fieldname child_doc.parenttype = testcase_doc.testcase_doctype new_record_doc.append(field_doc.fieldname, child_doc) elif (field_doc.fieldtype in ["Link", "Dynamic Link"] and update_field_doc.docfield_code_value == "Fixed Value"): new_record_doc.set( field_doc.fieldname, update_field_doc.docfield_value) elif (field_doc.fieldtype in ["Link", "Dynamic Link"]): child_testdata_doc = frappe.get_doc( 'Test Data', update_field_doc.linkfield_name) if (child_testdata_doc.doctype_type == "Transaction"): create_test_run_log( run_name, child_testdata_doc.name, None) child_doc = testdata_generator.create_testdata( update_field_doc.linkfield_name, run_name) try: if child_doc: child_doc.save() else: frappe.throw( "Child Doc is None. Test Data of Child {linkfield_name}. Test Data of Parent {name}" .format( linkfield_name=update_field_doc .linkfield_name, name=testdata_doc.name)) except frappe.DuplicateEntryError as e: child_doc = resolve_duplicate_entry_error( e, child_testdata_doc, run_name) except frappe.UniqueValidationError as e: child_doc = resolve_unique_validation_error( e, child_testdata_doc, run_name) child_testdata_doc_test_record_name = child_doc.name create_test_run_log(run_name, child_testdata_doc.name, child_doc.name) new_record_doc.set(field_doc.fieldname, child_doc.name) # for rest of data type.. either it should be code or fixed value elif (update_field_doc.docfield_code_value == "Code"): if update_field_doc.docfield_code and not update_field_doc.linkfield_name: new_record_doc.set( field_doc.fieldname, eval(update_field_doc.docfield_code)) if not update_field_doc.docfield_code and update_field_doc.linkfield_name: value = frappe.db.get_value( 'Test Run Log', { 'test_run_name': run_name, 'test_data': update_field_doc.linkfield_name }, 'test_record') new_record_doc.set(field_doc.fieldname, value) elif new_record_doc: new_record_doc.set( update_field_doc.docfield_fieldname, update_field_doc.docfield_value) try: if new_record_doc: new_record_doc.save() print("\033[0;33;93m >>> Test Data updated") else: frappe.throw( "Test Data {name} generated None doc. Please check Test Data {test_data}" .format(name=testdata_doc.name, test_data=testcase_doc.test_data)) except frappe.UniqueValidationError as e: new_record_doc = resolve_unique_validation_error( e, testdata_doc, run_name) except Exception as e: frappe.log_error(frappe.get_traceback(), ('barista-UPDATE-' + testcase_doc.name + '-' + str(e))[:error_log_title_len]) error_message = str(e) print('\033[0;31;91m Error occurred ---', str(e)) testdata_generator.set_record_name_child_table( new_record_doc, testcase_doc, create_new, run_name) elif (testcase_doc.testcase_type == "READ"): pass elif (testcase_doc.testcase_type == "DELETE"): try: record_doc = frappe.get_doc(testdata_doc.doctype_name, testdata_doc_test_record_name) record_doc.delete() except Exception as e: frappe.log_error(frappe.get_traceback(), ('barista-' + testcase_doc.name + '-DELETE-' + str(e))[:error_log_title_len]) error_message = str(e) print("\033[0;31;91m >>> Error in deleting - " + str(e)) elif (testcase_doc.testcase_type == "WORKFLOW"): try: start_time = time.time() current_workflow_state = None if (new_record_doc and new_record_doc.name == None): current_workflow_state = new_record_doc.workflow_state try: new_record_doc = new_record_doc.save() except frappe.UniqueValidationError as e: new_record_doc = resolve_unique_validation_error( e, testdata_doc, run_name) testdata_doc_test_record_name = new_record_doc.name create_test_run_log(run_name, testdata_doc.name, new_record_doc.name) apply_workflow(new_record_doc, testcase_doc.workflow_state) print("\033[0;32;92m >>> Workflow Applied") except Exception as e: frappe.log_error( frappe.get_traceback(), ("""barista-WORKFLOW-{testcase_doc.name}-{str( e)}-DocType-[{doctype_name}]-WorkflowState-[{current_workflow_state}]-Action-[{workflow_state}]""" .format(name=testcase_doc.name, current_workflow_state=current_workflow_state, doctype_name=testdata_doc.doctype_name, workflow_state=testcase_doc.workflow_state) )[:error_log_title_len]) error_message = str(e) print( "\033[0;31;91m >>> Error in applying Workflow - " + str(e)) elif (testcase_doc.testcase_type == "FUNCTION"): kwargs = {} error_message = "" try: for param in testcase_doc.function_parameters: parameter = param.parameter print("------1-----") print(parameter) if param.value and param.value.strip()[0] in [ '{', '[' ]: value = eval(param.value) else: value = param.value kwargs[parameter] = value print("------2-----") print(kwargs) if param.test_data: test_record_name = frappe.db.get_value( 'Test Run Log', { 'test_run_name': run_name, 'test_data': param.test_data }, 'test_record') print("-----3------") print(test_record_name) test_record_doctype = frappe.db.get_value( 'Test Data', param.test_data, 'doctype_name') print("-----4------") print(test_record_doctype) test_record_doc = frappe.get_doc( test_record_doctype, test_record_name) print("-----5------") print(test_record_doc) if param.is_object == 1: kwargs[parameter] = test_record_doc.as_dict() else: kwargs[parameter] = test_record_doc.get( param.field) print("-----6------") print(kwargs) print("\033[0;33;93m >>> Executing Function --", testcase_doc.function_name) if testcase_doc.json_parameter and testcase_doc.json_parameter.strip( ) != '': context_dict = {} resolved_jinja = ' ' if testcase_doc.testcase_doctype and testcase_doc.test_data: test_record_name = frappe.db.get_value( 'Test Run Log', { 'test_run_name': run_name, 'test_data': testcase_doc.test_data }, 'test_record') context = frappe.get_doc( testcase_doc.testcase_doctype, test_record_name).as_dict() context_dict = {"doc": context} try: validate_template(testcase_doc.json_parameter) resolved_jinja = render_template( testcase_doc.json_parameter, context_dict) except Exception as e: print( "\033[0;31;91m >>>> Error in Json Parameter\n ", str(e)) kwargs.update(eval(str(resolved_jinja))) method = testcase_doc.function_name if method and '.' in method: print("------method------") args = [] function_result = frappe.get_attr(method)(*args, **kwargs) print("\033>>>>") print("\033" + str(function_result)) else: test_data_record_name = frappe.db.get_value( 'Test Run Log', { 'test_run_name': run_name, 'test_data': testcase_doc.test_data }, 'test_record') test_record_doc = frappe.get_doc( testcase_doc.testcase_doctype, test_data_record_name) function_result = test_record_doc.run_method( method, **kwargs) print("\033>>>>") print("\033" + str(function_result)) print("\033[0;32;92m >>> Function Executed") except Exception as e: frappe.log_error(frappe.get_traceback(), ('barista-FUNCTION-' + testcase_doc.name + '-' + str(e))[:error_log_title_len]) error_message = str(e) print( "\033[0;31;91m >>>> Execution of function failed\n Error occurred :", str(e)) test_result_doc.execution_time = get_execution_time(start_time) assertions = frappe.get_list("Assertion", filters={'parent': testcase}) if len(assertions) == 0: test_result_doc.execution_result = 'Assertions are not present in the TestCase. Please add atleast one assertion.' test_result_doc.test_case_status = "Failed" test_result_doc.save() for assertion in assertions: self.process_assertion(assertion, testcase_doc, run_name, error_message, function_result, test_result_doc) except Exception as e: frappe.log_error(frappe.get_traceback(), ('barista-Critical Error-' + testcase + '-' + str(e))[:error_log_title_len]) test_result_doc.test_case_execution = "Execution Failed" test_result_doc.execution_result = str(e) test_result_doc.test_case_status = "Failed" test_result_doc.save() finally: print("\033[0;36;96m>> " + "Execution Ended \n\n") test_result_doc.save()
def advance_wf(name): doc = frappe.get_doc("Sales Order", name) if doc and doc.workflow_state == "Ready to Deliver": apply_workflow(doc, "Complete")