Daily Reminder (#12938)

* for email sending

* test commit for new branch

* Removed test changes

* test commit renzo

* Email sending

* Project Uo

* Project Update

* "My first commit"

* "My second commit"

* "My second commit"

* Holiday is included

* delete idea

* first pull

* first pull

* "My third commit"

* Delete idea

* delete again

* "Edit Time"

* "Edit Time"

* Naming series and bug fixing

* "Edit current day and time"

* "Proper naming series, hidden time and date"

* Project and Project Update dashboard

* dashboard

* Remove hooks for PR

* Remove hooks for PR

* Remove hooks for PR

* Deleted project_time.py

* Corrected indention

* Hook back to original

* Delete project_time.py

* "Modified time"

* Fix indention

* Sample

* FRM

* FRM

* Time fix

* Hooks original state

* "Modified time"

* Added permission to Project User

* Added function/method to be called in order to create project update for the specific project

* Naming series

* this is not included

* Fix minor bug

* Indent again

* "Reformat Code"

* "Check Indent"

* Indent again and again

* semi colon

* "Check Again Indent"

* "Check again Indent"

* "Check again Indent"

* ind

* "Check again Indent"

* "Check again Indent"

* Generate Project update
With button in email

* []

* "Erro Summary"

* "Add syntax for the communcation"

* "add summary code"

* "Modified Summary code"

* "Modified Summary code"

* "Fix update ID and set localhost"

* Fix time and date error in project_update
Fix naming series problem in project_update

* included "not updated" in project update

* Bug in Number of Drafts

* "add notes in summary"

* Correct code

* With error

* Removed the method

* Minor fixes

* Correction for daily summary
diff --git a/erpnext/config/projects.py b/erpnext/config/projects.py
index ac11c7e..2f8b92d 100644
--- a/erpnext/config/projects.py
+++ b/erpnext/config/projects.py
@@ -14,6 +14,11 @@
 				},
 				{
 					"type": "doctype",
+					"name": "Project Update",
+					"description": _("Project Update."),
+				},
+				{
+					"type": "doctype",
 					"name": "Task",
 					"route": "List/Task",
 					"description": _("Project activity / task."),
diff --git a/erpnext/projects/doctype/project/README.md b/erpnext/projects/doctype/project/README.md
index b1da6ad..7d513cb 100644
--- a/erpnext/projects/doctype/project/README.md
+++ b/erpnext/projects/doctype/project/README.md
@@ -1 +1 @@
-Project details. Projects can be internal or external and can have Tasks, Milestones associated to it.
\ No newline at end of file
+Project details. Projects can be internal or external and can have Tasks, Milestones associated to it.
diff --git a/erpnext/projects/doctype/project/project.js b/erpnext/projects/doctype/project/project.js
index cc8433c..682398f 100644
--- a/erpnext/projects/doctype/project/project.js
+++ b/erpnext/projects/doctype/project/project.js
@@ -1,18 +1,15 @@
 // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
-
 frappe.ui.form.on("Project", {
-	setup: function(frm) {
+	setup: function (frm) {
 		frm.set_indicator_formatter('title',
-			function(doc) {
+			function (doc) {
 				let indicator = 'orange';
 				if (doc.status == 'Overdue') {
 					indicator = 'red';
-				}
-				else if (doc.status == 'Cancelled') {
+				} else if (doc.status == 'Cancelled') {
 					indicator = 'dark grey';
-				}
-				else if (doc.status == 'Closed') {
+				} else if (doc.status == 'Closed') {
 					indicator = 'green';
 				}
 				return indicator;
@@ -20,10 +17,10 @@
 		);
 	},
 
-	onload: function(frm) {
+	onload: function (frm) {
 		var so = frappe.meta.get_docfield("Project", "sales_order");
-		so.get_route_options_for_new_doc = function(field) {
-			if(frm.is_new()) return;
+		so.get_route_options_for_new_doc = function (field) {
+			if (frm.is_new()) return;
 			return {
 				"customer": frm.doc.customer,
 				"project_name": frm.doc.name
@@ -32,14 +29,14 @@
 
 		frm.set_query('customer', 'erpnext.controllers.queries.customer_query');
 
-		frm.set_query("user", "users", function() {
+		frm.set_query("user", "users", function () {
 			return {
-				query:"erpnext.projects.doctype.project.project.get_users_for_project"
+				query: "erpnext.projects.doctype.project.project.get_users_for_project"
 			}
 		});
 
 		// sales order
-		frm.set_query('sales_order', function() {
+		frm.set_query('sales_order', function () {
 			var filters = {
 				'project': ["in", frm.doc.__islocal ? [""] : [frm.doc.name, ""]]
 			};
@@ -54,15 +51,17 @@
 		});
 	},
 
-	refresh: function(frm) {
-		if(frm.doc.__islocal) {
+	refresh: function (frm) {
+		if (frm.doc.__islocal) {
 			frm.web_link && frm.web_link.remove();
 		} else {
 			frm.add_web_link("/projects?project=" + encodeURIComponent(frm.doc.name));
 
-			if(frappe.model.can_read("Task")) {
-				frm.add_custom_button(__("Gantt Chart"), function() {
-					frappe.route_options = {"project": frm.doc.name};
+			if (frappe.model.can_read("Task")) {
+				frm.add_custom_button(__("Gantt Chart"), function () {
+					frappe.route_options = {
+						"project": frm.doc.name
+					};
 					frappe.set_route("List", "Task", "Gantt");
 				});
 			}
@@ -70,65 +69,69 @@
 			frm.trigger('show_dashboard');
 		}
 	},
-	tasks_refresh: function(frm) {
+	tasks_refresh: function (frm) {
 		var grid = frm.get_field('tasks').grid;
-		grid.wrapper.find('select[data-fieldname="status"]').each(function() {
-			if($(this).val()==='Open') {
+		grid.wrapper.find('select[data-fieldname="status"]').each(function () {
+			if ($(this).val() === 'Open') {
 				$(this).addClass('input-indicator-open');
 			} else {
 				$(this).removeClass('input-indicator-open');
 			}
 		});
 	},
-	show_dashboard: function(frm) {
-		if(frm.doc.__onload.activity_summary.length) {
-			var hours = $.map(frm.doc.__onload.activity_summary, function(d) { return d.total_hours });
-			var max_count = Math.max.apply(null, hours);
-			var sum = hours.reduce(function(a, b) { return a + b; }, 0);
-			var section = frm.dashboard.add_section(
-				frappe.render_template('project_dashboard',
-					{
-						data: frm.doc.__onload.activity_summary,
-						max_count: max_count,
-						sum: sum
-					}));
-
-			section.on('click', '.time-sheet-link', function() {
-				var activity_type = $(this).attr('data-activity_type');
-				frappe.set_route('List', 'Timesheet',
-					{'activity_type': activity_type, 'project': frm.doc.name, 'status': ["!=", "Cancelled"]});
-			});
-		}
-	}
-});
-
-frappe.ui.form.on("Project Task", {
-	edit_task: function(frm, doctype, name) {
+	edit_task: function (frm, doctype, name) {
 		var doc = frappe.get_doc(doctype, name);
-		if(doc.task_id) {
+		if (doc.task_id) {
 			frappe.set_route("Form", "Task", doc.task_id);
 		} else {
 			frappe.msgprint(__("Save the document first."));
 		}
 	},
-	edit_timesheet: function(frm, cdt, cdn) {
+	edit_timesheet: function (frm, cdt, cdn) {
 		var child = locals[cdt][cdn];
-		frappe.route_options = {"project": frm.doc.project_name, "task": child.task_id};
+		frappe.route_options = {
+			"project": frm.doc.project_name,
+			"task": child.task_id
+		};
 		frappe.set_route("List", "Timesheet");
 	},
-
-	make_timesheet: function(frm, cdt, cdn) {
+	make_timesheet: function (frm, cdt, cdn) {
 		var child = locals[cdt][cdn];
-		frappe.model.with_doctype('Timesheet', function() {
-				var doc = frappe.model.get_new_doc('Timesheet');
-				var row = frappe.model.add_child(doc, 'time_logs');
-				row.project = frm.doc.project_name;
-				row.task = child.task_id;
-				frappe.set_route('Form', doc.doctype, doc.name);
-			})
+		frappe.model.with_doctype('Timesheet', function () {
+			var doc = frappe.model.get_new_doc('Timesheet');
+			var row = frappe.model.add_child(doc, 'time_logs');
+			row.project = frm.doc.project_name;
+			row.task = child.task_id;
+			frappe.set_route('Form', doc.doctype, doc.name);
+		})
 	},
 
-	status: function(frm, doctype, name) {
+	status: function (frm, doctype, name) {
 		frm.trigger('tasks_refresh');
 	},
+
 });
+
+
+frappe.ui.form.on("Project", "validate", function (frm) {
+	frappe.call({
+		method: "erpnext.projects.doctype.project.project.times_check",
+		args: {
+			"from1": frm.doc.from,
+			"to": frm.doc.to,
+			"first_email": frm.doc.first_email,
+			"second_email": frm.doc.second_email,
+			"daily_time_to_send": frm.doc.daily_time_to_send,
+			"weekly_time_to_send": frm.doc.weekly_time_to_send
+
+		},
+		callback: function (r) {
+			frm.set_value("from", r.message.from1);
+			frm.set_value("to", r.message.to);
+			frm.set_value("first_email", r.message.first_email);
+			frm.set_value("second_email", r.message.second_email);
+			frm.set_value("daily_time_to_send", r.message.daily_time_to_send);
+			frm.set_value("weekly_time_to_send", r.message.weekly_time_to_send);
+		}
+	});
+});
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json
index 5d95bd3..7b4d718 100644
--- a/erpnext/projects/doctype/project/project.json
+++ b/erpnext/projects/doctype/project/project.json
@@ -1272,6 +1272,347 @@
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 1, 
+   "columns": 0, 
+   "fieldname": "monitor_progress", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Monitor Progress", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "collect_progress", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Collect Progress", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "eval:doc.collect_progress == true", 
+   "fieldname": "frequency", 
+   "fieldtype": "Select", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Frequency To Collect Progress", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Hourly\nTwice Daily\nDaily\nWeekly", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "column_break_45", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "eval:(doc.frequency == \"Hourly\" && doc.collect_progress == true)", 
+   "fieldname": "from", 
+   "fieldtype": "Time", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "From", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "eval:(doc.frequency == \"Hourly\" && doc.collect_progress == true)", 
+   "fieldname": "to", 
+   "fieldtype": "Time", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "To", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "eval:(doc.frequency == \"Twice Daily\" && doc.collect_progress == true)\n\n", 
+   "fieldname": "first_email", 
+   "fieldtype": "Time", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "First Email", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "eval:(doc.frequency == \"Twice Daily\" && doc.collect_progress == true)", 
+   "fieldname": "second_email", 
+   "fieldtype": "Time", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Second Email", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "eval:(doc.frequency == \"Daily\" && doc.collect_progress == true)", 
+   "fieldname": "daily_time_to_send", 
+   "fieldtype": "Time", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Time to send", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "eval:(doc.frequency == \"Weekly\" && doc.collect_progress == true)", 
+   "fieldname": "day_to_send", 
+   "fieldtype": "Select", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Day to Send", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Monday\nTuesday\nWednesday\nThursday\nFriday\nSaturday\nSunday", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "eval:(doc.frequency == \"Weekly\" && doc.collect_progress == true)", 
+   "fieldname": "weekly_time_to_send", 
+   "fieldtype": "Time", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Time to send", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
   }
  ], 
  "has_web_view": 0, 
@@ -1285,7 +1626,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 4, 
- "modified": "2017-12-10 08:40:46.843201", 
+ "modified": "2018-01-29 11:48:21.156697", 
  "modified_by": "Administrator", 
  "module": "Projects", 
  "name": "Project", 
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index 221c1d3..02a4afb 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -10,6 +10,7 @@
 from frappe.model.document import Document
 from erpnext.controllers.queries import get_filters_cond
 from frappe.desk.reportview import get_match_cond
+import datetime
 
 from six import iteritems
 
@@ -79,7 +80,8 @@
 			if task.task_weight or 0 > 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"))
+			frappe.throw(
+				_("Total of all task weights should be 1. Please adjust weights of all Project tasks accordingly"))
 
 	def sync_tasks(self):
 		"""sync tasks and remove table"""
@@ -105,7 +107,7 @@
 			task.flags.ignore_links = True
 			task.flags.from_project = True
 			task.flags.ignore_feed = True
-			task.save(ignore_permissions = True)
+			task.save(ignore_permissions=True)
 			task_names.append(task.name)
 
 		# delete
@@ -127,18 +129,18 @@
 		self.update_percent_complete()
 		self.update_costing()
 		self.flags.dont_sync_tasks = True
-		self.save(ignore_permissions = True)
+		self.save(ignore_permissions=True)
 
 	def after_insert(self):
 		if self.sales_order:
 			frappe.db.set_value("Sales Order", self.sales_order, "project", self.name)
 
-
 	def update_percent_complete(self):
 		total = frappe.db.sql("""select count(name) from tabTask where project=%s""", self.name)[0][0]
 		if not total and self.percent_complete:
 			self.percent_complete = 0
-		if (self.percent_complete_method == "Task Completion" and total > 0) or (not self.percent_complete_method and total > 0):
+		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(name) from tabTask where
 				project=%s and status in ('Closed', 'Cancelled')""", self.name)[0][0]
 			self.percent_complete = flt(flt(completed) / total * 100, 2)
@@ -153,8 +155,8 @@
 				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
+					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)
@@ -172,7 +174,7 @@
 			sum(total_sanctioned_amount) as total_sanctioned_amount
 			from `tabExpense Claim` where project = %s
 			and docstatus = 1""",
-			self.name, as_dict=1)[0]
+										   self.name, as_dict=1)[0]
 
 		self.actual_start_date = from_time_sheet.start_date
 		self.actual_end_date = from_time_sheet.end_date
@@ -186,10 +188,11 @@
 		self.update_sales_amount()
 		self.update_billed_amount()
 
-		self.gross_margin = flt(self.total_billed_amount) - (flt(self.total_costing_amount) + flt(self.total_expense_claim) + flt(self.total_purchase_cost))
+		self.gross_margin = flt(self.total_billed_amount) - (
+		flt(self.total_costing_amount) + flt(self.total_expense_claim) + flt(self.total_purchase_cost))
 
 		if self.total_billed_amount:
-			self.per_gross_margin = (self.gross_margin / flt(self.total_billed_amount)) *100
+			self.per_gross_margin = (self.gross_margin / flt(self.total_billed_amount)) * 100
 
 	def update_purchase_costing(self):
 		total_purchase_cost = frappe.db.sql("""select sum(base_net_amount)
@@ -209,13 +212,12 @@
 
 		self.total_billed_amount = total_billed_amount and total_billed_amount[0][0] or 0
 
-
 	def send_welcome_email(self):
 		url = get_url("/project/?name={0}".format(self.name))
 		messages = (
-		_("You have been invited to collaborate on the project: {0}".format(self.name)),
-		url,
-		_("Join")
+			_("You have been invited to collaborate on the project: {0}".format(self.name)),
+			url,
+			_("Join")
 		)
 
 		content = """
@@ -224,9 +226,10 @@
 		"""
 
 		for user in self.users:
-			if user.welcome_email_sent==0:
-				frappe.sendmail(user.user, subject=_("Project Collaboration Invitation"), content=content.format(*messages))
-				user.welcome_email_sent=1
+			if user.welcome_email_sent == 0:
+				frappe.sendmail(user.user, subject=_("Project Collaboration Invitation"),
+								content=content.format(*messages))
+				user.welcome_email_sent = 1
 
 	def on_update(self):
 		self.load_tasks()
@@ -256,18 +259,23 @@
 				depends_on_tasks = _task.depends_on_tasks
 
 				depends_on_tasks = [x for x in depends_on_tasks.split(',') if x]
-				dependency_map[task.title] = [ x['subject'] for x in frappe.get_list(
+				dependency_map[task.title] = [x['subject'] for x in frappe.get_list(
 					'Task Depends On', {"parent": name}, ['subject'])]
 
+			for key, value in dependency_map.iteritems():
+				task_name = frappe.db.get_value('Task', {"subject": key, "project": self.name})
+
 			for key, value in iteritems(dependency_map):
 				task_name = frappe.db.get_value('Task', {"subject": key, "project": self.name })
+
 				task_doc = frappe.get_doc('Task', task_name)
 
 				for dt in value:
-					dt_name = frappe.db.get_value('Task', {"subject": dt, "project": self.name })
+					dt_name = frappe.db.get_value('Task', {"subject": dt, "project": self.name})
 					task_doc.append('depends_on', {"task": dt_name})
 				task_doc.save()
 
+
 def get_timeline_data(doctype, name):
 	'''Return timeline for attendance'''
 	return dict(frappe.db.sql('''select unix_timestamp(from_time), count(*)
@@ -276,6 +284,7 @@
 			and docstatus < 2
 			group by date(from_time)''', name))
 
+
 def get_project_list(doctype, txt, filters, limit_start, limit_page_length=20, order_by="modified"):
 	return frappe.db.sql('''select distinct project.*
 		from tabProject project, `tabProject User` project_user
@@ -286,9 +295,10 @@
 			order by project.modified desc
 			limit {0}, {1}
 		'''.format(limit_start, limit_page_length),
-			{'user':frappe.session.user},
-			as_dict=True,
-			update={'doctype':'Project'})
+						 {'user': frappe.session.user},
+						 as_dict=True,
+						 update={'doctype': 'Project'})
+
 
 def get_list_context(context=None):
 	return {
@@ -315,16 +325,85 @@
 			idx desc,
 			name, full_name
 		limit %(start)s, %(page_len)s""".format(**{
-			'key': searchfield,
-			'fcond': get_filters_cond(doctype, filters, conditions),
-			'mcond': get_match_cond(doctype)
-		}), {
-			'txt': "%%%s%%" % txt,
-			'_txt': txt.replace("%", ""),
-			'start': start,
-			'page_len': page_len
-		})
+		'key': searchfield,
+		'fcond': get_filters_cond(doctype, filters, conditions),
+		'mcond': get_match_cond(doctype)
+	}), {
+							 'txt': "%%%s%%" % txt,
+							 '_txt': txt.replace("%", ""),
+							 'start': start,
+							 'page_len': page_len
+						 })
+
 
 @frappe.whitelist()
 def get_cost_center_name(project):
 	return frappe.db.get_value("Project", project, "cost_center")
+
+@frappe.whitelist()
+def hourly_reminder():
+	project = frappe.db.sql("""SELECT `tabProject`.name FROM `tabProject` WHERE `tabProject`.frequency = "Hourly" and (CURTIME() BETWEEN `tabProject`.from and `tabProject`.to) AND `tabProject`.collect_progress = 1 ORDER BY `tabProject`.name;""")
+	create_project_update(project)
+
+@frappe.whitelist()
+def twice_daily_reminder():
+	project = frappe.db.sql("""SELECT `tabProject User`.user FROM `tabProject User` INNER JOIN `tabProject` ON `tabProject`.project_name = `tabProject User`.parent WHERE (`tabProject`.frequency = "Twice Daily") AND ((`tabProject`.first_email BETWEEN DATE_ADD(curtime(), INTERVAL -15 MINUTE) AND DATE_ADD(curtime(), INTERVAL 15 MINUTE)) OR (`tabProject`.second_email BETWEEN DATE_ADD(curtime(), INTERVAL -15 MINUTE) AND DATE_ADD(curtime(), INTERVAL 15 MINUTE))) AND `tabProject`.collect_progress = 1;""")
+	create_project_update(project)
+
+@frappe.whitelist()
+def daily_reminder():
+	project = frappe.db.sql("""SELECT `tabProject User`.user FROM `tabProject User` INNER JOIN `tabProject` ON `tabProject`.project_name = `tabProject User`.parent WHERE (`tabProject`.frequency = "Daily") AND (`tabProject`.daily_time_to_send BETWEEN DATE_ADD(curtime(), INTERVAL -15 MINUTE) AND DATE_ADD(curtime(), INTERVAL 15 MINUTE)) AND `tabProject`.collect_progress = 1;""")
+	create_project_update(project)
+
+@frappe.whitelist()
+def weekly():
+	today = datetime.datetime.now().strftime("%A")
+	project = frappe.db.sql("""SELECT `tabProject User`.user FROM `tabProject User` INNER JOIN `tabProject` ON `tabProject`.project_name = `tabProject User`.parent WHERE (`tabProject`.frequency = "Weekly") AND (`tabProject`.day_to_send = %s) AND (`tabProject`.weekly_time_to_send BETWEEN DATE_ADD(curtime(), INTERVAL -15 MINUTE) AND DATE_ADD(curtime(), INTERVAL 15 MINUTE)) AND `tabProject`.collect_progress = 1""", today)
+	create_project_update(project)
+
+@frappe.whitelist()
+def times_check(from1, to, first_email, second_email, daily_time_to_send, weekly_time_to_send):
+    from1 = datetime.datetime.strptime(from1, "%H:%M:%S")
+    from1 = from1.strftime("%H:00:00")
+    to = datetime.datetime.strptime(to, "%H:%M:%S")
+    to = to.strftime("%H:00:00")
+    first_email = datetime.datetime.strptime(first_email, "%H:%M:%S")
+    first_email = first_email.strftime("%H:00:00")
+    second_email = datetime.datetime.strptime(second_email, "%H:%M:%S")
+    second_email = second_email.strftime("%H:00:00")
+    daily_time_to_send = datetime.datetime.strptime(daily_time_to_send, "%H:%M:%S")
+    daily_time_to_send = daily_time_to_send.strftime("%H:00:00")
+    weekly_time_to_send = datetime.datetime.strptime(weekly_time_to_send, "%H:%M:%S")
+    weekly_time_to_send = weekly_time_to_send.strftime("%H:00:00")
+    return {"from1": from1, "to": to, "first_email": first_email, "second_email": second_email,"daily_time_to_send": daily_time_to_send, "weekly_time_to_send": weekly_time_to_send}
+
+
+#Call this function in order to generate the Project Update for a specific project
+def create_project_update(project):
+	data = []
+	date_today = datetime.date.today()
+	time_now = frappe.utils.now_datetime().strftime('%H:%M:%S')
+	for projects in project:
+		project_update_dict = {
+			"doctype" : "Project Update",
+			"project" : projects[0],
+			"date": date_today,
+			"time": time_now,
+			"naming_series": "UPDATE-.project.-.YY.MM.DD.-"
+		}
+		project_update = frappe.get_doc(project_update_dict)
+		project_update.insert()
+		#you can edit your local_host
+		local_host = "http://localhost:8003"
+		project_update_url = "<a class = 'btn btn-primary' href=%s target='_blank'>" % (local_host +"/desk#Form/Project%20Update/" + (project_update.name)) + ("CREATE PROJECT UPDATE" + "</a>")
+		data.append(project_update_url)
+
+		email = frappe.db.sql("""SELECT user from `tabProject User` WHERE parent = %s;""", project[0])
+		for emails in email:
+			frappe.sendmail(
+				recipients=emails,
+				subject=frappe._(projects[0]),
+				header=[frappe._("Please Update your Project Status"), 'blue'],
+				message= project_update_url
+			)
+	return data
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project/project_dashboard.py b/erpnext/projects/doctype/project/project_dashboard.py
index 0ac7d6f..485aae7 100644
--- a/erpnext/projects/doctype/project/project_dashboard.py
+++ b/erpnext/projects/doctype/project/project_dashboard.py
@@ -8,7 +8,7 @@
 		'transactions': [
 			{
 				'label': _('Project'),
-				'items': ['Task', 'Timesheet', 'Expense Claim', 'Issue']
+				'items': ['Task', 'Timesheet', 'Expense Claim', 'Issue' , 'Project Update']
 			},
 			{
 				'label': _('Material'),
diff --git a/erpnext/projects/doctype/project_update/__init__.py b/erpnext/projects/doctype/project_update/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/projects/doctype/project_update/__init__.py
diff --git a/erpnext/projects/doctype/project_update/project_update.js b/erpnext/projects/doctype/project_update/project_update.js
new file mode 100644
index 0000000..990c1af
--- /dev/null
+++ b/erpnext/projects/doctype/project_update/project_update.js
@@ -0,0 +1,17 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Project Update', {
+	refresh: function() {
+
+	},
+
+	onload: function (frm) {
+		frm.set_value("naming_series", "UPDATE-.project.-.YY.MM.DD.-.####");
+	},
+
+	validate: function (frm) {
+		frm.set_value("time", frappe.datetime.now_time());
+		frm.set_value("date", frappe.datetime.nowdate());
+	}
+});
diff --git a/erpnext/projects/doctype/project_update/project_update.json b/erpnext/projects/doctype/project_update/project_update.json
new file mode 100644
index 0000000..a4eb1ee
--- /dev/null
+++ b/erpnext/projects/doctype/project_update/project_update.json
@@ -0,0 +1,366 @@
+{
+ "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "autoname": "naming_series:", 
+ "beta": 0, 
+ "creation": "2018-01-18 09:44:47.565494", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "editable_grid": 1, 
+ "engine": "InnoDB", 
+ "fields": [
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "project", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Project", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Project", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "column_break_2", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "date", 
+   "fieldtype": "Date", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Date", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "time", 
+   "fieldtype": "Time", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Time", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "section_break_5", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "progress", 
+   "fieldtype": "Select", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "How is the Project Progressing Right Now?", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Not Updated\nGreat/Quickly\nGood/Steady\nChallenging/Slow\nProblematic/Stuck", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "users", 
+   "fieldtype": "Table", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Users", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Project User", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "progress_details", 
+   "fieldtype": "Text Editor", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Progress Details", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "amended_from", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Amended From", 
+   "length": 0, 
+   "no_copy": 1, 
+   "options": "Project Update", 
+   "permlevel": 0, 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "", 
+   "fieldname": "naming_series", 
+   "fieldtype": "Data", 
+   "hidden": 1, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Series", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "UPDATE-.project.-.YY.MM.DD.-.####", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }
+ ], 
+ "has_web_view": 0, 
+ "hide_heading": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "image_view": 0, 
+ "in_create": 0, 
+ "is_submittable": 1, 
+ "issingle": 0, 
+ "istable": 0, 
+ "max_attachments": 0, 
+ "modified": "2018-02-14 10:50:16.794621", 
+ "modified_by": "Administrator", 
+ "module": "Projects", 
+ "name": "Project Update", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [
+  {
+   "amend": 0, 
+   "apply_user_permissions": 0, 
+   "cancel": 0, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "Projects User", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 1, 
+   "write": 1
+  }
+ ], 
+ "quick_entry": 0, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "show_name_in_global_search": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "track_changes": 1, 
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project_update/project_update.py b/erpnext/projects/doctype/project_update/project_update.py
new file mode 100644
index 0000000..8b4249f
--- /dev/null
+++ b/erpnext/projects/doctype/project_update/project_update.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class ProjectUpdate(Document):
+    pass
+
+@frappe.whitelist()
+def daily_reminder():
+    project = frappe.db.sql("""SELECT `tabProject`.project_name,`tabProject`.frequency,`tabProject`.expected_start_date,`tabProject`.expected_end_date,`tabProject`.percent_complete FROM `tabProject`;""")
+    for projects in project:
+        project_name = projects[0]
+        frequency = projects[1]
+        date_start = projects[2]
+        date_end = projects [3]
+        progress = projects [4]
+        draft = frappe.db.sql("""SELECT count(docstatus) from `tabProject Update` WHERE `tabProject Update`.project = %s AND `tabProject Update`.docstatus = 0;""",project_name)
+        for drafts in draft:
+            number_of_drafts = drafts[0]
+        update = frappe.db.sql("""SELECT name,date,time,progress,progress_details FROM `tabProject Update` WHERE `tabProject Update`.project = %s AND date = DATE_ADD(CURDATE(), INTERVAL -1 DAY);""",project_name)
+        email_sending(project_name,frequency,date_start,date_end,progress,number_of_drafts,update)
+
+def email_sending(project_name,frequency,date_start,date_end,progress,number_of_drafts,update):
+
+    holiday = frappe.db.sql("""SELECT holiday_date FROM `tabHoliday` where holiday_date = CURDATE();""")
+    msg = "<p>Project Name: " + project_name + "</p><p>Frequency: " + " " + frequency + "</p><p>Update Reminder:" + " " + str(date_start) + "</p><p>Expected Date End:" + " " + str(date_end) + "</p><p>Percent Progress:" + " " + str(progress) + "</p><p>Number of Updates:" + " " + str(len(update)) + "</p>" + "</p><p>Number of drafts:" + " " + str(number_of_drafts) + "</p>"
+    msg += """</u></b></p><table class='table table-bordered'><tr>
+                <th>Project ID</th><th>Date Updated</th><th>Time Updated</th><th>Project Status</th><th>Notes</th>"""
+    for updates in update:
+        msg += "<tr><td>" + str(updates[0]) + "</td><td>" + str(updates[1]) + "</td><td>" + str(updates[2]) + "</td><td>" + str(updates[3]) + "</td>" + "</td><td>" + str(updates[4]) + "</td></tr>"
+
+    msg += "</table>"
+    if len(holiday) == 0:
+        email = frappe.db.sql("""SELECT user from `tabProject User` WHERE parent = %s;""", project_name)
+    	for emails in email:
+    		frappe.sendmail(recipients=emails,subject=frappe._(project_name + ' ' + 'Summary'),message = msg)
+    else:
+    	pass
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project_update/test_project_update.js b/erpnext/projects/doctype/project_update/test_project_update.js
new file mode 100644
index 0000000..bda510b
--- /dev/null
+++ b/erpnext/projects/doctype/project_update/test_project_update.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Project Update", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Project Update
+		() => frappe.tests.make('Project Update', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/projects/doctype/project_update/test_project_update.py b/erpnext/projects/doctype/project_update/test_project_update.py
new file mode 100644
index 0000000..d5d0919
--- /dev/null
+++ b/erpnext/projects/doctype/project_update/test_project_update.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestProjectUpdate(unittest.TestCase):
+	pass
+
+test_records = frappe.get_test_records('Project Update')
+test_ignore = ["Sales Order"]
\ No newline at end of file