Merge pull request #24742 from deepeshgarg007/project_filter_search_fields
fix: Add searchfields in project query
This commit is contained in:
		
						commit
						d7a81be56d
					
				| @ -17,319 +17,326 @@ class CircularReferenceError(frappe.ValidationError): pass | ||||
| class EndDateCannotBeGreaterThanProjectEndDateError(frappe.ValidationError): pass | ||||
| 
 | ||||
| class Task(NestedSet): | ||||
|     nsm_parent_field = 'parent_task' | ||||
| 	nsm_parent_field = 'parent_task' | ||||
| 
 | ||||
|     def get_feed(self): | ||||
|         return '{0}: {1}'.format(_(self.status), self.subject) | ||||
| 	def get_feed(self): | ||||
| 		return '{0}: {1}'.format(_(self.status), self.subject) | ||||
| 
 | ||||
|     def get_customer_details(self): | ||||
|         cust = frappe.db.sql("select customer_name from `tabCustomer` where name=%s", self.customer) | ||||
|         if cust: | ||||
|             ret = {'customer_name': cust and cust[0][0] or ''} | ||||
|             return ret | ||||
| 	def get_customer_details(self): | ||||
| 		cust = frappe.db.sql("select customer_name from `tabCustomer` where name=%s", self.customer) | ||||
| 		if cust: | ||||
| 			ret = {'customer_name': cust and cust[0][0] or ''} | ||||
| 			return ret | ||||
| 
 | ||||
|     def validate(self): | ||||
|         self.validate_dates() | ||||
|         self.validate_parent_expected_end_date() | ||||
|         self.validate_parent_project_dates() | ||||
|         self.validate_progress() | ||||
|         self.validate_status() | ||||
|         self.update_depends_on() | ||||
|         self.validate_dependencies_for_template_task() | ||||
| 	def validate(self): | ||||
| 		self.validate_dates() | ||||
| 		self.validate_parent_expected_end_date() | ||||
| 		self.validate_parent_project_dates() | ||||
| 		self.validate_progress() | ||||
| 		self.validate_status() | ||||
| 		self.update_depends_on() | ||||
| 		self.validate_dependencies_for_template_task() | ||||
| 
 | ||||
|     def validate_dates(self): | ||||
|         if self.exp_start_date and self.exp_end_date and getdate(self.exp_start_date) > getdate(self.exp_end_date): | ||||
|             frappe.throw(_("{0} can not be greater than {1}").format(frappe.bold("Expected Start Date"), \ | ||||
|                 frappe.bold("Expected End Date"))) | ||||
| 	def validate_dates(self): | ||||
| 		if self.exp_start_date and self.exp_end_date and getdate(self.exp_start_date) > getdate(self.exp_end_date): | ||||
| 			frappe.throw(_("{0} can not be greater than {1}").format(frappe.bold("Expected Start Date"), \ | ||||
| 				frappe.bold("Expected End Date"))) | ||||
| 
 | ||||
|         if self.act_start_date and self.act_end_date and getdate(self.act_start_date) > getdate(self.act_end_date): | ||||
|             frappe.throw(_("{0} can not be greater than {1}").format(frappe.bold("Actual Start Date"), \ | ||||
|                 frappe.bold("Actual End Date"))) | ||||
| 		if self.act_start_date and self.act_end_date and getdate(self.act_start_date) > getdate(self.act_end_date): | ||||
| 			frappe.throw(_("{0} can not be greater than {1}").format(frappe.bold("Actual Start Date"), \ | ||||
| 				frappe.bold("Actual End Date"))) | ||||
| 
 | ||||
|     def validate_parent_expected_end_date(self): | ||||
|         if self.parent_task: | ||||
|             parent_exp_end_date = frappe.db.get_value("Task", self.parent_task, "exp_end_date") | ||||
|             if parent_exp_end_date and getdate(self.get("exp_end_date")) > getdate(parent_exp_end_date): | ||||
|                 frappe.throw(_("Expected End Date should be less than or equal to parent task's Expected End Date {0}.").format(getdate(parent_exp_end_date))) | ||||
| 	def validate_parent_expected_end_date(self): | ||||
| 		if self.parent_task: | ||||
| 			parent_exp_end_date = frappe.db.get_value("Task", self.parent_task, "exp_end_date") | ||||
| 			if parent_exp_end_date and getdate(self.get("exp_end_date")) > getdate(parent_exp_end_date): | ||||
| 				frappe.throw(_("Expected End Date should be less than or equal to parent task's Expected End Date {0}.").format(getdate(parent_exp_end_date))) | ||||
| 
 | ||||
|     def validate_parent_project_dates(self): | ||||
|         if not self.project or frappe.flags.in_test: | ||||
|             return | ||||
| 	def validate_parent_project_dates(self): | ||||
| 		if not self.project or frappe.flags.in_test: | ||||
| 			return | ||||
| 
 | ||||
|         expected_end_date = frappe.db.get_value("Project", self.project, "expected_end_date") | ||||
| 		expected_end_date = frappe.db.get_value("Project", self.project, "expected_end_date") | ||||
| 
 | ||||
|         if expected_end_date: | ||||
|             validate_project_dates(getdate(expected_end_date), self, "exp_start_date", "exp_end_date", "Expected") | ||||
|             validate_project_dates(getdate(expected_end_date), self, "act_start_date", "act_end_date", "Actual") | ||||
| 		if expected_end_date: | ||||
| 			validate_project_dates(getdate(expected_end_date), self, "exp_start_date", "exp_end_date", "Expected") | ||||
| 			validate_project_dates(getdate(expected_end_date), self, "act_start_date", "act_end_date", "Actual") | ||||
| 
 | ||||
|     def validate_status(self): | ||||
|         if self.is_template and self.status != "Template": | ||||
|             self.status = "Template" | ||||
|         if self.status!=self.get_db_value("status") and self.status == "Completed": | ||||
|             for d in self.depends_on: | ||||
|                 if frappe.db.get_value("Task", d.task, "status") not in ("Completed", "Cancelled"): | ||||
|                     frappe.throw(_("Cannot complete task {0} as its dependant task {1} are not ccompleted / cancelled.").format(frappe.bold(self.name), frappe.bold(d.task))) | ||||
| 	def validate_status(self): | ||||
| 		if self.is_template and self.status != "Template": | ||||
| 			self.status = "Template" | ||||
| 		if self.status!=self.get_db_value("status") and self.status == "Completed": | ||||
| 			for d in self.depends_on: | ||||
| 				if frappe.db.get_value("Task", d.task, "status") not in ("Completed", "Cancelled"): | ||||
| 					frappe.throw(_("Cannot complete task {0} as its dependant task {1} are not ccompleted / cancelled.").format(frappe.bold(self.name), frappe.bold(d.task))) | ||||
| 
 | ||||
|             close_all_assignments(self.doctype, self.name) | ||||
| 			close_all_assignments(self.doctype, self.name) | ||||
| 
 | ||||
|     def validate_progress(self): | ||||
|         if flt(self.progress or 0) > 100: | ||||
|             frappe.throw(_("Progress % for a task cannot be more than 100.")) | ||||
| 	def validate_progress(self): | ||||
| 		if flt(self.progress or 0) > 100: | ||||
| 			frappe.throw(_("Progress % for a task cannot be more than 100.")) | ||||
| 
 | ||||
|         if flt(self.progress) == 100: | ||||
|             self.status = 'Completed' | ||||
| 		if flt(self.progress) == 100: | ||||
| 			self.status = 'Completed' | ||||
| 
 | ||||
|         if self.status == 'Completed': | ||||
|             self.progress = 100 | ||||
| 		if self.status == 'Completed': | ||||
| 			self.progress = 100 | ||||
| 
 | ||||
|     def validate_dependencies_for_template_task(self): | ||||
|         if self.is_template: | ||||
|             self.validate_parent_template_task() | ||||
|             self.validate_depends_on_tasks() | ||||
|          | ||||
|     def validate_parent_template_task(self): | ||||
|         if self.parent_task: | ||||
|             if not frappe.db.get_value("Task", self.parent_task, "is_template"): | ||||
|                 parent_task_format = """<a href="#Form/Task/{0}">{0}</a>""".format(self.parent_task) | ||||
|                 frappe.throw(_("Parent Task {0} is not a Template Task").format(parent_task_format)) | ||||
|                  | ||||
|     def validate_depends_on_tasks(self): | ||||
|         if self.depends_on: | ||||
|             for task in self.depends_on: | ||||
|                 if not frappe.db.get_value("Task", task.task, "is_template"): | ||||
|                     dependent_task_format = """<a href="#Form/Task/{0}">{0}</a>""".format(task.task) | ||||
|                     frappe.throw(_("Dependent Task {0} is not a Template Task").format(dependent_task_format)) | ||||
| 	def validate_dependencies_for_template_task(self): | ||||
| 		if self.is_template: | ||||
| 			self.validate_parent_template_task() | ||||
| 			self.validate_depends_on_tasks() | ||||
| 
 | ||||
|     def update_depends_on(self): | ||||
|         depends_on_tasks = self.depends_on_tasks or "" | ||||
|         for d in self.depends_on: | ||||
|             if d.task and d.task not in depends_on_tasks: | ||||
|                 depends_on_tasks += d.task + "," | ||||
|         self.depends_on_tasks = depends_on_tasks | ||||
| 	def validate_parent_template_task(self): | ||||
| 		if self.parent_task: | ||||
| 			if not frappe.db.get_value("Task", self.parent_task, "is_template"): | ||||
| 				parent_task_format = """<a href="#Form/Task/{0}">{0}</a>""".format(self.parent_task) | ||||
| 				frappe.throw(_("Parent Task {0} is not a Template Task").format(parent_task_format)) | ||||
| 
 | ||||
|     def update_nsm_model(self): | ||||
|         frappe.utils.nestedset.update_nsm(self) | ||||
| 	def validate_depends_on_tasks(self): | ||||
| 		if self.depends_on: | ||||
| 			for task in self.depends_on: | ||||
| 				if not frappe.db.get_value("Task", task.task, "is_template"): | ||||
| 					dependent_task_format = """<a href="#Form/Task/{0}">{0}</a>""".format(task.task) | ||||
| 					frappe.throw(_("Dependent Task {0} is not a Template Task").format(dependent_task_format)) | ||||
| 
 | ||||
|     def on_update(self): | ||||
|         self.update_nsm_model() | ||||
|         self.check_recursion() | ||||
|         self.reschedule_dependent_tasks() | ||||
|         self.update_project() | ||||
|         self.unassign_todo() | ||||
|         self.populate_depends_on() | ||||
| 	def update_depends_on(self): | ||||
| 		depends_on_tasks = self.depends_on_tasks or "" | ||||
| 		for d in self.depends_on: | ||||
| 			if d.task and d.task not in depends_on_tasks: | ||||
| 				depends_on_tasks += d.task + "," | ||||
| 		self.depends_on_tasks = depends_on_tasks | ||||
| 
 | ||||
|     def unassign_todo(self): | ||||
|         if self.status == "Completed": | ||||
|             close_all_assignments(self.doctype, self.name) | ||||
|         if self.status == "Cancelled": | ||||
|             clear(self.doctype, self.name) | ||||
| 	def update_nsm_model(self): | ||||
| 		frappe.utils.nestedset.update_nsm(self) | ||||
| 
 | ||||
|     def update_total_expense_claim(self): | ||||
|         self.total_expense_claim = frappe.db.sql("""select sum(total_sanctioned_amount) from `tabExpense Claim` | ||||
|             where project = %s and task = %s and docstatus=1""",(self.project, self.name))[0][0] | ||||
| 	def on_update(self): | ||||
| 		self.update_nsm_model() | ||||
| 		self.check_recursion() | ||||
| 		self.reschedule_dependent_tasks() | ||||
| 		self.update_project() | ||||
| 		self.unassign_todo() | ||||
| 		self.populate_depends_on() | ||||
| 
 | ||||
|     def update_time_and_costing(self): | ||||
|         tl = frappe.db.sql("""select min(from_time) as start_date, max(to_time) as end_date, | ||||
|             sum(billing_amount) as total_billing_amount, sum(costing_amount) as total_costing_amount, | ||||
|             sum(hours) as time from `tabTimesheet Detail` where task = %s and docstatus=1""" | ||||
|             ,self.name, as_dict=1)[0] | ||||
|         if self.status == "Open": | ||||
|             self.status = "Working" | ||||
|         self.total_costing_amount= tl.total_costing_amount | ||||
|         self.total_billing_amount= tl.total_billing_amount | ||||
|         self.actual_time= tl.time | ||||
|         self.act_start_date= tl.start_date | ||||
|         self.act_end_date= tl.end_date | ||||
| 	def unassign_todo(self): | ||||
| 		if self.status == "Completed": | ||||
| 			close_all_assignments(self.doctype, self.name) | ||||
| 		if self.status == "Cancelled": | ||||
| 			clear(self.doctype, self.name) | ||||
| 
 | ||||
|     def update_project(self): | ||||
|         if self.project and not self.flags.from_project: | ||||
|             frappe.get_cached_doc("Project", self.project).update_project() | ||||
| 	def update_total_expense_claim(self): | ||||
| 		self.total_expense_claim = frappe.db.sql("""select sum(total_sanctioned_amount) from `tabExpense Claim` | ||||
| 			where project = %s and task = %s and docstatus=1""",(self.project, self.name))[0][0] | ||||
| 
 | ||||
|     def check_recursion(self): | ||||
|         if self.flags.ignore_recursion_check: return | ||||
|         check_list = [['task', 'parent'], ['parent', 'task']] | ||||
|         for d in check_list: | ||||
|             task_list, count = [self.name], 0 | ||||
|             while (len(task_list) > count ): | ||||
|                 tasks = frappe.db.sql(" select %s from `tabTask Depends On` where %s = %s " % | ||||
|                     (d[0], d[1], '%s'), cstr(task_list[count])) | ||||
|                 count = count + 1 | ||||
|                 for b in tasks: | ||||
|                     if b[0] == self.name: | ||||
|                         frappe.throw(_("Circular Reference Error"), CircularReferenceError) | ||||
|                     if b[0]: | ||||
|                         task_list.append(b[0]) | ||||
| 	def update_time_and_costing(self): | ||||
| 		tl = frappe.db.sql("""select min(from_time) as start_date, max(to_time) as end_date, | ||||
| 			sum(billing_amount) as total_billing_amount, sum(costing_amount) as total_costing_amount, | ||||
| 			sum(hours) as time from `tabTimesheet Detail` where task = %s and docstatus=1""" | ||||
| 			,self.name, as_dict=1)[0] | ||||
| 		if self.status == "Open": | ||||
| 			self.status = "Working" | ||||
| 		self.total_costing_amount= tl.total_costing_amount | ||||
| 		self.total_billing_amount= tl.total_billing_amount | ||||
| 		self.actual_time= tl.time | ||||
| 		self.act_start_date= tl.start_date | ||||
| 		self.act_end_date= tl.end_date | ||||
| 
 | ||||
|                 if count == 15: | ||||
|                     break | ||||
| 	def update_project(self): | ||||
| 		if self.project and not self.flags.from_project: | ||||
| 			frappe.get_cached_doc("Project", self.project).update_project() | ||||
| 
 | ||||
|     def reschedule_dependent_tasks(self): | ||||
|         end_date = self.exp_end_date or self.act_end_date | ||||
|         if end_date: | ||||
|             for task_name in frappe.db.sql(""" | ||||
|                 select name from `tabTask` as parent | ||||
|                 where parent.project = %(project)s | ||||
|                     and parent.name in ( | ||||
|                         select parent from `tabTask Depends On` as child | ||||
|                         where child.task = %(task)s and child.project = %(project)s) | ||||
|             """, {'project': self.project, 'task':self.name }, as_dict=1): | ||||
|                 task = frappe.get_doc("Task", task_name.name) | ||||
|                 if task.exp_start_date and task.exp_end_date and task.exp_start_date < getdate(end_date) and task.status == "Open": | ||||
|                     task_duration = date_diff(task.exp_end_date, task.exp_start_date) | ||||
|                     task.exp_start_date = add_days(end_date, 1) | ||||
|                     task.exp_end_date = add_days(task.exp_start_date, task_duration) | ||||
|                     task.flags.ignore_recursion_check = True | ||||
|                     task.save() | ||||
| 	def check_recursion(self): | ||||
| 		if self.flags.ignore_recursion_check: return | ||||
| 		check_list = [['task', 'parent'], ['parent', 'task']] | ||||
| 		for d in check_list: | ||||
| 			task_list, count = [self.name], 0 | ||||
| 			while (len(task_list) > count ): | ||||
| 				tasks = frappe.db.sql(" select %s from `tabTask Depends On` where %s = %s " % | ||||
| 					(d[0], d[1], '%s'), cstr(task_list[count])) | ||||
| 				count = count + 1 | ||||
| 				for b in tasks: | ||||
| 					if b[0] == self.name: | ||||
| 						frappe.throw(_("Circular Reference Error"), CircularReferenceError) | ||||
| 					if b[0]: | ||||
| 						task_list.append(b[0]) | ||||
| 
 | ||||
|     def has_webform_permission(self): | ||||
|         project_user = frappe.db.get_value("Project User", {"parent": self.project, "user":frappe.session.user} , "user") | ||||
|         if project_user: | ||||
|             return True | ||||
| 				if count == 15: | ||||
| 					break | ||||
| 
 | ||||
|     def populate_depends_on(self): | ||||
|         if self.parent_task: | ||||
|             parent = frappe.get_doc('Task', self.parent_task) | ||||
|             if self.name not in [row.task for row in parent.depends_on]: | ||||
|                 parent.append("depends_on", { | ||||
|                     "doctype": "Task Depends On", | ||||
|                     "task": self.name, | ||||
|                     "subject": self.subject | ||||
|                 }) | ||||
|                 parent.save() | ||||
| 	def reschedule_dependent_tasks(self): | ||||
| 		end_date = self.exp_end_date or self.act_end_date | ||||
| 		if end_date: | ||||
| 			for task_name in frappe.db.sql(""" | ||||
| 				select name from `tabTask` as parent | ||||
| 				where parent.project = %(project)s | ||||
| 					and parent.name in ( | ||||
| 						select parent from `tabTask Depends On` as child | ||||
| 						where child.task = %(task)s and child.project = %(project)s) | ||||
| 			""", {'project': self.project, 'task':self.name }, as_dict=1): | ||||
| 				task = frappe.get_doc("Task", task_name.name) | ||||
| 				if task.exp_start_date and task.exp_end_date and task.exp_start_date < getdate(end_date) and task.status == "Open": | ||||
| 					task_duration = date_diff(task.exp_end_date, task.exp_start_date) | ||||
| 					task.exp_start_date = add_days(end_date, 1) | ||||
| 					task.exp_end_date = add_days(task.exp_start_date, task_duration) | ||||
| 					task.flags.ignore_recursion_check = True | ||||
| 					task.save() | ||||
| 
 | ||||
|     def on_trash(self): | ||||
|         if check_if_child_exists(self.name): | ||||
|             throw(_("Child Task exists for this Task. You can not delete this Task.")) | ||||
| 	def has_webform_permission(self): | ||||
| 		project_user = frappe.db.get_value("Project User", {"parent": self.project, "user":frappe.session.user} , "user") | ||||
| 		if project_user: | ||||
| 			return True | ||||
| 
 | ||||
|         self.update_nsm_model() | ||||
| 	def populate_depends_on(self): | ||||
| 		if self.parent_task: | ||||
| 			parent = frappe.get_doc('Task', self.parent_task) | ||||
| 			if self.name not in [row.task for row in parent.depends_on]: | ||||
| 				parent.append("depends_on", { | ||||
| 					"doctype": "Task Depends On", | ||||
| 					"task": self.name, | ||||
| 					"subject": self.subject | ||||
| 				}) | ||||
| 				parent.save() | ||||
| 
 | ||||
|     def after_delete(self): | ||||
|         self.update_project() | ||||
| 	def on_trash(self): | ||||
| 		if check_if_child_exists(self.name): | ||||
| 			throw(_("Child Task exists for this Task. You can not delete this Task.")) | ||||
| 
 | ||||
|     def update_status(self): | ||||
|         if self.status not in ('Cancelled', 'Completed') and self.exp_end_date: | ||||
|             from datetime import datetime | ||||
|             if self.exp_end_date < datetime.now().date(): | ||||
|                 self.db_set('status', 'Overdue', update_modified=False) | ||||
|                 self.update_project() | ||||
| 		self.update_nsm_model() | ||||
| 
 | ||||
| 	def after_delete(self): | ||||
| 		self.update_project() | ||||
| 
 | ||||
| 	def update_status(self): | ||||
| 		if self.status not in ('Cancelled', 'Completed') and self.exp_end_date: | ||||
| 			from datetime import datetime | ||||
| 			if self.exp_end_date < datetime.now().date(): | ||||
| 				self.db_set('status', 'Overdue', update_modified=False) | ||||
| 				self.update_project() | ||||
| 
 | ||||
| @frappe.whitelist() | ||||
| def check_if_child_exists(name): | ||||
|     child_tasks = frappe.get_all("Task", filters={"parent_task": name}) | ||||
|     child_tasks = [get_link_to_form("Task", task.name) for task in child_tasks] | ||||
|     return child_tasks | ||||
| 	child_tasks = frappe.get_all("Task", filters={"parent_task": name}) | ||||
| 	child_tasks = [get_link_to_form("Task", task.name) for task in child_tasks] | ||||
| 	return child_tasks | ||||
| 
 | ||||
| 
 | ||||
| @frappe.whitelist() | ||||
| @frappe.validate_and_sanitize_search_inputs | ||||
| def get_project(doctype, txt, searchfield, start, page_len, filters): | ||||
|     from erpnext.controllers.queries import get_match_cond | ||||
|     return frappe.db.sql(""" select name from `tabProject` | ||||
|             where %(key)s like %(txt)s | ||||
|                 %(mcond)s | ||||
|             order by name | ||||
|             limit %(start)s, %(page_len)s""" % { | ||||
|                 'key': searchfield, | ||||
|                 'txt': frappe.db.escape('%' + txt + '%'), | ||||
|                 'mcond':get_match_cond(doctype), | ||||
|                 'start': start, | ||||
|                 'page_len': page_len | ||||
|             }) | ||||
| 	from erpnext.controllers.queries import get_match_cond | ||||
| 	meta = frappe.get_meta(doctype) | ||||
| 	searchfields = meta.get_search_fields() | ||||
| 	search_columns = ", " + ", ".join(searchfields) if searchfields else '' | ||||
| 	search_cond = " or " + " or ".join([field + " like %(txt)s" for field in searchfields]) | ||||
| 
 | ||||
| 	return frappe.db.sql(""" select name {search_columns} from `tabProject` | ||||
| 		where %(key)s like %(txt)s | ||||
| 			%(mcond)s | ||||
| 			{search_condition} | ||||
| 		order by name | ||||
| 		limit %(start)s, %(page_len)s""".format(search_columns = search_columns, | ||||
| 			search_condition=search_cond), { | ||||
| 			'key': searchfield, | ||||
| 			'txt': '%' + txt + '%', | ||||
| 			'mcond':get_match_cond(doctype), | ||||
| 			'start': start, | ||||
| 			'page_len': page_len | ||||
| 		}) | ||||
| 
 | ||||
| 
 | ||||
| @frappe.whitelist() | ||||
| def set_multiple_status(names, status): | ||||
|     names = json.loads(names) | ||||
|     for name in names: | ||||
|         task = frappe.get_doc("Task", name) | ||||
|         task.status = status | ||||
|         task.save() | ||||
| 	names = json.loads(names) | ||||
| 	for name in names: | ||||
| 		task = frappe.get_doc("Task", name) | ||||
| 		task.status = status | ||||
| 		task.save() | ||||
| 
 | ||||
| def set_tasks_as_overdue(): | ||||
|     tasks = frappe.get_all("Task", filters={"status": ["not in", ["Cancelled", "Completed"]]}, fields=["name", "status", "review_date"]) | ||||
|     for task in tasks: | ||||
|         if task.status == "Pending Review": | ||||
|             if getdate(task.review_date) > getdate(today()): | ||||
|                 continue | ||||
|         frappe.get_doc("Task", task.name).update_status() | ||||
| 	tasks = frappe.get_all("Task", filters={"status": ["not in", ["Cancelled", "Completed"]]}, fields=["name", "status", "review_date"]) | ||||
| 	for task in tasks: | ||||
| 		if task.status == "Pending Review": | ||||
| 			if getdate(task.review_date) > getdate(today()): | ||||
| 				continue | ||||
| 		frappe.get_doc("Task", task.name).update_status() | ||||
| 
 | ||||
| 
 | ||||
| @frappe.whitelist() | ||||
| def make_timesheet(source_name, target_doc=None, ignore_permissions=False): | ||||
|     def set_missing_values(source, target): | ||||
|         target.append("time_logs", { | ||||
|             "hours": source.actual_time, | ||||
|             "completed": source.status == "Completed", | ||||
|             "project": source.project, | ||||
|             "task": source.name | ||||
|         }) | ||||
| 	def set_missing_values(source, target): | ||||
| 		target.append("time_logs", { | ||||
| 			"hours": source.actual_time, | ||||
| 			"completed": source.status == "Completed", | ||||
| 			"project": source.project, | ||||
| 			"task": source.name | ||||
| 		}) | ||||
| 
 | ||||
|     doclist = get_mapped_doc("Task", source_name, { | ||||
|             "Task": { | ||||
|                 "doctype": "Timesheet" | ||||
|             } | ||||
|         }, target_doc, postprocess=set_missing_values, ignore_permissions=ignore_permissions) | ||||
| 	doclist = get_mapped_doc("Task", source_name, { | ||||
| 			"Task": { | ||||
| 				"doctype": "Timesheet" | ||||
| 			} | ||||
| 		}, target_doc, postprocess=set_missing_values, ignore_permissions=ignore_permissions) | ||||
| 
 | ||||
|     return doclist | ||||
| 	return doclist | ||||
| 
 | ||||
| 
 | ||||
| @frappe.whitelist() | ||||
| def get_children(doctype, parent, task=None, project=None, is_root=False): | ||||
| 
 | ||||
|     filters = [['docstatus', '<', '2']] | ||||
| 	filters = [['docstatus', '<', '2']] | ||||
| 
 | ||||
|     if task: | ||||
|         filters.append(['parent_task', '=', task]) | ||||
|     elif parent and not is_root: | ||||
|         # via expand child | ||||
|         filters.append(['parent_task', '=', parent]) | ||||
|     else: | ||||
|         filters.append(['ifnull(`parent_task`, "")', '=', '']) | ||||
| 	if task: | ||||
| 		filters.append(['parent_task', '=', task]) | ||||
| 	elif parent and not is_root: | ||||
| 		# via expand child | ||||
| 		filters.append(['parent_task', '=', parent]) | ||||
| 	else: | ||||
| 		filters.append(['ifnull(`parent_task`, "")', '=', '']) | ||||
| 
 | ||||
|     if project: | ||||
|         filters.append(['project', '=', project]) | ||||
| 	if project: | ||||
| 		filters.append(['project', '=', project]) | ||||
| 
 | ||||
|     tasks = frappe.get_list(doctype, fields=[ | ||||
|         'name as value', | ||||
|         'subject as title', | ||||
|         'is_group as expandable' | ||||
|     ], filters=filters, order_by='name') | ||||
| 	tasks = frappe.get_list(doctype, fields=[ | ||||
| 		'name as value', | ||||
| 		'subject as title', | ||||
| 		'is_group as expandable' | ||||
| 	], filters=filters, order_by='name') | ||||
| 
 | ||||
|     # return tasks | ||||
|     return tasks | ||||
| 	# return tasks | ||||
| 	return tasks | ||||
| 
 | ||||
| @frappe.whitelist() | ||||
| def add_node(): | ||||
|     from frappe.desk.treeview import make_tree_args | ||||
|     args = frappe.form_dict | ||||
|     args.update({ | ||||
|         "name_field": "subject" | ||||
|     }) | ||||
|     args = make_tree_args(**args) | ||||
| 	from frappe.desk.treeview import make_tree_args | ||||
| 	args = frappe.form_dict | ||||
| 	args.update({ | ||||
| 		"name_field": "subject" | ||||
| 	}) | ||||
| 	args = make_tree_args(**args) | ||||
| 
 | ||||
|     if args.parent_task == 'All Tasks' or args.parent_task == args.project: | ||||
|         args.parent_task = None | ||||
| 	if args.parent_task == 'All Tasks' or args.parent_task == args.project: | ||||
| 		args.parent_task = None | ||||
| 
 | ||||
|     frappe.get_doc(args).insert() | ||||
| 	frappe.get_doc(args).insert() | ||||
| 
 | ||||
| @frappe.whitelist() | ||||
| def add_multiple_tasks(data, parent): | ||||
|     data = json.loads(data) | ||||
|     new_doc = {'doctype': 'Task', 'parent_task': parent if parent!="All Tasks" else ""} | ||||
|     new_doc['project'] = frappe.db.get_value('Task', {"name": parent}, 'project') or "" | ||||
| 	data = json.loads(data) | ||||
| 	new_doc = {'doctype': 'Task', 'parent_task': parent if parent!="All Tasks" else ""} | ||||
| 	new_doc['project'] = frappe.db.get_value('Task', {"name": parent}, 'project') or "" | ||||
| 
 | ||||
|     for d in data: | ||||
|         if not d.get("subject"): continue | ||||
|         new_doc['subject'] = d.get("subject") | ||||
|         new_task = frappe.get_doc(new_doc) | ||||
|         new_task.insert() | ||||
| 	for d in data: | ||||
| 		if not d.get("subject"): continue | ||||
| 		new_doc['subject'] = d.get("subject") | ||||
| 		new_task = frappe.get_doc(new_doc) | ||||
| 		new_task.insert() | ||||
| 
 | ||||
| def on_doctype_update(): | ||||
|     frappe.db.add_index("Task", ["lft", "rgt"]) | ||||
| 	frappe.db.add_index("Task", ["lft", "rgt"]) | ||||
| 
 | ||||
| def validate_project_dates(project_end_date, task, task_start, task_end, actual_or_expected_date): | ||||
|     if task.get(task_start) and date_diff(project_end_date, getdate(task.get(task_start))) < 0: | ||||
|         frappe.throw(_("Task's {0} Start Date cannot be after Project's End Date.").format(actual_or_expected_date)) | ||||
| 	if task.get(task_start) and date_diff(project_end_date, getdate(task.get(task_start))) < 0: | ||||
| 		frappe.throw(_("Task's {0} Start Date cannot be after Project's End Date.").format(actual_or_expected_date)) | ||||
| 
 | ||||
|     if task.get(task_end) and date_diff(project_end_date, getdate(task.get(task_end))) < 0: | ||||
|         frappe.throw(_("Task's {0} End Date cannot be after Project's End Date.").format(actual_or_expected_date)) | ||||
| 	if task.get(task_end) and date_diff(project_end_date, getdate(task.get(task_end))) < 0: | ||||
| 		frappe.throw(_("Task's {0} End Date cannot be after Project's End Date.").format(actual_or_expected_date)) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user