move Subscription to frappe as Auto Repeat
This commit is contained in:
parent
0c53ff9ca4
commit
40d378e454
8 changed files with 1422 additions and 1 deletions
0
frappe/desk/doctype/auto_repeat/__init__.py
Normal file
0
frappe/desk/doctype/auto_repeat/__init__.py
Normal file
75
frappe/desk/doctype/auto_repeat/auto_repeat.js
Normal file
75
frappe/desk/doctype/auto_repeat/auto_repeat.js
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
// Copyright (c) 2018, Frappe Technologies and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Auto Repeat', {
|
||||
setup: function(frm) {
|
||||
frm.fields_dict['reference_doctype'].get_query = function(doc) {
|
||||
return {
|
||||
query: "frappe.desk.doctype.auto_repeat.auto_repeat.auto_repeat_doctype_query"
|
||||
};
|
||||
};
|
||||
|
||||
frm.fields_dict['reference_document'].get_query = function() {
|
||||
return {
|
||||
filters: {
|
||||
"docstatus": 1,
|
||||
"auto_repeat": ''
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
frm.fields_dict['print_format'].get_query = function() {
|
||||
return {
|
||||
filters: {
|
||||
"doc_type": frm.doc.reference_doctype
|
||||
}
|
||||
};
|
||||
};
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
if(frm.doc.docstatus == 1) {
|
||||
let label = __('View {0}', [frm.doc.reference_doctype]);
|
||||
frm.add_custom_button(__(label),
|
||||
function() {
|
||||
frappe.route_options = {
|
||||
"auto_repeat": frm.doc.name,
|
||||
};
|
||||
frappe.set_route("List", frm.doc.reference_doctype);
|
||||
}
|
||||
);
|
||||
|
||||
if(frm.doc.status != 'Stopped') {
|
||||
frm.add_custom_button(__("Stop"),
|
||||
function() {
|
||||
frm.events.stop_resume_auto_repeat(frm, "Stopped");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if(frm.doc.status == 'Stopped') {
|
||||
frm.add_custom_button(__("Resume"),
|
||||
function() {
|
||||
frm.events.stop_resume_auto_repeat(frm, "Resumed");
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
stop_resume_auto_repeat: function(frm, status) {
|
||||
frappe.call({
|
||||
method: "frappe.desk.doctype.auto_repeat.auto_repeat.stop_resume_auto_repeat",
|
||||
args: {
|
||||
subscription: frm.doc.name,
|
||||
status: status
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
frm.set_value("status", r.message);
|
||||
frm.reload_doc();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
888
frappe/desk/doctype/auto_repeat/auto_repeat.json
Normal file
888
frappe/desk/doctype/auto_repeat/auto_repeat.json
Normal file
|
|
@ -0,0 +1,888 @@
|
|||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "naming_series:",
|
||||
"beta": 0,
|
||||
"creation": "2018-03-09 11:22:31.192349",
|
||||
"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": "section_break_1",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "naming_series",
|
||||
"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": "Series",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "SUB-",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "reference_doctype",
|
||||
"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": "Reference Doctype",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "DocType",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "reference_document",
|
||||
"fieldtype": "Dynamic 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": "Reference Document",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "reference_doctype",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_5",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "start_date",
|
||||
"fieldtype": "Date",
|
||||
"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": "Start Date",
|
||||
"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": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "end_date",
|
||||
"fieldtype": "Date",
|
||||
"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": "End Date",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "submit_on_creation",
|
||||
"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": "Submit on Creation",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "disabled",
|
||||
"fieldtype": "Check",
|
||||
"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": "Disabled",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_10",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "frequency",
|
||||
"fieldtype": "Select",
|
||||
"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": "Frequency",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nDaily\nWeekly\nMonthly\nQuarterly\nHalf-yearly\nYearly",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_13",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval: in_list([\"Monthly\", \"Quarterly\", \"Yearly\"], doc.frequency)",
|
||||
"fieldname": "repeat_on_day",
|
||||
"fieldtype": "Int",
|
||||
"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": "Repeat on Day",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "next_schedule_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": "Next Schedule Date",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"fieldname": "notification",
|
||||
"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": "Notification",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "notify_by_email",
|
||||
"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": "Notify by 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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval: doc.notify_by_email",
|
||||
"description": "To add dynamic subject, use jinja tags like\n\n<div><pre><code>New {{ doc.doctype }} #{{ doc.name }}</code></pre></div>",
|
||||
"fieldname": "subject",
|
||||
"fieldtype": "Data",
|
||||
"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": "Subject",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_17",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "notify_by_email",
|
||||
"fieldname": "recipients",
|
||||
"fieldtype": "Small Text",
|
||||
"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": "Recipients",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "notify_by_email",
|
||||
"fieldname": "print_format",
|
||||
"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": "Print Format",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Print Format",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.notify_by_email",
|
||||
"fieldname": "section_break_20",
|
||||
"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": "Message",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Please find attached {{ doc.doctype }} #{{ doc.name }}",
|
||||
"fieldname": "message",
|
||||
"fieldtype": "Text",
|
||||
"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": "Message",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"depends_on": "eval: !doc.__islocal",
|
||||
"fieldname": "section_break_16",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"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": "Status",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nDraft\nStopped\nSubmitted\nCancelled\nCompleted",
|
||||
"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,
|
||||
"translatable": 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": "Auto Repeat",
|
||||
"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,
|
||||
"translatable": 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-03-10 14:45:49.645884",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Desk",
|
||||
"name": "Auto Repeat",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"search_fields": "reference_document",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "reference_document",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
332
frappe/desk/doctype/auto_repeat/auto_repeat.py
Normal file
332
frappe/desk/doctype/auto_repeat/auto_repeat.py
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
# -*- 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
|
||||
import calendar
|
||||
from frappe import _
|
||||
from frappe.desk.form import assign_to
|
||||
from frappe.utils.jinja import validate_template
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from frappe.utils.user import get_system_managers
|
||||
from frappe.utils import cstr, getdate, split_emails, add_days, today, get_last_day, get_first_day
|
||||
from frappe.model.document import Document
|
||||
|
||||
month_map = {'Monthly': 1, 'Quarterly': 3, 'Half-yearly': 6, 'Yearly': 12}
|
||||
|
||||
|
||||
class AutoRepeat(Document):
|
||||
def validate(self):
|
||||
self.update_status()
|
||||
self.validate_reference_doctype()
|
||||
self.validate_dates()
|
||||
self.validate_next_schedule_date()
|
||||
self.validate_email_id()
|
||||
|
||||
validate_template(self.subject or "")
|
||||
validate_template(self.message or "")
|
||||
|
||||
def before_submit(self):
|
||||
if not self.next_schedule_date:
|
||||
self.next_schedule_date = get_next_schedule_date(
|
||||
self.start_date, self.frequency, self.repeat_on_day)
|
||||
|
||||
def on_submit(self):
|
||||
self.update_auto_repeat_id()
|
||||
|
||||
def on_update_after_submit(self):
|
||||
self.validate_dates()
|
||||
self.set_next_schedule_date()
|
||||
|
||||
def before_cancel(self):
|
||||
self.unlink_auto_repeat_id()
|
||||
self.next_schedule_date = None
|
||||
|
||||
def unlink_auto_repeat_id(self):
|
||||
frappe.db.sql(
|
||||
"update `tab{0}` set auto_repeat = null where auto_repeat=%s".format(self.reference_doctype), self.name)
|
||||
|
||||
def validate_reference_doctype(self):
|
||||
if not frappe.get_meta(self.reference_doctype).has_field('auto_repeat'):
|
||||
frappe.throw(_("Add custom field Auto Repeat in the doctype {0}").format(self.reference_doctype))
|
||||
|
||||
def validate_dates(self):
|
||||
if self.end_date and getdate(self.start_date) > getdate(self.end_date):
|
||||
frappe.throw(_("End date must be greater than start date"))
|
||||
|
||||
def validate_next_schedule_date(self):
|
||||
if self.repeat_on_day and self.next_schedule_date:
|
||||
next_date = getdate(self.next_schedule_date)
|
||||
if next_date.day != self.repeat_on_day:
|
||||
# if the repeat day is the last day of the month (31)
|
||||
# and the current month does not have as many days,
|
||||
# then the last day of the current month is a valid date
|
||||
lastday = calendar.monthrange(next_date.year, next_date.month)[1]
|
||||
if self.repeat_on_day < lastday:
|
||||
# the specified day of the month is not same as the day specified
|
||||
# or the last day of the month
|
||||
frappe.throw(_("Next Date's day and Repeat on Day of Month must be equal"))
|
||||
|
||||
def validate_email_id(self):
|
||||
if self.notify_by_email:
|
||||
if self.recipients:
|
||||
email_list = split_emails(self.recipients.replace("\n", ""))
|
||||
|
||||
from frappe.utils import validate_email_add
|
||||
for email in email_list:
|
||||
if not validate_email_add(email):
|
||||
frappe.throw(_("{0} is an invalid email address in 'Recipients'").format(email))
|
||||
else:
|
||||
frappe.throw(_("'Recipients' not specified"))
|
||||
|
||||
def set_next_schedule_date(self):
|
||||
if self.repeat_on_day:
|
||||
self.next_schedule_date = get_next_date(self.next_schedule_date, 0, self.repeat_on_day)
|
||||
|
||||
def update_auto_repeat_id(self):
|
||||
frappe.db.set_value(self.reference_doctype, self.reference_document, "auto_repeat", self.name)
|
||||
|
||||
def update_status(self, status=None):
|
||||
self.status = {
|
||||
'0': 'Draft',
|
||||
'1': 'Submitted',
|
||||
'2': 'Cancelled'
|
||||
}[cstr(self.docstatus or 0)]
|
||||
|
||||
if status and status != 'Resumed':
|
||||
self.status = status
|
||||
|
||||
|
||||
def get_next_schedule_date(start_date, frequency, repeat_on_day):
|
||||
mcount = month_map.get(frequency)
|
||||
if mcount:
|
||||
next_date = get_next_date(start_date, mcount, repeat_on_day)
|
||||
else:
|
||||
days = 7 if frequency == 'Weekly' else 1
|
||||
next_date = add_days(start_date, days)
|
||||
return next_date
|
||||
|
||||
|
||||
def make_auto_repeat_entry(date=None):
|
||||
date = date or today()
|
||||
for data in get_auto_repeat_entries(date):
|
||||
schedule_date = getdate(data.next_schedule_date)
|
||||
while schedule_date <= getdate(today()):
|
||||
create_documents(data, schedule_date)
|
||||
schedule_date = get_next_schedule_date(
|
||||
schedule_date, data.frequency, data.repeat_on_day)
|
||||
|
||||
if schedule_date and not frappe.db.get_value('Auto Repeat', data.name, 'disabled'):
|
||||
frappe.db.set_value('Auto Repeat', data.name, 'next_schedule_date', schedule_date)
|
||||
|
||||
|
||||
def get_auto_repeat_entries(date):
|
||||
return frappe.db.sql(""" select * from `tabAuto Repeat`
|
||||
where docstatus = 1 and next_schedule_date <=%s
|
||||
and reference_document is not null and reference_document != ''
|
||||
and next_schedule_date <= ifnull(end_date, '2199-12-31')
|
||||
and ifnull(disabled, 0) = 0 and status != 'Stopped' """, (date), as_dict=1)
|
||||
|
||||
|
||||
def create_documents(data, schedule_date):
|
||||
try:
|
||||
doc = make_new_document(data, schedule_date)
|
||||
if data.notify_by_email and data.recipients:
|
||||
print_format = data.print_format or "Standard"
|
||||
send_notification(doc, data, print_format=print_format)
|
||||
|
||||
frappe.db.commit()
|
||||
except Exception:
|
||||
frappe.db.rollback()
|
||||
frappe.db.begin()
|
||||
frappe.log_error(frappe.get_traceback())
|
||||
disable_auto_repeat(data)
|
||||
frappe.db.commit()
|
||||
if data.reference_document and not frappe.flags.in_test:
|
||||
notify_error_to_user(data)
|
||||
|
||||
|
||||
def disable_auto_repeat(data):
|
||||
auto_repeat = frappe.get_doc('Auto Repeat', data.name)
|
||||
auto_repeat.db_set('disabled', 1)
|
||||
|
||||
|
||||
def notify_error_to_user(data):
|
||||
party = ''
|
||||
party_type = ''
|
||||
|
||||
if data.reference_doctype in ['Sales Order', 'Sales Invoice', 'Delivery Note']:
|
||||
party_type = 'customer'
|
||||
elif data.reference_doctype in ['Purchase Order', 'Purchase Invoice', 'Purchase Receipt']:
|
||||
party_type = 'supplier'
|
||||
|
||||
if party_type:
|
||||
party = frappe.db.get_value(data.reference_doctype, data.reference_document, party_type)
|
||||
|
||||
notify_errors(data.reference_document, data.reference_doctype, party, data.owner, data.name)
|
||||
|
||||
|
||||
def make_new_document(args, schedule_date):
|
||||
doc = frappe.get_doc(args.reference_doctype, args.reference_document)
|
||||
new_doc = frappe.copy_doc(doc, ignore_no_copy=False)
|
||||
update_doc(new_doc, doc, args, schedule_date)
|
||||
new_doc.insert(ignore_permissions=True)
|
||||
|
||||
if args.submit_on_creation:
|
||||
new_doc.submit()
|
||||
|
||||
return new_doc
|
||||
|
||||
|
||||
def update_doc(new_document, reference_doc, args, schedule_date):
|
||||
new_document.docstatus = 0
|
||||
if new_document.meta.get_field('set_posting_time'):
|
||||
new_document.set('set_posting_time', 1)
|
||||
|
||||
mcount = month_map.get(args.frequency)
|
||||
|
||||
if new_document.meta.get_field('auto_repeat'):
|
||||
new_document.set('auto_repeat', args.name)
|
||||
|
||||
for fieldname in ['naming_series', 'ignore_pricing_rule', 'posting_time',
|
||||
'select_print_heading', 'remarks', 'owner']:
|
||||
if new_document.meta.get_field(fieldname):
|
||||
new_document.set(fieldname, reference_doc.get(fieldname))
|
||||
|
||||
# copy item fields
|
||||
if new_document.meta.get_field('items'):
|
||||
for i, item in enumerate(new_document.items):
|
||||
for fieldname in ("page_break",):
|
||||
item.set(fieldname, reference_doc.items[i].get(fieldname))
|
||||
|
||||
for data in new_document.meta.fields:
|
||||
if data.fieldtype == 'Date' and data.reqd:
|
||||
new_document.set(data.fieldname, schedule_date)
|
||||
|
||||
set_auto_repeat_period(args, mcount, new_document)
|
||||
|
||||
new_document.run_method("on_recurring", reference_doc=reference_doc, auto_repeat_doc=args)
|
||||
|
||||
|
||||
def set_auto_repeat_period(args, mcount, new_document):
|
||||
if mcount and new_document.meta.get_field('from_date') and new_document.meta.get_field('to_date'):
|
||||
last_ref_doc = frappe.db.sql("""
|
||||
select name, from_date, to_date
|
||||
from `tab{0}`
|
||||
where auto_repeat=%s and docstatus < 2
|
||||
order by creation desc
|
||||
limit 1
|
||||
""".format(args.reference_doctype), args.name, as_dict=1)
|
||||
|
||||
if not last_ref_doc:
|
||||
return
|
||||
|
||||
from_date = get_next_date(last_ref_doc[0].from_date, mcount)
|
||||
|
||||
if (cstr(get_first_day(last_ref_doc[0].from_date)) == cstr(last_ref_doc[0].from_date)) and \
|
||||
(cstr(get_last_day(last_ref_doc[0].to_date)) == cstr(last_ref_doc[0].to_date)):
|
||||
to_date = get_last_day(get_next_date(last_ref_doc[0].to_date, mcount))
|
||||
else:
|
||||
to_date = get_next_date(last_ref_doc[0].to_date, mcount)
|
||||
|
||||
new_document.set('from_date', from_date)
|
||||
new_document.set('to_date', to_date)
|
||||
|
||||
|
||||
def get_next_date(dt, mcount, day=None):
|
||||
dt = getdate(dt)
|
||||
dt += relativedelta(months=mcount, day=day)
|
||||
|
||||
return dt
|
||||
|
||||
|
||||
def send_notification(new_rv, auto_repeat_doc, print_format='Standard'):
|
||||
"""Notify concerned persons about recurring document generation"""
|
||||
print_format = print_format
|
||||
subject = auto_repeat_doc.subject or ''
|
||||
message = auto_repeat_doc.message or ''
|
||||
|
||||
if not auto_repeat_doc.subject:
|
||||
subject = _("New {0}: #{1}").format(new_rv.doctype, new_rv.name)
|
||||
elif "{" in auto_repeat_doc.subject:
|
||||
subject = frappe.render_template(auto_repeat_doc.subject, {'doc': new_rv})
|
||||
|
||||
if not auto_repeat_doc.message:
|
||||
message = _("Please find attached {0} #{1}").format(new_rv.doctype, new_rv.name)
|
||||
elif "{" in auto_repeat_doc.message:
|
||||
message = frappe.render_template(auto_repeat_doc.message, {'doc': new_rv})
|
||||
|
||||
attachments = [frappe.attach_print(new_rv.doctype, new_rv.name,
|
||||
file_name=new_rv.name, print_format=print_format)]
|
||||
|
||||
frappe.sendmail(auto_repeat_doc.recipients,
|
||||
subject=subject, message=message, attachments=attachments)
|
||||
|
||||
|
||||
def notify_errors(doc, doctype, party, owner, name):
|
||||
recipients = get_system_managers(only_name=True)
|
||||
frappe.sendmail(recipients + [frappe.db.get_value("User", owner, "email")],
|
||||
subject=_("[Urgent] Error while creating recurring %s for %s" % (doctype, doc)),
|
||||
message=frappe.get_template("templates/emails/recurring_document_failed.html").render({
|
||||
"type": _(doctype),
|
||||
"name": doc,
|
||||
"party": party or "",
|
||||
"auto_repeat": name
|
||||
}))
|
||||
|
||||
assign_task_to_owner(name, "Recurring Documents Failed", recipients)
|
||||
|
||||
|
||||
def assign_task_to_owner(name, msg, users):
|
||||
for d in users:
|
||||
args = {
|
||||
'doctype': 'Auto Repeat',
|
||||
'assign_to': d,
|
||||
'name': name,
|
||||
'description': msg,
|
||||
'priority': 'High'
|
||||
}
|
||||
assign_to.add(args)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_auto_repeat(doctype, docname):
|
||||
doc = frappe.new_doc('Auto Repeat')
|
||||
|
||||
reference_doc = frappe.get_doc(doctype, docname)
|
||||
doc.reference_doctype = doctype
|
||||
doc.reference_document = docname
|
||||
doc.start_date = reference_doc.get('posting_date') or reference_doc.get('transaction_date')
|
||||
return doc
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def stop_resume_auto_repeat(auto_repeat, status):
|
||||
doc = frappe.get_doc('Auto Repeat', auto_repeat)
|
||||
frappe.msgprint(_("Auto Repeat has been {0}").format(status))
|
||||
if status == 'Resumed':
|
||||
doc.next_schedule_date = get_next_schedule_date(today(),
|
||||
doc.frequency, doc.repeat_on_day)
|
||||
|
||||
doc.update_status(status)
|
||||
doc.save()
|
||||
|
||||
return doc.status
|
||||
|
||||
|
||||
def auto_repeat_doctype_query(doctype, txt, searchfield, start, page_len, filters):
|
||||
return frappe.db.sql("""select parent from `tabDocField`
|
||||
where fieldname = 'auto_repeat'
|
||||
and parent like %(txt)s
|
||||
order by
|
||||
if(locate(%(_txt)s, parent), locate(%(_txt)s, parent), 99999),
|
||||
parent
|
||||
limit %(start)s, %(page_len)s""".format(**{
|
||||
'key': searchfield,
|
||||
}), {
|
||||
'txt': "%%%s%%" % txt,
|
||||
'_txt': txt.replace("%", ""),
|
||||
'start': start,
|
||||
'page_len': page_len
|
||||
})
|
||||
16
frappe/desk/doctype/auto_repeat/auto_repeat_list.js
Normal file
16
frappe/desk/doctype/auto_repeat/auto_repeat_list.js
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
frappe.listview_settings['Auto Repeat'] = {
|
||||
add_fields: ["next_schedule_date"],
|
||||
get_indicator: function(doc) {
|
||||
if(doc.disabled) {
|
||||
return [__("Disabled"), "red"];
|
||||
} else if(doc.next_schedule_date >= frappe.datetime.get_today() && doc.status != 'Stopped') {
|
||||
return [__("Active"), "green"];
|
||||
} else if(doc.docstatus === 0) {
|
||||
return [__("Draft"), "red", "docstatus,=,0"];
|
||||
} else if(doc.status === 'Stopped') {
|
||||
return [__("Stopped"), "red"];
|
||||
} else {
|
||||
return [__("Expired"), "darkgrey"];
|
||||
}
|
||||
}
|
||||
};
|
||||
98
frappe/desk/doctype/auto_repeat/test_auto_repeat.py
Normal file
98
frappe/desk/doctype/auto_repeat/test_auto_repeat.py
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from erpnext.accounts.report.financial_statements import get_months
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
|
||||
from frappe.desk.doctype.auto_repeat.auto_repeat import make_auto_repeat_entry, disable_auto_repeat
|
||||
from frappe.utils import today, add_days, getdate
|
||||
|
||||
|
||||
def add_custom_fields():
|
||||
df = dict(
|
||||
fieldname='auto_repeat', label='Auto Repeat', fieldtype='Link', insert_after='sender',
|
||||
options='Auto Repeat')
|
||||
create_custom_field('ToDo', df)
|
||||
|
||||
|
||||
class TestAutoRepeat(unittest.TestCase):
|
||||
def setUp(self):
|
||||
if not frappe.db.sql('select name from `tabCustom Field` where name="auto_repeat"'):
|
||||
add_custom_fields()
|
||||
|
||||
def test_daily_auto_repeat(self):
|
||||
todo = frappe.get_doc(
|
||||
dict(doctype='ToDo', description='test recurring todo', assigned_by='Administrator')).insert()
|
||||
|
||||
doc = make_auto_repeat(reference_document=todo.name)
|
||||
self.assertEqual(doc.next_schedule_date, today())
|
||||
make_auto_repeat_entry()
|
||||
frappe.db.commit()
|
||||
|
||||
todo = frappe.get_doc(doc.reference_doctype, doc.reference_document)
|
||||
self.assertEqual(todo.auto_repeat, doc.name)
|
||||
|
||||
new_todo = frappe.db.get_value('ToDo',
|
||||
{'auto_repeat': doc.name, 'name': ('!=', todo.name)}, 'name')
|
||||
|
||||
new_todo = frappe.get_doc('ToDo', new_todo)
|
||||
|
||||
self.assertEqual(todo.get('description'), new_todo.get('description'))
|
||||
|
||||
def test_monthly_auto_repeat(self):
|
||||
current_fiscal_year = get_fiscal_year(today(), as_dict=True)
|
||||
start_date = current_fiscal_year.year_start_date
|
||||
end_date = current_fiscal_year.year_end_date
|
||||
|
||||
todo = frappe.get_doc(
|
||||
dict(doctype='ToDo', description='test recurring todo', assigned_by='Administrator')).insert()
|
||||
|
||||
self.monthly_auto_repeat('ToDo', todo.name, start_date, end_date)
|
||||
|
||||
def monthly_auto_repeat(self, doctype, docname, start_date, end_date):
|
||||
doc = make_auto_repeat(
|
||||
reference_doctype=doctype, frequency='Monthly', reference_document=docname, start_date=start_date,
|
||||
end_date=end_date)
|
||||
|
||||
disable_auto_repeat(doc)
|
||||
# doc.disabled = 1
|
||||
# doc.save()
|
||||
# frappe.db.commit()
|
||||
|
||||
make_auto_repeat_entry()
|
||||
docnames = frappe.get_all(doc.reference_doctype, {'auto_repeat': doc.name})
|
||||
self.assertEqual(len(docnames), 1)
|
||||
|
||||
doc = frappe.get_doc('Auto Repeat', doc.name)
|
||||
doc.db_set('disabled', 0)
|
||||
# doc.save()
|
||||
|
||||
months = get_months(getdate(start_date), getdate(today()))
|
||||
make_auto_repeat_entry()
|
||||
|
||||
docnames = frappe.get_all(doc.reference_doctype, {'auto_repeat': doc.name})
|
||||
self.assertEqual(len(docnames), months)
|
||||
|
||||
|
||||
def make_auto_repeat(**args):
|
||||
args = frappe._dict(args)
|
||||
doc = frappe.get_doc({
|
||||
'doctype': 'Auto Repeat',
|
||||
'reference_doctype': args.reference_doctype or 'ToDo',
|
||||
'reference_document': args.reference_document or \
|
||||
frappe.db.get_value('ToDo', {'docstatus': 1}, 'name'),
|
||||
'frequency': args.frequency or 'Daily',
|
||||
'start_date': args.start_date or add_days(today(), -1),
|
||||
'end_date': args.end_date or add_days(today(), 1),
|
||||
'submit_on_creation': args.submit_on_creation or 0
|
||||
}).insert(ignore_permissions=True)
|
||||
|
||||
if not args.do_not_submit:
|
||||
doc.submit()
|
||||
|
||||
return doc
|
||||
|
|
@ -141,7 +141,8 @@ scheduler_events = {
|
|||
'frappe.model.utils.user_settings.sync_user_settings',
|
||||
"frappe.utils.error.collect_error_snapshots",
|
||||
"frappe.desk.page.backups.backups.delete_downloadable_backups",
|
||||
"frappe.limits.update_space_usage"
|
||||
"frappe.limits.update_space_usage",
|
||||
"frappe.desk.doctype.auto_repeat.auto_repeat.make_auto_repeat_entry",
|
||||
],
|
||||
"daily": [
|
||||
"frappe.email.queue.clear_outbox",
|
||||
|
|
|
|||
11
frappe/templates/emails/recurring_document_failed.html
Normal file
11
frappe/templates/emails/recurring_document_failed.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<h2>{{_("Recurring")}} {{ type }} {{ _("Failed")}}</h2>
|
||||
|
||||
<p>{{_("An error occured while creating recurring")}} {{ type }} <b>{{ name }}</b> {{_("for")}} <b>{{ party }}</b>.</p>
|
||||
<p>{{_("This could be because of some invalid Email Addresses in the")}} {{ type }}.</p>
|
||||
<p>{{_("To stop sending repetitive error notifications from the system, we have checked Disabled field in the Auto Repeat document")}} {{ auto_repeat}} {{_("for the")}} {{ type }} {{ name }}.</p>
|
||||
<p><b>{{_("Please correct the")}} {{ type }} {{_('and uncheck Disabled in the Auto Repeat document')}} {{ auto_repeat }} {{_("for automatic creating of the recurring document to continue.")}}</b></p>
|
||||
<hr>
|
||||
<p><b>{{_("It is necessary to take this action today itself for the above mentioned recurring")}} {{ type }}
|
||||
{{_('to be generated. If delayed, you will have to manually change the "Repeat on Day of Month" field
|
||||
of this')}} {{ type }} {{_("for generating the recurring")}} {{ type }} {{_("in the Auto Repeat document")}} {{ auto_repeat }}.</b></p>
|
||||
<p>[{{_("This email is autogenerated")}}]</p>
|
||||
Loading…
Add table
Reference in a new issue