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
This commit is contained in:
parent
aa4d7a3436
commit
417dfed214
@ -12,6 +12,11 @@ def get_data():
|
||||
"name": "Project",
|
||||
"description": _("Project master."),
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Project Update",
|
||||
"description": _("Project Update."),
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Task",
|
||||
|
@ -1 +1 @@
|
||||
Project details. Projects can be internal or external and can have Tasks, Milestones associated to it.
|
||||
Project details. Projects can be internal or external and can have Tasks, Milestones associated to it.
|
||||
|
@ -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 @@ frappe.ui.form.on("Project", {
|
||||
);
|
||||
},
|
||||
|
||||
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 @@ frappe.ui.form.on("Project", {
|
||||
|
||||
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 @@ frappe.ui.form.on("Project", {
|
||||
});
|
||||
},
|
||||
|
||||
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 @@ frappe.ui.form.on("Project", {
|
||||
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);
|
||||
}
|
||||
});
|
||||
});
|
@ -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",
|
||||
|
@ -10,6 +10,7 @@ from frappe import _
|
||||
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 @@ class Project(Document):
|
||||
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 @@ class Project(Document):
|
||||
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 @@ class Project(Document):
|
||||
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 @@ class Project(Document):
|
||||
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 @@ class Project(Document):
|
||||
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 @@ class Project(Document):
|
||||
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 @@ class Project(Document):
|
||||
|
||||
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 @@ class Project(Document):
|
||||
"""
|
||||
|
||||
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 @@ class Project(Document):
|
||||
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 @@ def get_timeline_data(doctype, name):
|
||||
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 @@ def get_project_list(doctype, txt, filters, limit_start, limit_page_length=20, o
|
||||
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 @@ def get_users_for_project(doctype, txt, searchfield, start, page_len, filters):
|
||||
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
|
@ -8,7 +8,7 @@ def get_data():
|
||||
'transactions': [
|
||||
{
|
||||
'label': _('Project'),
|
||||
'items': ['Task', 'Timesheet', 'Expense Claim', 'Issue']
|
||||
'items': ['Task', 'Timesheet', 'Expense Claim', 'Issue' , 'Project Update']
|
||||
},
|
||||
{
|
||||
'label': _('Material'),
|
||||
|
0
erpnext/projects/doctype/project_update/__init__.py
Normal file
0
erpnext/projects/doctype/project_update/__init__.py
Normal file
17
erpnext/projects/doctype/project_update/project_update.js
Normal file
17
erpnext/projects/doctype/project_update/project_update.js
Normal file
@ -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());
|
||||
}
|
||||
});
|
366
erpnext/projects/doctype/project_update/project_update.json
Normal file
366
erpnext/projects/doctype/project_update/project_update.json
Normal file
@ -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
|
||||
}
|
42
erpnext/projects/doctype/project_update/project_update.py
Normal file
42
erpnext/projects/doctype/project_update/project_update.py
Normal file
@ -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
|
@ -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()
|
||||
]);
|
||||
|
||||
});
|
@ -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"]
|
Loading…
x
Reference in New Issue
Block a user