Skip to content
Closed
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
65 changes: 57 additions & 8 deletions one_compliance/one_compliance/doc_events/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,21 @@ def on_update(self):
self.unassign_todo()
self.populate_depends_on()

def before_validate(self):
self.update_project_eed()

def update_project_eed(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

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

if project.expected_end_date < self.completed_on:
project.expected_end_date = self.completed_on
project.save()
def unassign_todo(self):
if self.status == "Completed":
close_all_assignments(self.doctype, self.name)
Expand Down Expand Up @@ -344,13 +359,14 @@ def task_on_update(doc, method):
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)
sales_order = project.sales_order
if not sales_order or not frappe.db.exists('Sales Order', sales_order):
sales_order = frappe.db.exists("Sales Order", {"project":project.name, 'docstatus':1})
if not sales_order:
frappe.throw(_(f"Sales Order not found for {project.name}"))
if not frappe.db.get_value("Sales Order", sales_order, "custom_is_rework"):
create_project_completion_todos(sales_order, project.name)

# Check if this task is a dependency for other tasks
dependent_tasks = frappe.get_all('Task Depends On', filters={'task': doc.name}, fields=['parent'])
for dependent_task in dependent_tasks:
Expand Down Expand Up @@ -501,12 +517,31 @@ 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):
def update_task_status(task_id, status, completed_by, completed_on, comment=None):
# Load the task document from the database
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 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)

# Project comment
if task_doc.project:
project_prefix = frappe.bold(_("Reason for updating expected end:"))
project_comment = (
f"{project_prefix} <br>"
f"Task <b>{task_doc.name}</b> updated to status <b>{status}</b> "
f"on {completed_on}.<br>"
f"Comment: {frappe.utils.escape_html(comment)}"
)
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)
Expand Down Expand Up @@ -694,3 +729,17 @@ 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)
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))
Original file line number Diff line number Diff line change
Expand Up @@ -925,44 +925,74 @@ function update_status(page, taskName, projectId, taskId) {
fieldname: 'completed_on',
fieldtype: 'Date',
default: 'Today'
}
},
{
label: 'Comment',
fieldname: 'comment',
fieldtype: 'Small Text'
}
];

let d = new frappe.ui.Dialog({
title: 'Enter details',
fields: fields,
primary_action_label: 'Update',
primary_action(values) {
// Block if validation requires comment but it's missing
if (d.fields_dict.comment.df.reqd && !values.comment) {
frappe.msgprint(__('Please enter a comment before updating.'));
return;
}

frappe.call({
method: 'one_compliance.one_compliance.doc_events.task.update_task_status',
args: {
'task_id': taskId,
'status': values.status,
'completed_by': values.completed_by,
'completed_on': values.completed_on
},
callback: function(r){
if (r.message){
d.hide();
const selectedStatus = page.fields_dict.status.get_value();
const taskName = page.fields_dict.task.get_value();
const projectName = page.fields_dict.project.get_value();
const customerName = page.fields_dict.customer.get_value();
const department = page.fields_dict.department.get_value();
const subCategory = page.fields_dict.compliance_sub_category.get_value();
const employee = page.fields_dict.employee.get_value();
const employeeGroup = page.fields_dict.employee_group.get_value();
const from_date = page.fields_dict.from_date.get_value();
const to_date = page.fields_dict.to_date.get_value();
refresh_tasks_manually(page, selectedStatus, taskName, projectName, customerName, department, subCategory, employee, employeeGroup, from_date, to_date)
// location.reload();
}
}
});
method: 'one_compliance.one_compliance.doc_events.task.update_task_status',
args: {
'task_id': taskId,
'status': values.status,
'completed_by': values.completed_by,
'completed_on': values.completed_on,
'comment': values.comment
},
callback: function(r){
if (r.message){
d.hide();
const selectedStatus = page.fields_dict.status.get_value();
const taskName = page.fields_dict.task.get_value();
const projectName = page.fields_dict.project.get_value();
const customerName = page.fields_dict.customer.get_value();
const department = page.fields_dict.department.get_value();
const subCategory = page.fields_dict.compliance_sub_category.get_value();
const employee = page.fields_dict.employee.get_value();
const employeeGroup = page.fields_dict.employee_group.get_value();
const from_date = page.fields_dict.from_date.get_value();
const to_date = page.fields_dict.to_date.get_value();
refresh_tasks_manually(page, selectedStatus, taskName, projectName, customerName, department, subCategory, employee, employeeGroup, from_date, to_date)
}
}
});
},
});
d.set_value('completed_by', frappe.session.user);
d.show();

//Hide comment initially
d.fields_dict.comment.$wrapper.hide();
d.set_df_property('comment', 'reqd', 0);

//Fetch project and validate dates
frappe.db.get_doc("Project", projectId).then(project => {
if (project.expected_end_date) {
let expectedDate = new Date(project.expected_end_date);
let completedDate = new Date(frappe.datetime.get_today());

if (completedDate > expectedDate) {
// force comment if task is completed after project EED
d.fields_dict.comment.$wrapper.show();
d.set_df_property('comment', 'reqd', 1);
}
}
});

d.show();
}

// Function to update status to working when clicking start time
Expand Down
2 changes: 1 addition & 1 deletion one_compliance/one_compliance/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def create_todo(doctype, name, assign_to, owner, description):

add_custom(
{
"assign_to": assign_to,
"assign_to": [assign_to],
"doctype": doctype,
"name": name,
"description": description,
Expand Down