Merge pull request #6662 from PawanMeh/fixes_6363

[fix] #6363
This commit is contained in:
Nabin Hait 2016-10-24 11:56:43 +05:30 committed by GitHub
commit f430d73daf
11 changed files with 209 additions and 35 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -2,6 +2,20 @@ Project management in ERPNext is Task driven. You can create Project and assign
<img class="screenshot" alt="Project" src="{{docs_base_url}}/assets/img/project/project.png"> <img class="screenshot" alt="Project" src="{{docs_base_url}}/assets/img/project/project.png">
You can also track % Completion of a Project using different methods.
1. Task Completion
2. Task Progress
3. Task Weight
<img class="screenshot" alt="Project" src="{{docs_base_url}}/assets/img/project/project-percent-complete.png">
Some examples of how the % Completion is calculated based on Tasks.
<img class="screenshot" alt="Project" src="{{docs_base_url}}/assets/img/project/percent-complete-calc.png">
<img class="screenshot" alt="Project" src="{{docs_base_url}}/assets/img/project/percent-complete-formula.png">
### Managing tasks ### Managing tasks
Project can be divided into multiple Tasks. Project can be divided into multiple Tasks.
Task can be created via Project document itself or can be created via [Task]({{docs_base_url}}/user/manual/en/projects/tasks.html) Task can be created via Project document itself or can be created via [Task]({{docs_base_url}}/user/manual/en/projects/tasks.html)
@ -18,6 +32,12 @@ Task can be created via Project document itself or can be created via [Task]({{
<img class="screenshot" alt="Project - Task Grid" src="{{docs_base_url}}/assets/img/project/project_task_grid.png"> <img class="screenshot" alt="Project - Task Grid" src="{{docs_base_url}}/assets/img/project/project_task_grid.png">
* To add Weights to Tasks you can follow the below steps
<img class="screenshot" alt="Project - Task Grid" src="{{docs_base_url}}/assets/img/project/tasks.png">
<img class="screenshot" alt="Project - Task Grid" src="{{docs_base_url}}/assets/img/project/task-weights.png">
### Managing time ### Managing time
ERPNext uses [Time Log]({{docs_base_url}}/user/manual/en/projects/time-log.html) to track the progress of a Project. ERPNext uses [Time Log]({{docs_base_url}}/user/manual/en/projects/time-log.html) to track the progress of a Project.

View File

@ -3,16 +3,19 @@
"allow_import": 1, "allow_import": 1,
"allow_rename": 1, "allow_rename": 1,
"autoname": "field:project_name", "autoname": "field:project_name",
"beta": 0,
"creation": "2013-03-07 11:55:07", "creation": "2013-03-07 11:55:07",
"custom": 0, "custom": 0,
"docstatus": 0, "docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "Setup", "document_type": "Setup",
"editable_grid": 0,
"fields": [ "fields": [
{ {
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"description": "", "description": "",
"fieldname": "project_name", "fieldname": "project_name",
"fieldtype": "Data", "fieldtype": "Data",
@ -39,6 +42,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"default": "Open", "default": "Open",
"fieldname": "status", "fieldname": "status",
"fieldtype": "Select", "fieldtype": "Select",
@ -67,6 +71,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "project_type", "fieldname": "project_type",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0, "hidden": 0,
@ -94,6 +99,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "is_active", "fieldname": "is_active",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0, "hidden": 0,
@ -121,6 +127,35 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"default": "Task Completion",
"fieldname": "percent_complete_method",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "% Complete Method",
"length": 0,
"no_copy": 0,
"options": "Task Completion\nTask Progress\nTask Weight",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_5", "fieldname": "column_break_5",
"fieldtype": "Column Break", "fieldtype": "Column Break",
"hidden": 0, "hidden": 0,
@ -145,6 +180,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "priority", "fieldname": "priority",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0, "hidden": 0,
@ -172,6 +208,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "expected_start_date", "fieldname": "expected_start_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0, "hidden": 0,
@ -198,6 +235,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 1, "bold": 1,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "expected_end_date", "fieldname": "expected_end_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0, "hidden": 0,
@ -220,10 +258,36 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"fieldname": "percent_complete",
"fieldtype": "Percent",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "% Completed",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{ {
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 1, "collapsible": 1,
"columns": 0,
"fieldname": "customer_details", "fieldname": "customer_details",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -250,6 +314,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "customer", "fieldname": "customer",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -277,6 +342,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "column_break_14", "fieldname": "column_break_14",
"fieldtype": "Column Break", "fieldtype": "Column Break",
"hidden": 0, "hidden": 0,
@ -301,6 +367,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "sales_order", "fieldname": "sales_order",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -327,6 +394,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 1, "collapsible": 1,
"columns": 0,
"fieldname": "users_section", "fieldname": "users_section",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -352,6 +420,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"description": "Project will be accessible on the website to these users", "description": "Project will be accessible on the website to these users",
"fieldname": "users", "fieldname": "users",
"fieldtype": "Table", "fieldtype": "Table",
@ -379,6 +448,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "sb_milestones", "fieldname": "sb_milestones",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -405,6 +475,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "tasks", "fieldname": "tasks",
"fieldtype": "Table", "fieldtype": "Table",
"hidden": 0, "hidden": 0,
@ -427,34 +498,11 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"fieldname": "percent_complete",
"fieldtype": "Percent",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "% Tasks Completed",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{ {
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 1, "collapsible": 1,
"columns": 0,
"fieldname": "section_break0", "fieldname": "section_break0",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -481,6 +529,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "notes", "fieldname": "notes",
"fieldtype": "Text Editor", "fieldtype": "Text Editor",
"hidden": 0, "hidden": 0,
@ -507,6 +556,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 1, "collapsible": 1,
"columns": 0,
"fieldname": "section_break_18", "fieldname": "section_break_18",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -532,6 +582,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "actual_start_date", "fieldname": "actual_start_date",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 0, "hidden": 0,
@ -557,6 +608,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "actual_time", "fieldname": "actual_time",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0, "hidden": 0,
@ -582,6 +634,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "column_break_20", "fieldname": "column_break_20",
"fieldtype": "Column Break", "fieldtype": "Column Break",
"hidden": 0, "hidden": 0,
@ -606,6 +659,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "actual_end_date", "fieldname": "actual_end_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0, "hidden": 0,
@ -632,6 +686,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 1, "collapsible": 1,
"columns": 0,
"fieldname": "project_details", "fieldname": "project_details",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -658,6 +713,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "estimated_costing", "fieldname": "estimated_costing",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0, "hidden": 0,
@ -685,6 +741,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"description": "", "description": "",
"fieldname": "total_costing_amount", "fieldname": "total_costing_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
@ -711,6 +768,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"description": "", "description": "",
"fieldname": "total_expense_claim", "fieldname": "total_expense_claim",
"fieldtype": "Currency", "fieldtype": "Currency",
@ -737,6 +795,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "company", "fieldname": "company",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -762,6 +821,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "cost_center", "fieldname": "cost_center",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -787,6 +847,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "column_break_28", "fieldname": "column_break_28",
"fieldtype": "Column Break", "fieldtype": "Column Break",
"hidden": 0, "hidden": 0,
@ -811,6 +872,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"description": "", "description": "",
"fieldname": "total_billing_amount", "fieldname": "total_billing_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
@ -837,6 +899,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "total_purchase_cost", "fieldname": "total_purchase_cost",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0, "hidden": 0,
@ -862,6 +925,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 1, "collapsible": 1,
"columns": 0,
"fieldname": "margin", "fieldname": "margin",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -888,6 +952,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "gross_margin", "fieldname": "gross_margin",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0, "hidden": 0,
@ -915,6 +980,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "column_break_37", "fieldname": "column_break_37",
"fieldtype": "Column Break", "fieldtype": "Column Break",
"hidden": 0, "hidden": 0,
@ -939,6 +1005,7 @@
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0,
"fieldname": "per_gross_margin", "fieldname": "per_gross_margin",
"fieldtype": "Percent", "fieldtype": "Percent",
"hidden": 0, "hidden": 0,
@ -967,13 +1034,15 @@
"hide_toolbar": 0, "hide_toolbar": 0,
"icon": "icon-puzzle-piece", "icon": "icon-puzzle-piece",
"idx": 29, "idx": 29,
"image_view": 0,
"in_create": 0, "in_create": 0,
"in_dialog": 0, "in_dialog": 0,
"is_submittable": 0, "is_submittable": 0,
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"max_attachments": 4, "max_attachments": 4,
"modified": "2016-04-22 03:15:39.635420", "modified": "2016-10-21 04:20:14.974653",
"modified": "2016-10-23 01:02:40.632849",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Projects", "module": "Projects",
"name": "Project", "name": "Project",
@ -989,6 +1058,7 @@
"export": 0, "export": 0,
"if_owner": 0, "if_owner": 0,
"import": 0, "import": 0,
"is_custom": 0,
"permlevel": 0, "permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
@ -1009,6 +1079,7 @@
"export": 0, "export": 0,
"if_owner": 0, "if_owner": 0,
"import": 0, "import": 0,
"is_custom": 0,
"permlevel": 1, "permlevel": 1,
"print": 0, "print": 0,
"read": 1, "read": 1,
@ -1027,4 +1098,4 @@
"sort_order": "DESC", "sort_order": "DESC",
"timeline_field": "customer", "timeline_field": "customer",
"track_seen": 1 "track_seen": 1
} }

View File

@ -36,7 +36,8 @@ class Project(Document):
"start_date": task.exp_start_date, "start_date": task.exp_start_date,
"end_date": task.exp_end_date, "end_date": task.exp_end_date,
"description": task.description, "description": task.description,
"task_id": task.name "task_id": task.name,
"task_weight": task.task_weight
}) })
def get_tasks(self): def get_tasks(self):
@ -44,6 +45,7 @@ class Project(Document):
def validate(self): def validate(self):
self.validate_dates() self.validate_dates()
self.validate_weights()
self.sync_tasks() self.sync_tasks()
self.tasks = [] self.tasks = []
self.send_welcome_email() self.send_welcome_email()
@ -52,6 +54,14 @@ class Project(Document):
if self.expected_start_date and self.expected_end_date: if self.expected_start_date and self.expected_end_date:
if getdate(self.expected_end_date) < getdate(self.expected_start_date): if getdate(self.expected_end_date) < getdate(self.expected_start_date):
frappe.throw(_("Expected End Date can not be less than Expected Start Date")) frappe.throw(_("Expected End Date can not be less than Expected Start Date"))
def validate_weights(self):
sum = 0
for task in self.tasks:
if task.task_weight > 0:
sum = sum + task.task_weight
if sum > 0 and sum != 1:
frappe.throw(_("Total of all task weights should be 1. Please adjust weights of all Project tasks accordingly"))
def sync_tasks(self): def sync_tasks(self):
"""sync tasks and remove table""" """sync tasks and remove table"""
@ -64,13 +74,13 @@ class Project(Document):
else: else:
task = frappe.new_doc("Task") task = frappe.new_doc("Task")
task.project = self.name task.project = self.name
task.update({ task.update({
"subject": t.title, "subject": t.title,
"status": t.status, "status": t.status,
"exp_start_date": t.start_date, "exp_start_date": t.start_date,
"exp_end_date": t.end_date, "exp_end_date": t.end_date,
"description": t.description, "description": t.description,
"task_weight": t.task_weight
}) })
task.flags.ignore_links = True task.flags.ignore_links = True
@ -93,13 +103,28 @@ class Project(Document):
self.save(ignore_permissions = True) self.save(ignore_permissions = True)
def update_percent_complete(self): def update_percent_complete(self):
total = frappe.db.sql("""select count(*) from tabTask where project=%s""", self.name)[0][0] total = frappe.db.sql("""select count(name) from tabTask where project=%s""", self.name)[0][0]
if total: if (self.percent_complete_method == "Task Completion" and total > 0) or (not self.percent_complete_method and total > 0):
completed = frappe.db.sql("""select count(*) from tabTask where completed = frappe.db.sql("""select count(name) from tabTask where
project=%s and status in ('Closed', 'Cancelled')""", self.name)[0][0] project=%s and status in ('Closed', 'Cancelled')""", self.name)[0][0]
self.percent_complete = flt(flt(completed) / total * 100, 2) self.percent_complete = flt(flt(completed) / total * 100, 2)
if (self.percent_complete_method == "Task Progress" and total > 0):
progress = frappe.db.sql("""select sum(progress) from tabTask where
project=%s""", self.name)[0][0]
self.percent_complete = flt(flt(progress) / total, 2)
if (self.percent_complete_method == "Task Weight" and total > 0):
weight_sum = frappe.db.sql("""select sum(task_weight) from tabTask where
project=%s""", self.name)[0][0]
if weight_sum == 1:
weighted_progress = frappe.db.sql("""select progress,task_weight from tabTask where
project=%s""", self.name,as_dict=1)
pct_complete=0
for row in weighted_progress:
pct_complete += row["progress"] * row["task_weight"]
self.percent_complete = flt(flt(pct_complete), 2)
def update_costing(self): def update_costing(self):
from_time_sheet = frappe.db.sql("""select from_time_sheet = frappe.db.sql("""select
sum(costing_amount) as costing_amount, sum(costing_amount) as costing_amount,

View File

@ -9,6 +9,7 @@
"doctype": "DocType", "doctype": "DocType",
"document_type": "Other", "document_type": "Other",
"editable_grid": 1, "editable_grid": 1,
"engine": "InnoDB",
"fields": [ "fields": [
{ {
"allow_on_submit": 0, "allow_on_submit": 0,
@ -169,6 +170,32 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "task_weight",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Weight",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{ {
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
@ -258,7 +285,7 @@
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2016-08-26 02:44:34.737837", "modified": "2016-10-19 11:16:16.023965",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Projects", "module": "Projects",
"name": "Project Task", "name": "Project Task",

View File

@ -230,6 +230,32 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "task_weight",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Weight",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{ {
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
@ -294,7 +320,7 @@
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_list_view": 0, "in_list_view": 0,
"label": "Progress", "label": "% Progress",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
@ -854,7 +880,7 @@
"istable": 0, "istable": 0,
"max_attachments": 5, "max_attachments": 5,
"menu_index": 0, "menu_index": 0,
"modified": "2016-10-03 15:12:56.078675", "modified": "2016-10-20 02:59:02.228659",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Projects", "module": "Projects",
"name": "Task", "name": "Task",

View File

@ -28,6 +28,7 @@ class Task(Document):
def validate(self): def validate(self):
self.validate_dates() self.validate_dates()
self.validate_progress()
self.validate_status() self.validate_status()
self.update_depends_on() self.update_depends_on()
@ -46,6 +47,10 @@ class Task(Document):
from frappe.desk.form.assign_to import clear from frappe.desk.form.assign_to import clear
clear(self.doctype, self.name) clear(self.doctype, self.name)
def validate_progress(self):
if self.progress > 100:
frappe.throw(_("Progress % for a task cannot be more than 100."))
def update_depends_on(self): def update_depends_on(self):
depends_on_tasks = "" depends_on_tasks = ""