Daily work summary refactor (#12944)
* added daily work summary setting doctype and code to support feature this will allow multiple setting for daily work summary * added daily work summary setting user doctype * made changes in daily work summary code * [minor] entry change in hr config file * deleted previous daily work summary settings (and its company) doctype * removed unwanted permission check * toggled read_only option for enabled field * removed print statements * add patch for the changes * doc changes * [minor] indentation fix * fixed tests * indentation fixes * codacy issue fix * formatting fixes * renamed doctype Renamed Daily Work Summary Setting to Daily Work Summary Group and did related code and doc changes * fixed typo * updated doc * codacy issue fix * [minor] renamed doctype name in json * Renamed old doctype * fixed indentation * codacy fix * indentation fix * renamed doctype * handled patch exception * fixed exception * Update daily_work_summary_group.py * rename patch file removed abbreviation in file name * handled exception in patch code * removed Unnecessary pass statement * [minor] indentation fix
This commit is contained in:
committed by
Rushabh Mehta
parent
b8c088edb7
commit
d3069fee4d
@@ -244,8 +244,8 @@ def get_data():
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Daily Work Summary Settings"
|
"name": "Daily Work Summary Group"
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,15 +1,24 @@
|
|||||||
# Daily Work Summary
|
# Daily Work Summary
|
||||||
|
|
||||||
Daily Work Summary is way to get a automated way to get a summary of work done by all employees in a company. Once you set it up, each active Employee of the Company gets an email asking them what did they work on during the day.
|
Daily Work Summary is way to get a automated way to get a summary of work done by users.
|
||||||
|
|
||||||
|
Replies of all users who choose to respond is collected and sent as a summary at midnight. Emails are only sent based on the Holiday List selected for the group
|
||||||
|
|
||||||
|
**Note:**
|
||||||
|
> You must have one active incoming email account setup for this to work.
|
||||||
|
|
||||||
Replies of all employees who choose to respond is collected and sent as a summary at midnight. Emails are only sent based on the Holiday List setup in the Company or Employee master.
|
|
||||||
|
|
||||||
*Note:* You must have one active incoming email account setup for this to work.
|
|
||||||
|
|
||||||
### How to Use
|
### How to Use
|
||||||
|
|
||||||
Go to "Daily Work Summary Settings" via HR module or search bar and set the company for which you want to activate this feature.
|
Go to "Daily Work Summary Group" via HR module or search bar and set the users for whom you want to send the reminder.
|
||||||
|
|
||||||
You can also choose to Customize the Message you send to your employees:
|
You can set multiple groups with different set of _users_ from your user list with different _time to send emails_ and with separate _holiday list_ for each.
|
||||||
|
|
||||||
|
You can also choose to customize the _Message_ you send to users.
|
||||||
|
|
||||||
|
**Note:**
|
||||||
|
>1. If no holiday list is selected then the email will be sent every day.
|
||||||
|
>2. Name of a "Daily Work Summary Group" will be sent as the title for daily summary email.
|
||||||
|
>3. Mail will not be sent to the users of a disabled Daily Work Summary Group.
|
||||||
|
|
||||||
<img class="screenshot" alt="Department" src="{{docs_base_url}}/assets/img/human-resources/department.png">
|
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ doc_events = {
|
|||||||
scheduler_events = {
|
scheduler_events = {
|
||||||
"hourly": [
|
"hourly": [
|
||||||
"erpnext.accounts.doctype.subscription.subscription.make_subscription_entry",
|
"erpnext.accounts.doctype.subscription.subscription.make_subscription_entry",
|
||||||
'erpnext.hr.doctype.daily_work_summary_settings.daily_work_summary_settings.trigger_emails'
|
'erpnext.hr.doctype.daily_work_summary_group.daily_work_summary_group.trigger_emails'
|
||||||
],
|
],
|
||||||
"daily": [
|
"daily": [
|
||||||
"erpnext.stock.reorder_item.reorder_item",
|
"erpnext.stock.reorder_item.reorder_item",
|
||||||
@@ -230,7 +230,7 @@ scheduler_events = {
|
|||||||
"erpnext.hr.doctype.employee.employee.send_birthday_reminders",
|
"erpnext.hr.doctype.employee.employee.send_birthday_reminders",
|
||||||
"erpnext.projects.doctype.task.task.set_tasks_as_overdue",
|
"erpnext.projects.doctype.task.task.set_tasks_as_overdue",
|
||||||
"erpnext.assets.doctype.asset.depreciation.post_depreciation_entries",
|
"erpnext.assets.doctype.asset.depreciation.post_depreciation_entries",
|
||||||
"erpnext.hr.doctype.daily_work_summary_settings.daily_work_summary_settings.send_summary",
|
"erpnext.hr.doctype.daily_work_summary_group.daily_work_summary_group.send_summary",
|
||||||
"erpnext.stock.doctype.serial_no.serial_no.update_maintenance_status",
|
"erpnext.stock.doctype.serial_no.serial_no.update_maintenance_status",
|
||||||
"erpnext.buying.doctype.supplier_scorecard.supplier_scorecard.refresh_scorecards",
|
"erpnext.buying.doctype.supplier_scorecard.supplier_scorecard.refresh_scorecards",
|
||||||
"erpnext.setup.doctype.company.company.cache_companies_monthly_sales_history",
|
"erpnext.setup.doctype.company.company.cache_companies_monthly_sales_history",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 0,
|
"allow_rename": 0,
|
||||||
"beta": 0,
|
"beta": 0,
|
||||||
@@ -12,22 +13,24 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "company",
|
"fieldname": "daily_work_summary_group",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 1,
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Company",
|
"label": "Daily Work Summary Group",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "Company",
|
"options": "Daily Work Summary Group",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
@@ -41,6 +44,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -52,6 +56,7 @@
|
|||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Status",
|
"label": "Status",
|
||||||
@@ -71,6 +76,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -81,6 +87,7 @@
|
|||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Email Sent To",
|
"label": "Email Sent To",
|
||||||
@@ -99,17 +106,17 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"has_web_view": 0,
|
||||||
"hide_heading": 0,
|
"hide_heading": 0,
|
||||||
"hide_toolbar": 0,
|
"hide_toolbar": 0,
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"image_view": 0,
|
"image_view": 0,
|
||||||
"in_create": 1,
|
"in_create": 1,
|
||||||
"in_dialog": 0,
|
|
||||||
"is_submittable": 0,
|
"is_submittable": 0,
|
||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-11-21 01:05:55.258867",
|
"modified": "2018-02-16 11:02:06.727749",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Daily Work Summary",
|
"name": "Daily Work Summary",
|
||||||
@@ -126,7 +133,6 @@
|
|||||||
"export": 0,
|
"export": 0,
|
||||||
"if_owner": 0,
|
"if_owner": 0,
|
||||||
"import": 0,
|
"import": 0,
|
||||||
"is_custom": 0,
|
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print": 0,
|
"print": 0,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
@@ -147,7 +153,6 @@
|
|||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
"if_owner": 0,
|
||||||
"import": 0,
|
"import": 0,
|
||||||
"is_custom": 0,
|
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
@@ -162,7 +167,9 @@
|
|||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
"read_only_onload": 0,
|
"read_only_onload": 0,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 0,
|
||||||
"track_seen": 0
|
"track_seen": 0
|
||||||
}
|
}
|
||||||
@@ -11,52 +11,66 @@ from erpnext.hr.doctype.employee.employee import is_holiday
|
|||||||
from frappe.utils import global_date_format
|
from frappe.utils import global_date_format
|
||||||
from markdown2 import markdown
|
from markdown2 import markdown
|
||||||
|
|
||||||
|
|
||||||
class DailyWorkSummary(Document):
|
class DailyWorkSummary(Document):
|
||||||
def send_mails(self, settings, emails):
|
def send_mails(self, dws_group, emails):
|
||||||
'''Send emails to get daily work summary to all employees'''
|
'''Send emails to get daily work summary to all users \
|
||||||
|
in selected daily work summary group'''
|
||||||
incoming_email_account = frappe.db.get_value('Email Account',
|
incoming_email_account = frappe.db.get_value('Email Account',
|
||||||
dict(enable_incoming=1, default_incoming=1), 'email_id')
|
dict(enable_incoming=1, default_incoming=1),
|
||||||
|
'email_id')
|
||||||
|
|
||||||
self.db_set('email_sent_to', '\n'.join(emails))
|
self.db_set('email_sent_to', '\n'.join(emails))
|
||||||
frappe.sendmail(recipients = emails, message = settings.message,
|
frappe.sendmail(recipients=emails,
|
||||||
subject = settings.subject, reference_doctype=self.doctype,
|
message=dws_group.message,
|
||||||
reference_name=self.name, reply_to = incoming_email_account)
|
subject=dws_group.subject,
|
||||||
|
reference_doctype=self.doctype,
|
||||||
|
reference_name=self.name,
|
||||||
|
reply_to=incoming_email_account)
|
||||||
|
|
||||||
def send_summary(self):
|
def send_summary(self):
|
||||||
'''Send summary of all replies. Called at midnight'''
|
'''Send summary of all replies. Called at midnight'''
|
||||||
args = self.get_message_details()
|
args = self.get_message_details()
|
||||||
|
emails = get_user_emails_from_group(self.daily_work_summary_group)
|
||||||
frappe.sendmail(recipients = get_employee_emails(self.company, False),
|
frappe.sendmail(recipients=emails,
|
||||||
template='daily_work_summary',
|
template='daily_work_summary',
|
||||||
args=args,
|
args=args,
|
||||||
subject = _('Daily Work Summary for {0}').format(self.company),
|
subject=_(self.daily_work_summary_group),
|
||||||
reference_doctype=self.doctype, reference_name=self.name)
|
reference_doctype=self.doctype,
|
||||||
|
reference_name=self.name)
|
||||||
|
|
||||||
self.db_set('status', 'Sent')
|
self.db_set('status', 'Sent')
|
||||||
|
|
||||||
def get_message_details(self):
|
def get_message_details(self):
|
||||||
'''Return args for template'''
|
'''Return args for template'''
|
||||||
settings = frappe.get_doc('Daily Work Summary Settings')
|
dws_group = frappe.get_doc('Daily Work Summary Group',
|
||||||
|
self.daily_work_summary_group)
|
||||||
|
|
||||||
replies = frappe.get_all('Communication', fields=['content', 'text_content', 'sender'],
|
replies = frappe.get_all('Communication',
|
||||||
filters=dict(reference_doctype=self.doctype, reference_name=self.name,
|
fields=['content', 'text_content', 'sender'],
|
||||||
communication_type='Communication', sent_or_received='Received'),
|
filters=dict(reference_doctype=self.doctype,
|
||||||
|
reference_name=self.name,
|
||||||
|
communication_type='Communication',
|
||||||
|
sent_or_received='Received'),
|
||||||
order_by='creation asc')
|
order_by='creation asc')
|
||||||
|
|
||||||
did_not_reply = self.email_sent_to.split()
|
did_not_reply = self.email_sent_to.split()
|
||||||
|
|
||||||
for d in replies:
|
for d in replies:
|
||||||
emp = frappe.db.get_values("Employee", {"user_id": d.sender},
|
user = frappe.db.get_values("User",
|
||||||
["employee_name", "image"], as_dict=True)
|
{"email": d.sender},
|
||||||
|
["full_name", "user_image"],
|
||||||
|
as_dict=True)
|
||||||
|
|
||||||
d.sender_name = emp[0].employee_name if emp else d.sender
|
d.sender_name = user[0].full_name if user else d.sender
|
||||||
d.image = emp[0].image if emp and emp[0].image else None
|
d.image = user[0].image if user and user[0].image else None
|
||||||
|
|
||||||
original_image = d.image
|
original_image = d.image
|
||||||
# make thumbnail image
|
# make thumbnail image
|
||||||
try:
|
try:
|
||||||
if original_image:
|
if original_image:
|
||||||
file_name = frappe.get_list('File', {'file_url': original_image})
|
file_name = frappe.get_list('File',
|
||||||
|
{'file_url': original_image})
|
||||||
|
|
||||||
if file_name:
|
if file_name:
|
||||||
file_name = file_name[0].name
|
file_name = file_name[0].name
|
||||||
@@ -74,34 +88,27 @@ class DailyWorkSummary(Document):
|
|||||||
if d.sender in did_not_reply:
|
if d.sender in did_not_reply:
|
||||||
did_not_reply.remove(d.sender)
|
did_not_reply.remove(d.sender)
|
||||||
if d.text_content:
|
if d.text_content:
|
||||||
d.content = markdown(EmailReplyParser.parse_reply(d.text_content))
|
d.content = markdown(
|
||||||
|
EmailReplyParser.parse_reply(d.text_content)
|
||||||
|
)
|
||||||
|
|
||||||
|
did_not_reply = [(frappe.db.get_value("User", {"email": email}, "full_name") or email)
|
||||||
did_not_reply = [(frappe.db.get_value("Employee", {"user_id": email}, "employee_name") or email)
|
|
||||||
for email in did_not_reply]
|
for email in did_not_reply]
|
||||||
|
|
||||||
return dict(replies=replies,
|
return dict(replies=replies,
|
||||||
original_message=settings.message,
|
original_message=dws_group.message,
|
||||||
title=_('Daily Work Summary for {0}'.format(global_date_format(self.creation))),
|
title=_('Work Summary for {0}'.format(
|
||||||
|
global_date_format(self.creation)
|
||||||
|
)),
|
||||||
did_not_reply=', '.join(did_not_reply) or '',
|
did_not_reply=', '.join(did_not_reply) or '',
|
||||||
did_not_reply_title=_('No replies from'))
|
did_not_reply_title=_('No replies from'))
|
||||||
|
|
||||||
|
|
||||||
def get_employee_emails(company, only_working=True):
|
def get_user_emails_from_group(group):
|
||||||
'''Returns list of Employee user ids for the given company who are working today
|
'''Returns list of email of users from the given group
|
||||||
|
|
||||||
:param company: Company `name`'''
|
|
||||||
employee_list = frappe.get_all('Employee', fields=['name', 'user_id'],
|
|
||||||
filters={'status': 'Active', 'company': company})
|
|
||||||
|
|
||||||
out = []
|
|
||||||
for e in employee_list:
|
|
||||||
if e.user_id:
|
|
||||||
if only_working and is_holiday(e.name):
|
|
||||||
# don't add if holiday
|
|
||||||
continue
|
|
||||||
out.append(e.user_id)
|
|
||||||
|
|
||||||
return out
|
|
||||||
|
|
||||||
|
:param group: Daily Work Summary Group `name`'''
|
||||||
|
group_doc = frappe.get_doc('Daily Work Summary Group', group)
|
||||||
|
emails = [d.email for d in group_doc.users]
|
||||||
|
|
||||||
|
return emails
|
||||||
|
|||||||
@@ -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: Daily Work Summary", function (assert) {
|
||||||
|
let done = assert.async();
|
||||||
|
|
||||||
|
// number of asserts
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
frappe.run_serially([
|
||||||
|
// insert a new Daily Work Summary
|
||||||
|
() => frappe.tests.make('Daily Work Summary', [
|
||||||
|
// values to be set
|
||||||
|
{ key: 'value' }
|
||||||
|
]),
|
||||||
|
() => {
|
||||||
|
assert.equal(cur_frm.doc.key, 'value');
|
||||||
|
},
|
||||||
|
() => done()
|
||||||
|
]);
|
||||||
|
|
||||||
|
});
|
||||||
@@ -13,30 +13,31 @@ import frappe.utils
|
|||||||
class TestDailyWorkSummary(unittest.TestCase):
|
class TestDailyWorkSummary(unittest.TestCase):
|
||||||
def test_email_trigger(self):
|
def test_email_trigger(self):
|
||||||
self.setup_and_prepare_test()
|
self.setup_and_prepare_test()
|
||||||
for d in self.employees:
|
for d in self.users:
|
||||||
# check that email is sent to this employee
|
# check that email is sent to users
|
||||||
self.assertTrue(d.user_id in [d.recipient for d in self.emails
|
self.assertTrue(d.email in [d.recipient for d in self.emails
|
||||||
if self.settings.subject in d.message])
|
if self.groups.subject in d.message])
|
||||||
|
|
||||||
def test_email_trigger_failed(self):
|
def test_email_trigger_failed(self):
|
||||||
hour = '00'
|
hour = '00:00'
|
||||||
if frappe.utils.nowtime().split(':')[0] == '00':
|
if frappe.utils.nowtime().split(':')[0] == '00':
|
||||||
hour = '01'
|
hour = '01:00'
|
||||||
|
|
||||||
self.setup_and_prepare_test(hour)
|
self.setup_and_prepare_test(hour)
|
||||||
|
|
||||||
for d in self.employees:
|
for d in self.users:
|
||||||
# check that email is sent to this employee
|
# check that email is not sent to users
|
||||||
self.assertFalse(d.user_id in [d.recipient for d in self.emails
|
self.assertFalse(d.email in [d.recipient for d in self.emails
|
||||||
if self.settings.subject in d.message])
|
if self.groups.subject in d.message])
|
||||||
|
|
||||||
def test_incoming(self):
|
def test_incoming(self):
|
||||||
# get test mail with message-id as in-reply-to
|
# get test mail with message-id as in-reply-to
|
||||||
self.setup_and_prepare_test()
|
self.setup_and_prepare_test()
|
||||||
|
|
||||||
with open(os.path.join(os.path.dirname(__file__), "test_data", "test-reply.raw"), "r") as f:
|
with open(os.path.join(os.path.dirname(__file__), "test_data", "test-reply.raw"), "r") as f:
|
||||||
test_mails = [f.read().replace('{{ sender }}', self.employees[-1].user_id)\
|
test_mails = [f.read().replace('{{ sender }}',
|
||||||
.replace('{{ message_id }}', self.emails[-1].message_id)]
|
self.users[-1].email).replace('{{ message_id }}',
|
||||||
|
self.emails[-1].message_id)]
|
||||||
|
|
||||||
# pull the mail
|
# pull the mail
|
||||||
email_account = frappe.get_doc("Email Account", "_Test Email Account 1")
|
email_account = frappe.get_doc("Email Account", "_Test Email Account 1")
|
||||||
@@ -55,30 +56,38 @@ class TestDailyWorkSummary(unittest.TestCase):
|
|||||||
frappe.db.sql('delete from `tabEmail Queue`')
|
frappe.db.sql('delete from `tabEmail Queue`')
|
||||||
frappe.db.sql('delete from `tabEmail Queue Recipient`')
|
frappe.db.sql('delete from `tabEmail Queue Recipient`')
|
||||||
frappe.db.sql('delete from `tabCommunication`')
|
frappe.db.sql('delete from `tabCommunication`')
|
||||||
|
frappe.db.sql('delete from `tabDaily Work Summary Group`')
|
||||||
|
|
||||||
self.setup_settings(hour)
|
self.users = frappe.get_all('User',
|
||||||
|
fields=['email'],
|
||||||
|
filters=dict(email=('!=', 'test@example.com')))
|
||||||
|
self.setup_groups(hour)
|
||||||
|
|
||||||
from erpnext.hr.doctype.daily_work_summary_settings.daily_work_summary_settings \
|
from erpnext.hr.doctype.daily_work_summary_group.daily_work_summary_group \
|
||||||
import trigger_emails
|
import trigger_emails
|
||||||
trigger_emails()
|
trigger_emails()
|
||||||
|
|
||||||
# check if emails are created
|
# check if emails are created
|
||||||
self.employees = frappe.get_all('Employee', fields = ['user_id'],
|
|
||||||
filters=dict(company='_Test Company', status='Active', user_id=('!=', 'test@example.com')))
|
|
||||||
|
|
||||||
self.emails = frappe.db.sql("""select r.recipient, q.message, q.message_id from `tabEmail Queue` as q, `tabEmail Queue Recipient` as r where q.name = r.parent""", as_dict=1)
|
self.emails = frappe.db.sql("""select r.recipient, q.message, q.message_id \
|
||||||
|
from `tabEmail Queue` as q, `tabEmail Queue Recipient` as r \
|
||||||
|
where q.name = r.parent""", as_dict=1)
|
||||||
|
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
def setup_settings(self, hour=None):
|
def setup_groups(self, hour=None):
|
||||||
# setup email to trigger at this our
|
# setup email to trigger at this hour
|
||||||
if not hour:
|
if not hour:
|
||||||
hour = frappe.utils.nowtime().split(':')[0]
|
hour = frappe.utils.nowtime().split(':')[0]
|
||||||
self.settings = frappe.get_doc('Daily Work Summary Settings')
|
hour = hour+':00'
|
||||||
self.settings.companies = []
|
|
||||||
|
|
||||||
self.settings.append('companies', dict(company='_Test Company',
|
groups = frappe.get_doc(dict(doctype="Daily Work Summary Group",
|
||||||
send_emails_at=hour + ':00'))
|
name="Daily Work Summary",
|
||||||
self.settings.test_subject = 'this is a subject for testing summary emails'
|
users=self.users,
|
||||||
self.settings.save()
|
send_emails_at=hour,
|
||||||
|
subject="this is a subject for testing summary emails",
|
||||||
|
message='this is a message for testing summary emails'))
|
||||||
|
groups.insert()
|
||||||
|
|
||||||
|
self.groups = groups
|
||||||
|
self.groups.save()
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('Daily Work Summary Group', {
|
||||||
|
refresh: function (frm) {
|
||||||
|
if (!frm.is_new()) {
|
||||||
|
frm.add_custom_button(__('Daily Work Summary'), function () {
|
||||||
|
frappe.set_route('List', 'Daily Work Summary');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -1,31 +1,35 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 0,
|
"allow_rename": 0,
|
||||||
|
"autoname": "Prompt",
|
||||||
"beta": 0,
|
"beta": 0,
|
||||||
"creation": "2016-11-08 04:55:08.231715",
|
"creation": "2018-02-12 15:06:18.767239",
|
||||||
"custom": 0,
|
"custom": 0,
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Document",
|
"document_type": "",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"description": "Emails will be sent to all Active Employees of the company at the given hour, if they do not have holiday. Summary of responses will be sent at midnight.",
|
"default": "1",
|
||||||
"fieldname": "select_companies",
|
"fieldname": "enabled",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Check",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Select Companies",
|
"label": "Enabled",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
@@ -41,22 +45,85 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "companies",
|
"fieldname": "select_users",
|
||||||
|
"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": "Select Users",
|
||||||
|
"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": "users",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Companies",
|
"label": "Users",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "Daily Work Summary Settings Company",
|
"options": "Daily Work Summary Group 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": 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": "send_emails_at",
|
||||||
|
"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": "Send Emails At",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "00:00\n01:00\n02:00\n03:00\n04:00\n05:00\n06:00\n07:00\n08:00\n09:00\n10:00\n11:00\n12:00\n13:00\n14:00\n15:00\n16:00\n17:00\n18:00\n19:00\n20:00\n21:00\n22:00\n23:00",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
@@ -70,19 +137,52 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "message_section",
|
"fieldname": "holiday_list",
|
||||||
|
"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": "Holiday List",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Holiday List",
|
||||||
|
"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": "mail_details",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Message",
|
"label": "Reminder",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
@@ -98,6 +198,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -109,6 +210,7 @@
|
|||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Subject",
|
"label": "Subject",
|
||||||
@@ -127,6 +229,7 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@@ -138,6 +241,7 @@
|
|||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Message",
|
"label": "Message",
|
||||||
@@ -156,20 +260,20 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"has_web_view": 0,
|
||||||
"hide_heading": 0,
|
"hide_heading": 0,
|
||||||
"hide_toolbar": 0,
|
"hide_toolbar": 0,
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"image_view": 0,
|
"image_view": 0,
|
||||||
"in_create": 0,
|
"in_create": 0,
|
||||||
"in_dialog": 0,
|
|
||||||
"is_submittable": 0,
|
"is_submittable": 0,
|
||||||
"issingle": 1,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-11-21 00:55:20.726328",
|
"modified": "2018-02-16 10:56:03.998495",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Daily Work Summary Settings",
|
"name": "Daily Work Summary Group",
|
||||||
"name_case": "",
|
"name_case": "",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
@@ -180,14 +284,13 @@
|
|||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 0,
|
"export": 1,
|
||||||
"if_owner": 0,
|
"if_owner": 0,
|
||||||
"import": 0,
|
"import": 0,
|
||||||
"is_custom": 0,
|
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 0,
|
"report": 1,
|
||||||
"role": "HR Manager",
|
"role": "HR Manager",
|
||||||
"set_user_permissions": 0,
|
"set_user_permissions": 0,
|
||||||
"share": 1,
|
"share": 1,
|
||||||
@@ -198,7 +301,9 @@
|
|||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"read_only_onload": 0,
|
"read_only_onload": 0,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 0,
|
||||||
"track_seen": 0
|
"track_seen": 0
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
# # -*- coding: utf-8 -*-
|
||||||
|
# # Copyright (c) 2015, 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
|
||||||
|
import frappe.utils
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
|
|
||||||
|
class DailyWorkSummaryGroup(Document):
|
||||||
|
def validate(self):
|
||||||
|
if self.users:
|
||||||
|
if not frappe.flags.in_test and not is_incoming_account_enabled():
|
||||||
|
frappe.throw(_('Please enable default incoming account before creating Daily Work Summary Group'))
|
||||||
|
|
||||||
|
|
||||||
|
def trigger_emails():
|
||||||
|
'''Send emails to Employees at the given hour asking
|
||||||
|
them what did they work on today'''
|
||||||
|
groups = frappe.get_all("Daily Work Summary Group")
|
||||||
|
for d in groups:
|
||||||
|
group_doc = frappe.get_doc("Daily Work Summary Group", d)
|
||||||
|
if (is_current_hour(group_doc.send_emails_at)
|
||||||
|
and not is_holiday_today(group_doc.holiday_list)
|
||||||
|
and group_doc.enabled):
|
||||||
|
emails = [d.email for d in group_doc.users]
|
||||||
|
# find emails relating to a company
|
||||||
|
if emails:
|
||||||
|
daily_work_summary = frappe.get_doc(
|
||||||
|
dict(doctype='Daily Work Summary', daily_work_summary_group=group_doc.name)
|
||||||
|
).insert()
|
||||||
|
daily_work_summary.send_mails(group_doc, emails)
|
||||||
|
|
||||||
|
|
||||||
|
def is_current_hour(hour):
|
||||||
|
return frappe.utils.nowtime().split(':')[0] == hour.split(':')[0]
|
||||||
|
|
||||||
|
|
||||||
|
def is_holiday_today(holiday_list):
|
||||||
|
date = frappe.utils.today()
|
||||||
|
if holiday_list:
|
||||||
|
return frappe.get_all('Holiday List',
|
||||||
|
dict(name=holiday_list, holiday_date=date)) and True or False
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def send_summary():
|
||||||
|
'''Send summary to everyone'''
|
||||||
|
for d in frappe.get_all('Daily Work Summary', dict(status='Open')):
|
||||||
|
daily_work_summary = frappe.get_doc('Daily Work Summary', d.name)
|
||||||
|
daily_work_summary.send_summary()
|
||||||
|
|
||||||
|
|
||||||
|
def is_incoming_account_enabled():
|
||||||
|
return frappe.db.get_value('Email Account', dict(enable_incoming=1, default_incoming=1))
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 0,
|
"allow_rename": 0,
|
||||||
"beta": 0,
|
"beta": 0,
|
||||||
"creation": "2016-11-08 05:44:02.502527",
|
"creation": "2018-02-12 14:57:38.332692",
|
||||||
"custom": 0,
|
"custom": 0,
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@@ -12,22 +13,24 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "company",
|
"fieldname": "user",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Company",
|
"label": "User",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "Company",
|
"options": "User",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
@@ -35,29 +38,30 @@
|
|||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 0,
|
||||||
"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,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "17:00",
|
"fieldname": "email",
|
||||||
"fieldname": "send_emails_at",
|
"fieldtype": "Read Only",
|
||||||
"fieldtype": "Select",
|
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 1,
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Send Emails At",
|
"label": "email",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "00:00\n01:00\n02:00\n03:00\n04:00\n05:00\n06:00\n07:00\n08:00\n09:00\n10:00\n11:00\n12:00\n13:00\n14:00\n15:00\n16:00\n17:00\n18:00\n19:00\n20:00\n21:00\n22:00\n23:00",
|
"options": "user.email",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
@@ -65,33 +69,35 @@
|
|||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"has_web_view": 0,
|
||||||
"hide_heading": 0,
|
"hide_heading": 0,
|
||||||
"hide_toolbar": 0,
|
"hide_toolbar": 0,
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"image_view": 0,
|
"image_view": 0,
|
||||||
"in_create": 0,
|
"in_create": 0,
|
||||||
"in_dialog": 0,
|
|
||||||
"is_submittable": 0,
|
"is_submittable": 0,
|
||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-11-08 05:46:09.198788",
|
"modified": "2018-02-12 15:57:01.332287",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Daily Work Summary Settings Company",
|
"name": "Daily Work Summary Group User",
|
||||||
"name_case": "",
|
"name_case": "",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"read_only_onload": 0,
|
"read_only_onload": 0,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1,
|
||||||
"track_seen": 0
|
"track_seen": 0
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class DailyWorkSummarySettingsCompany(Document):
|
class DailyWorkSummaryGroupUser(Document):
|
||||||
pass
|
pass
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
|
||||||
// For license information, please see license.txt
|
|
||||||
|
|
||||||
frappe.ui.form.on('Daily Work Summary Settings', {
|
|
||||||
refresh: function(frm) {
|
|
||||||
frm.add_custom_button(__('Daily Work Summary'), function() {
|
|
||||||
frappe.set_route('List', 'Daily Work Summary');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2015, 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
|
|
||||||
import frappe.utils
|
|
||||||
from frappe import _
|
|
||||||
from erpnext.hr.doctype.daily_work_summary.daily_work_summary import get_employee_emails
|
|
||||||
|
|
||||||
class DailyWorkSummarySettings(Document):
|
|
||||||
def validate(self):
|
|
||||||
if self.companies:
|
|
||||||
if not frappe.flags.in_test and not frappe.db.get_value('Email Account', dict(enable_incoming=1,
|
|
||||||
default_incoming=1)):
|
|
||||||
frappe.throw(_('There must be a default incoming Email Account enabled for this to work. Please setup a default incoming Email Account (POP/IMAP) and try again.'))
|
|
||||||
|
|
||||||
def trigger_emails():
|
|
||||||
'''Send emails to Employees of the enabled companies at the give hour asking
|
|
||||||
them what did they work on today'''
|
|
||||||
settings = frappe.get_doc('Daily Work Summary Settings')
|
|
||||||
for d in settings.companies:
|
|
||||||
# if current hour
|
|
||||||
if frappe.utils.nowtime().split(':')[0] == d.send_emails_at.split(':')[0]:
|
|
||||||
emails = get_employee_emails(d.company)
|
|
||||||
# find emails relating to a company
|
|
||||||
if emails:
|
|
||||||
daily_work_summary = frappe.get_doc(dict(doctype='Daily Work Summary',
|
|
||||||
company=d.company)).insert()
|
|
||||||
daily_work_summary.send_mails(settings, emails)
|
|
||||||
|
|
||||||
def send_summary():
|
|
||||||
'''Send summary to everyone'''
|
|
||||||
for d in frappe.get_all('Daily Work Summary', dict(status='Open')):
|
|
||||||
daily_work_summary = frappe.get_doc('Daily Work Summary', d.name)
|
|
||||||
daily_work_summary.send_summary()
|
|
||||||
@@ -8,9 +8,9 @@ frappe.pages['team-updates'].on_page_load = function(wrapper) {
|
|||||||
frappe.team_updates.make(page);
|
frappe.team_updates.make(page);
|
||||||
frappe.team_updates.run();
|
frappe.team_updates.run();
|
||||||
|
|
||||||
if(frappe.model.can_read('Daily Work Summary Settings')) {
|
if(frappe.model.can_read('Daily Work Summary Group')) {
|
||||||
page.add_menu_item(__('Daily Work Summary Settings'), function() {
|
page.add_menu_item(__('Daily Work Summary Group'), function() {
|
||||||
frappe.set_route('Form', 'Daily Work Summary Settings');
|
frappe.set_route('Form', 'Daily Work Summary Group');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -501,3 +501,4 @@ erpnext.patches.v10_0.set_b2c_limit
|
|||||||
erpnext.patches.v10_0.update_translatable_fields
|
erpnext.patches.v10_0.update_translatable_fields
|
||||||
erpnext.patches.v10_0.rename_offer_letter_to_job_offer
|
erpnext.patches.v10_0.rename_offer_letter_to_job_offer
|
||||||
execute:frappe.delete_doc('DocType', 'Production Planning Tool', ignore_missing=True)
|
execute:frappe.delete_doc('DocType', 'Production Planning Tool', ignore_missing=True)
|
||||||
|
erpnext.patches.v10_0.migrate_daily_work_summary_settings_to_daily_work_summary_group
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# Copyright (c) 2018, Frappe and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
# check if Daily Work Summary Settings Company table exists
|
||||||
|
try:
|
||||||
|
frappe.db.sql('DESC `tabDaily Work Summary Settings Company`')
|
||||||
|
except Exception:
|
||||||
|
return
|
||||||
|
|
||||||
|
# get the previously saved settings
|
||||||
|
previous_setting = get_previous_setting()
|
||||||
|
if previous_setting["companies"]:
|
||||||
|
for d in previous_setting["companies"]:
|
||||||
|
users = frappe.get_list("Employee", dict(
|
||||||
|
company=d.company, user_id=("!=", " ")), "user_id as user")
|
||||||
|
if(len(users)):
|
||||||
|
# create new group entry for each company entry
|
||||||
|
new_group = frappe.get_doc(dict(doctype="Daily Work Summary Group",
|
||||||
|
name="Daily Work Summary for " + d.company,
|
||||||
|
users=users,
|
||||||
|
send_emails_at=d.send_emails_at,
|
||||||
|
subject=previous_setting["subject"],
|
||||||
|
message=previous_setting["message"]))
|
||||||
|
new_group.insert(ignore_permissions=True)
|
||||||
|
new_group.save()
|
||||||
|
frappe.delete_doc("Daily Work Summary Settings")
|
||||||
|
frappe.delete_doc("Daily Work Summary Settings Company")
|
||||||
|
|
||||||
|
def get_setting_companies():
|
||||||
|
return frappe.db.sql("select * from `tabDaily Work Summary Settings Company`", as_dict=True)
|
||||||
|
|
||||||
|
|
||||||
|
def get_previous_setting():
|
||||||
|
obj = {}
|
||||||
|
setting_data = frappe.db.sql(
|
||||||
|
"select field, value from tabSingles where doctype='Daily Work Summary Settings'")
|
||||||
|
for field, value in setting_data:
|
||||||
|
obj[field] = value
|
||||||
|
obj["companies"] = get_setting_companies()
|
||||||
|
return obj
|
||||||
@@ -29,7 +29,7 @@ def check_setup_wizard_not_completed():
|
|||||||
|
|
||||||
def set_single_defaults():
|
def set_single_defaults():
|
||||||
for dt in ('Accounts Settings', 'Print Settings', 'HR Settings', 'Buying Settings',
|
for dt in ('Accounts Settings', 'Print Settings', 'HR Settings', 'Buying Settings',
|
||||||
'Selling Settings', 'Stock Settings', 'Daily Work Summary Settings'):
|
'Selling Settings', 'Stock Settings'):
|
||||||
default_values = frappe.db.sql("""select fieldname, `default` from `tabDocField`
|
default_values = frappe.db.sql("""select fieldname, `default` from `tabDocField`
|
||||||
where parent=%s""", dt)
|
where parent=%s""", dt)
|
||||||
if default_values:
|
if default_values:
|
||||||
|
|||||||
Reference in New Issue
Block a user