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",
|
"name": "Project",
|
||||||
"description": _("Project master."),
|
"description": _("Project master."),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Project Update",
|
||||||
|
"description": _("Project Update."),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Task",
|
"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
|
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
// License: GNU General Public License v3. See license.txt
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Project", {
|
frappe.ui.form.on("Project", {
|
||||||
setup: function(frm) {
|
setup: function (frm) {
|
||||||
frm.set_indicator_formatter('title',
|
frm.set_indicator_formatter('title',
|
||||||
function(doc) {
|
function (doc) {
|
||||||
let indicator = 'orange';
|
let indicator = 'orange';
|
||||||
if (doc.status == 'Overdue') {
|
if (doc.status == 'Overdue') {
|
||||||
indicator = 'red';
|
indicator = 'red';
|
||||||
}
|
} else if (doc.status == 'Cancelled') {
|
||||||
else if (doc.status == 'Cancelled') {
|
|
||||||
indicator = 'dark grey';
|
indicator = 'dark grey';
|
||||||
}
|
} else if (doc.status == 'Closed') {
|
||||||
else if (doc.status == 'Closed') {
|
|
||||||
indicator = 'green';
|
indicator = 'green';
|
||||||
}
|
}
|
||||||
return indicator;
|
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");
|
var so = frappe.meta.get_docfield("Project", "sales_order");
|
||||||
so.get_route_options_for_new_doc = function(field) {
|
so.get_route_options_for_new_doc = function (field) {
|
||||||
if(frm.is_new()) return;
|
if (frm.is_new()) return;
|
||||||
return {
|
return {
|
||||||
"customer": frm.doc.customer,
|
"customer": frm.doc.customer,
|
||||||
"project_name": frm.doc.name
|
"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('customer', 'erpnext.controllers.queries.customer_query');
|
||||||
|
|
||||||
frm.set_query("user", "users", function() {
|
frm.set_query("user", "users", function () {
|
||||||
return {
|
return {
|
||||||
query:"erpnext.projects.doctype.project.project.get_users_for_project"
|
query: "erpnext.projects.doctype.project.project.get_users_for_project"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// sales order
|
// sales order
|
||||||
frm.set_query('sales_order', function() {
|
frm.set_query('sales_order', function () {
|
||||||
var filters = {
|
var filters = {
|
||||||
'project': ["in", frm.doc.__islocal ? [""] : [frm.doc.name, ""]]
|
'project': ["in", frm.doc.__islocal ? [""] : [frm.doc.name, ""]]
|
||||||
};
|
};
|
||||||
@ -54,15 +51,17 @@ frappe.ui.form.on("Project", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function(frm) {
|
refresh: function (frm) {
|
||||||
if(frm.doc.__islocal) {
|
if (frm.doc.__islocal) {
|
||||||
frm.web_link && frm.web_link.remove();
|
frm.web_link && frm.web_link.remove();
|
||||||
} else {
|
} else {
|
||||||
frm.add_web_link("/projects?project=" + encodeURIComponent(frm.doc.name));
|
frm.add_web_link("/projects?project=" + encodeURIComponent(frm.doc.name));
|
||||||
|
|
||||||
if(frappe.model.can_read("Task")) {
|
if (frappe.model.can_read("Task")) {
|
||||||
frm.add_custom_button(__("Gantt Chart"), function() {
|
frm.add_custom_button(__("Gantt Chart"), function () {
|
||||||
frappe.route_options = {"project": frm.doc.name};
|
frappe.route_options = {
|
||||||
|
"project": frm.doc.name
|
||||||
|
};
|
||||||
frappe.set_route("List", "Task", "Gantt");
|
frappe.set_route("List", "Task", "Gantt");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -70,65 +69,69 @@ frappe.ui.form.on("Project", {
|
|||||||
frm.trigger('show_dashboard');
|
frm.trigger('show_dashboard');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tasks_refresh: function(frm) {
|
tasks_refresh: function (frm) {
|
||||||
var grid = frm.get_field('tasks').grid;
|
var grid = frm.get_field('tasks').grid;
|
||||||
grid.wrapper.find('select[data-fieldname="status"]').each(function() {
|
grid.wrapper.find('select[data-fieldname="status"]').each(function () {
|
||||||
if($(this).val()==='Open') {
|
if ($(this).val() === 'Open') {
|
||||||
$(this).addClass('input-indicator-open');
|
$(this).addClass('input-indicator-open');
|
||||||
} else {
|
} else {
|
||||||
$(this).removeClass('input-indicator-open');
|
$(this).removeClass('input-indicator-open');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
show_dashboard: function(frm) {
|
edit_task: function (frm, doctype, name) {
|
||||||
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) {
|
|
||||||
var doc = frappe.get_doc(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);
|
frappe.set_route("Form", "Task", doc.task_id);
|
||||||
} else {
|
} else {
|
||||||
frappe.msgprint(__("Save the document first."));
|
frappe.msgprint(__("Save the document first."));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
edit_timesheet: function(frm, cdt, cdn) {
|
edit_timesheet: function (frm, cdt, cdn) {
|
||||||
var child = locals[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");
|
frappe.set_route("List", "Timesheet");
|
||||||
},
|
},
|
||||||
|
make_timesheet: function (frm, cdt, cdn) {
|
||||||
make_timesheet: function(frm, cdt, cdn) {
|
|
||||||
var child = locals[cdt][cdn];
|
var child = locals[cdt][cdn];
|
||||||
frappe.model.with_doctype('Timesheet', function() {
|
frappe.model.with_doctype('Timesheet', function () {
|
||||||
var doc = frappe.model.get_new_doc('Timesheet');
|
var doc = frappe.model.get_new_doc('Timesheet');
|
||||||
var row = frappe.model.add_child(doc, 'time_logs');
|
var row = frappe.model.add_child(doc, 'time_logs');
|
||||||
row.project = frm.doc.project_name;
|
row.project = frm.doc.project_name;
|
||||||
row.task = child.task_id;
|
row.task = child.task_id;
|
||||||
frappe.set_route('Form', doc.doctype, doc.name);
|
frappe.set_route('Form', doc.doctype, doc.name);
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
status: function(frm, doctype, name) {
|
status: function (frm, doctype, name) {
|
||||||
frm.trigger('tasks_refresh');
|
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,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 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,
|
"has_web_view": 0,
|
||||||
@ -1285,7 +1626,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 4,
|
"max_attachments": 4,
|
||||||
"modified": "2017-12-10 08:40:46.843201",
|
"modified": "2018-01-29 11:48:21.156697",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Projects",
|
"module": "Projects",
|
||||||
"name": "Project",
|
"name": "Project",
|
||||||
|
@ -10,6 +10,7 @@ from frappe import _
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from erpnext.controllers.queries import get_filters_cond
|
from erpnext.controllers.queries import get_filters_cond
|
||||||
from frappe.desk.reportview import get_match_cond
|
from frappe.desk.reportview import get_match_cond
|
||||||
|
import datetime
|
||||||
|
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
|
|
||||||
@ -79,7 +80,8 @@ class Project(Document):
|
|||||||
if task.task_weight or 0 > 0:
|
if task.task_weight or 0 > 0:
|
||||||
sum = sum + task.task_weight
|
sum = sum + task.task_weight
|
||||||
if sum > 0 and sum != 1:
|
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):
|
def sync_tasks(self):
|
||||||
"""sync tasks and remove table"""
|
"""sync tasks and remove table"""
|
||||||
@ -105,7 +107,7 @@ class Project(Document):
|
|||||||
task.flags.ignore_links = True
|
task.flags.ignore_links = True
|
||||||
task.flags.from_project = True
|
task.flags.from_project = True
|
||||||
task.flags.ignore_feed = True
|
task.flags.ignore_feed = True
|
||||||
task.save(ignore_permissions = True)
|
task.save(ignore_permissions=True)
|
||||||
task_names.append(task.name)
|
task_names.append(task.name)
|
||||||
|
|
||||||
# delete
|
# delete
|
||||||
@ -127,18 +129,18 @@ class Project(Document):
|
|||||||
self.update_percent_complete()
|
self.update_percent_complete()
|
||||||
self.update_costing()
|
self.update_costing()
|
||||||
self.flags.dont_sync_tasks = True
|
self.flags.dont_sync_tasks = True
|
||||||
self.save(ignore_permissions = True)
|
self.save(ignore_permissions=True)
|
||||||
|
|
||||||
def after_insert(self):
|
def after_insert(self):
|
||||||
if self.sales_order:
|
if self.sales_order:
|
||||||
frappe.db.set_value("Sales Order", self.sales_order, "project", self.name)
|
frappe.db.set_value("Sales Order", self.sales_order, "project", self.name)
|
||||||
|
|
||||||
|
|
||||||
def update_percent_complete(self):
|
def update_percent_complete(self):
|
||||||
total = frappe.db.sql("""select count(name) 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 not total and self.percent_complete:
|
if not total and self.percent_complete:
|
||||||
self.percent_complete = 0
|
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
|
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)
|
||||||
@ -153,8 +155,8 @@ class Project(Document):
|
|||||||
project=%s""", self.name)[0][0]
|
project=%s""", self.name)[0][0]
|
||||||
if weight_sum == 1:
|
if weight_sum == 1:
|
||||||
weighted_progress = frappe.db.sql("""select progress,task_weight from tabTask where
|
weighted_progress = frappe.db.sql("""select progress,task_weight from tabTask where
|
||||||
project=%s""", self.name,as_dict=1)
|
project=%s""", self.name, as_dict=1)
|
||||||
pct_complete=0
|
pct_complete = 0
|
||||||
for row in weighted_progress:
|
for row in weighted_progress:
|
||||||
pct_complete += row["progress"] * row["task_weight"]
|
pct_complete += row["progress"] * row["task_weight"]
|
||||||
self.percent_complete = flt(flt(pct_complete), 2)
|
self.percent_complete = flt(flt(pct_complete), 2)
|
||||||
@ -172,7 +174,7 @@ class Project(Document):
|
|||||||
sum(total_sanctioned_amount) as total_sanctioned_amount
|
sum(total_sanctioned_amount) as total_sanctioned_amount
|
||||||
from `tabExpense Claim` where project = %s
|
from `tabExpense Claim` where project = %s
|
||||||
and docstatus = 1""",
|
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_start_date = from_time_sheet.start_date
|
||||||
self.actual_end_date = from_time_sheet.end_date
|
self.actual_end_date = from_time_sheet.end_date
|
||||||
@ -186,10 +188,11 @@ class Project(Document):
|
|||||||
self.update_sales_amount()
|
self.update_sales_amount()
|
||||||
self.update_billed_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:
|
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):
|
def update_purchase_costing(self):
|
||||||
total_purchase_cost = frappe.db.sql("""select sum(base_net_amount)
|
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
|
self.total_billed_amount = total_billed_amount and total_billed_amount[0][0] or 0
|
||||||
|
|
||||||
|
|
||||||
def send_welcome_email(self):
|
def send_welcome_email(self):
|
||||||
url = get_url("/project/?name={0}".format(self.name))
|
url = get_url("/project/?name={0}".format(self.name))
|
||||||
messages = (
|
messages = (
|
||||||
_("You have been invited to collaborate on the project: {0}".format(self.name)),
|
_("You have been invited to collaborate on the project: {0}".format(self.name)),
|
||||||
url,
|
url,
|
||||||
_("Join")
|
_("Join")
|
||||||
)
|
)
|
||||||
|
|
||||||
content = """
|
content = """
|
||||||
@ -224,9 +226,10 @@ class Project(Document):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
for user in self.users:
|
for user in self.users:
|
||||||
if user.welcome_email_sent==0:
|
if user.welcome_email_sent == 0:
|
||||||
frappe.sendmail(user.user, subject=_("Project Collaboration Invitation"), content=content.format(*messages))
|
frappe.sendmail(user.user, subject=_("Project Collaboration Invitation"),
|
||||||
user.welcome_email_sent=1
|
content=content.format(*messages))
|
||||||
|
user.welcome_email_sent = 1
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
self.load_tasks()
|
self.load_tasks()
|
||||||
@ -256,18 +259,23 @@ class Project(Document):
|
|||||||
depends_on_tasks = _task.depends_on_tasks
|
depends_on_tasks = _task.depends_on_tasks
|
||||||
|
|
||||||
depends_on_tasks = [x for x in depends_on_tasks.split(',') if x]
|
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'])]
|
'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):
|
for key, value in iteritems(dependency_map):
|
||||||
task_name = frappe.db.get_value('Task', {"subject": key, "project": self.name })
|
task_name = frappe.db.get_value('Task', {"subject": key, "project": self.name })
|
||||||
|
|
||||||
task_doc = frappe.get_doc('Task', task_name)
|
task_doc = frappe.get_doc('Task', task_name)
|
||||||
|
|
||||||
for dt in value:
|
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.append('depends_on', {"task": dt_name})
|
||||||
task_doc.save()
|
task_doc.save()
|
||||||
|
|
||||||
|
|
||||||
def get_timeline_data(doctype, name):
|
def get_timeline_data(doctype, name):
|
||||||
'''Return timeline for attendance'''
|
'''Return timeline for attendance'''
|
||||||
return dict(frappe.db.sql('''select unix_timestamp(from_time), count(*)
|
return dict(frappe.db.sql('''select unix_timestamp(from_time), count(*)
|
||||||
@ -276,6 +284,7 @@ def get_timeline_data(doctype, name):
|
|||||||
and docstatus < 2
|
and docstatus < 2
|
||||||
group by date(from_time)''', name))
|
group by date(from_time)''', name))
|
||||||
|
|
||||||
|
|
||||||
def get_project_list(doctype, txt, filters, limit_start, limit_page_length=20, order_by="modified"):
|
def get_project_list(doctype, txt, filters, limit_start, limit_page_length=20, order_by="modified"):
|
||||||
return frappe.db.sql('''select distinct project.*
|
return frappe.db.sql('''select distinct project.*
|
||||||
from tabProject project, `tabProject User` project_user
|
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
|
order by project.modified desc
|
||||||
limit {0}, {1}
|
limit {0}, {1}
|
||||||
'''.format(limit_start, limit_page_length),
|
'''.format(limit_start, limit_page_length),
|
||||||
{'user':frappe.session.user},
|
{'user': frappe.session.user},
|
||||||
as_dict=True,
|
as_dict=True,
|
||||||
update={'doctype':'Project'})
|
update={'doctype': 'Project'})
|
||||||
|
|
||||||
|
|
||||||
def get_list_context(context=None):
|
def get_list_context(context=None):
|
||||||
return {
|
return {
|
||||||
@ -315,16 +325,85 @@ def get_users_for_project(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
idx desc,
|
idx desc,
|
||||||
name, full_name
|
name, full_name
|
||||||
limit %(start)s, %(page_len)s""".format(**{
|
limit %(start)s, %(page_len)s""".format(**{
|
||||||
'key': searchfield,
|
'key': searchfield,
|
||||||
'fcond': get_filters_cond(doctype, filters, conditions),
|
'fcond': get_filters_cond(doctype, filters, conditions),
|
||||||
'mcond': get_match_cond(doctype)
|
'mcond': get_match_cond(doctype)
|
||||||
}), {
|
}), {
|
||||||
'txt': "%%%s%%" % txt,
|
'txt': "%%%s%%" % txt,
|
||||||
'_txt': txt.replace("%", ""),
|
'_txt': txt.replace("%", ""),
|
||||||
'start': start,
|
'start': start,
|
||||||
'page_len': page_len
|
'page_len': page_len
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_cost_center_name(project):
|
def get_cost_center_name(project):
|
||||||
return frappe.db.get_value("Project", project, "cost_center")
|
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': [
|
'transactions': [
|
||||||
{
|
{
|
||||||
'label': _('Project'),
|
'label': _('Project'),
|
||||||
'items': ['Task', 'Timesheet', 'Expense Claim', 'Issue']
|
'items': ['Task', 'Timesheet', 'Expense Claim', 'Issue' , 'Project Update']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'label': _('Material'),
|
'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