Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion one_compliance/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@
'one_compliance.one_compliance.doc_events.task.make_sales_invoice',
'one_compliance.one_compliance.doc_events.task.subtask_on_update',
'one_compliance.one_compliance.doc_events.task.on_task_update',
'one_compliance.one_compliance.doc_events.task.enable_customer_on_task_completion'
'one_compliance.one_compliance.doc_events.task.enable_customer_on_task_completion',
'one_compliance.one_compliance.doc_events.task.on_update',
],
'validate':[
'one_compliance.one_compliance.doc_events.task.append_users_to_project',
Expand Down
150 changes: 123 additions & 27 deletions one_compliance/one_compliance/doc_events/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from frappe.utils.data import format_date
from frappe.utils.nestedset import NestedSet
from erpnext.projects.doctype.task.task import check_if_child_exists, CircularReferenceError
from frappe.utils import getdate

from one_compliance.one_compliance.utils import (
create_project_completion_todos,
Expand Down Expand Up @@ -191,6 +192,25 @@ def on_update(self):
self.unassign_todo()
self.populate_depends_on()

def before_validate(self):
self.update_project_expected_end_date()

def update_project_expected_end_date(self):
'''
Update the project's expected end date if the task's completion date is later.
'''
if not self.project or not self.completed_on:
return
current_eed = frappe.db.get_value("Project", self.project, "expected_end_date")

if getdate(current_eed) < getdate(self.completed_on):
frappe.db.set_value(
"Project",
self.project,
"expected_end_date",
self.completed_on
)

def unassign_todo(self):
if self.status == "Completed":
close_all_assignments(self.doctype, self.name)
Expand Down Expand Up @@ -298,7 +318,6 @@ def update_status(self):
self.db_set("status", "Overdue", update_modified=False)
self.update_project()


@frappe.whitelist()
def append_users_to_project(doc, method):
if doc.assigned_to and doc.project:
Expand Down Expand Up @@ -335,37 +354,75 @@ def add_project_user_if_not_exists(project, user_id):
@frappe.whitelist()
def task_on_update(doc, method):
set_task_time_line(doc)

if doc.status == 'Completed':
if frappe.db.get_single_value("Compliance Settings", "enable_task_complete_notification_for_director"):
if frappe.db.get_single_value(
"Compliance Settings",
"enable_task_complete_notification_for_director"
):
task_complete_notification_for_director(doc)

if doc.custom_is_payable:
create_journal_entry(doc)
if doc.project:
if frappe.db.exists('Project', doc.project):
project = frappe.get_doc ('Project', doc.project)
if project.status == 'Completed':
if not frappe.db.get_value("Sales Order", project.sales_order, "custom_is_rework"):
create_project_completion_todos(project.sales_order, project.project_name)
# send_project_completion_mail = frappe.db.get_value('Customer', project.customer, 'send_project_completion_mail')
# if send_project_completion_mail:
# email_id = frappe.db.get_value('Customer', project.customer, 'email_id')
# if email_id:
# project_complete_notification_for_customer(project, email_id)
Comment thread
MhmdSinanKT marked this conversation as resolved.
# Check if this task is a dependency for other tasks
dependent_tasks = frappe.get_all('Task Depends On', filters={'task': doc.name}, fields=['parent'])

if doc.project and frappe.db.exists("Project", doc.project):

project_status, sales_order = frappe.db.get_value(
"Project",
doc.project,
["status", "sales_order"]
)

if project_status == "Completed":

if not sales_order or not frappe.db.exists("Sales Order", sales_order):
sales_order = frappe.db.exists(
"Sales Order",
{"project": doc.project, "docstatus": 1}
)
if not sales_order:
frappe.throw(
_(f"Sales Order not found for {doc.project}")
)

if not frappe.db.get_value(
"Sales Order",
sales_order,
"custom_is_rework"
):
create_project_completion_todos(sales_order, doc.project)

dependent_tasks = frappe.get_all(
'Task Depends On',
filters={'task': doc.name},
fields=['parent']
)

for dependent_task in dependent_tasks:
task = frappe.get_doc('Task', dependent_task.parent)
task_name = dependent_task.parent

current_status = frappe.db.get_value("Task", task_name, "status")

all_dependencies_completed = True
# Check if all dependent tasks are completed
for dependency in task.depends_on:
dependency_doc = frappe.get_doc('Task', dependency.task)
if dependency_doc.status != 'Completed':

dependencies = frappe.get_all(
"Task Depends On",
filters={"parent": task_name},
fields=["task"]
)

for dependency in dependencies:
dep_status = frappe.db.get_value(
"Task",
dependency.task,
"status"
)
if dep_status != "Completed":
all_dependencies_completed = False
break
# If all dependencies are completed, mark the dependent task as completed
if all_dependencies_completed and task.status != 'Completed':
task.status = 'Completed'
task.save()

if all_dependencies_completed and current_status != "Completed":
frappe.db.set_value("Task", task_name, "status", "Completed")

@frappe.whitelist()
def task_complete_notification_for_director(doc):
Expand Down Expand Up @@ -501,14 +558,32 @@ def create_sales_order(project, rate, sub_category_doc, payment_terms=None, subm
frappe.msgprint("Sales Order {0} Created against {1}".format(new_sales_order.name, project.name), alert=True)

@frappe.whitelist()
def update_task_status(task_id, status, completed_by, completed_on):
# Load the task document from the database
def update_task_status(task_id, status, completed_by, completed_on, comment=None):
'''
Update the status and completion details of a Task and optionally add comments
to both the Task and its linked Project.
'''

task_doc = frappe.get_doc("Task", task_id)
task_doc.completed_on = frappe.utils.getdate(completed_on)
task_doc.status = status
task_doc.completed_by = completed_by
if comment:
task_prefix = frappe.bold(_("Reason for updating task status:"))
task_comment = f"{task_prefix}<br> {frappe.utils.escape_html(comment)}"
task_doc.add_comment("Comment", task_comment)

if task_doc.project:
formatted_date = frappe.utils.formatdate(completed_on, "dd-mm-yyyy")
project_prefix = frappe.bold(_("Reason for Updating Expected End Date:"))
project_comment = (
f"{project_prefix}<br>"
f"Task <b>{task_doc.name}</b> Completed on {formatted_date}."
)
project_doc = frappe.get_doc("Project", task_doc.project)
project_doc.add_comment("Comment", project_comment)

task_doc.save()
frappe.db.commit()
frappe.msgprint("Task Status has been set to {0}".format(status), alert=True)
return True

Expand Down Expand Up @@ -694,3 +769,24 @@ def enable_customer_on_task_completion(doc, method):
customer.aml_compliance_checked = 1
customer.save(ignore_permissions=True)
frappe.msgprint(f"Customer {customer.name} has been enabled after AML compliance task completion.")

def on_update(doc, method):
'''
Update the project's expected end date if the task's completion date is later.
'''
if not doc.project or not doc.completed_on:
return

project = frappe.get_doc("Project", doc.project)

if project.expected_end_date < doc.completed_on:
project.db_set('expected_end_date', doc.completed_on)
task_completed_date = getdate(doc.completed_on)
project_eed = getdate(project.expected_end_date)

if task_completed_date > project_eed:
project.db_set("expected_end_date", task_completed_date)
comment_content = '<h2><b>Reason for updating project completion date:</b></h2>'
comment_content += f"Expected End Date updated to <b>{doc.completed_on}</b> based on Task <b>{doc.name}</b> completion."
project.add_comment(text=_(comment_content))

Loading