Shift Management (#13667)

* [fix] #13634

* review_changes

* rename function

* rename function
This commit is contained in:
Pawan Mehta 2018-04-18 10:59:59 +05:30 committed by Nabin Hait
parent efff6e53de
commit 2215d4c593
7 changed files with 270 additions and 46 deletions

View File

@ -263,10 +263,6 @@ def get_data():
{
"type": "doctype",
"name": "Shift Assignment",
},
{
"type": "doctype",
"name": "Shift Assignment Tool",
}
]
},

View File

@ -1,7 +1,7 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_import": 1,
"allow_rename": 0,
"autoname": "SH.#####",
"beta": 0,
@ -26,7 +26,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Employee",
"length": 0,
@ -183,7 +183,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Company",
"length": 0,
@ -215,7 +215,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Date",
"length": 0,
@ -233,6 +233,38 @@
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "shift_request",
"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": "Shift Request",
"length": 0,
"no_copy": 0,
"options": "Shift Request",
"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,
@ -275,7 +307,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-04-14 15:42:12.617715",
"modified": "2018-04-17 14:50:09.125737",
"modified_by": "Administrator",
"module": "HR",
"name": "Shift Assignment",

View File

@ -4,7 +4,77 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import cint, cstr, date_diff, flt, formatdate, getdate
class OverlapError(frappe.ValidationError): pass
class ShiftAssignment(Document):
pass
def validate(self):
self.validate_overlapping_dates();
def validate_overlapping_dates(self):
if not self.name:
self.name = "New Shift Assignment"
d = frappe.db.sql("""
select
name, shift_type, date
from `tabShift Assignment`
where employee = %(employee)s and docstatus < 2
and date = %(date)s
and name != %(name)s""", {
"employee": self.employee,
"shift_type": self.shift_type,
"date": self.date,
"name": self.name
}, as_dict = 1)
for date_overlap in d:
if date_overlap['name']:
self.throw_overlap_error(date_overlap)
def throw_overlap_error(self, d):
msg = _("Employee {0} has already applied for {1} on {2} : ").format(self.employee,
d['shift_type'], formatdate(d['date'])) \
+ """ <b><a href="#Form/Shift Request/{0}">{0}</a></b>""".format(d["name"])
frappe.throw(msg, OverlapError)
@frappe.whitelist()
def get_events(start, end, filters=None):
events = []
employee = frappe.db.get_value("Employee", {"user_id": frappe.session.user}, ["name", "company"],
as_dict=True)
if employee:
employee, company = employee.name, employee.company
else:
employee=''
company=frappe.db.get_value("Global Defaults", None, "default_company")
from frappe.desk.reportview import get_filters_cond
conditions = get_filters_cond("Shift Assignment", filters, [])
add_assignments(events, start, end, conditions=conditions)
return events
def add_assignments(events, start, end, conditions=None):
query = """select name, date, employee_name,
employee, docstatus
from `tabShift Assignment` where
date <= %(date)s
and docstatus < 2"""
if conditions:
query += conditions
for d in frappe.db.sql(query, {"date":start, "date":end}, as_dict=True):
e = {
"name": d.name,
"doctype": "Shift Assignment",
"date": d.date,
"title": cstr(d.employee_name) + \
cstr(d.shift_type),
"docstatus": d.docstatus
}
if e not in events:
events.append(e)

View File

@ -0,0 +1,19 @@
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.views.calendar["Shift Assignment"] = {
field_map: {
"start": "date",
"end": "date",
"id": "name",
"docstatus": 1
},
options: {
header: {
left: 'prev,next today',
center: 'title',
right: 'month'
}
},
get_events_method: "erpnext.hr.doctype.shift_assignment.shift_assignment.get_events"
}

View File

@ -1,7 +1,7 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_import": 1,
"allow_rename": 0,
"autoname": "SREQ.#####",
"beta": 0,
@ -13,6 +13,38 @@
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "shift_type",
"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": "Shift Type",
"length": 0,
"no_copy": 0,
"options": "Shift Type",
"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,
@ -77,6 +109,36 @@
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_4",
"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,
@ -109,38 +171,6 @@
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "shift_type",
"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": "Shift Type",
"length": 0,
"no_copy": 0,
"options": "Shift Type",
"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,
@ -245,7 +275,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-04-14 15:40:39.590051",
"modified": "2018-04-16 11:01:25.902995",
"modified_by": "Administrator",
"module": "HR",
"name": "Shift Request",

View File

@ -4,7 +4,84 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import formatdate, getdate
class OverlapError(frappe.ValidationError): pass
class ShiftRequest(Document):
pass
def validate(self):
self.validate_dates();
self.validate_shift_request_overlap_dates();
def on_submit(self):
date_list = self.get_working_days(self.from_date, self.to_date)
for date in date_list:
assignment_doc = frappe.new_doc("Shift Assignment")
assignment_doc.company = self.company
assignment_doc.shift_type = self.shift_type
assignment_doc.employee = self.employee
assignment_doc.date = date
assignment_doc.shift_request = self.name
assignment_doc.insert()
assignment_doc.submit()
def validate_dates(self):
if self.from_date and self.to_date and (getdate(self.to_date) < getdate(self.from_date)):
frappe.throw(_("To date cannot be before from date"))
def validate_shift_request_overlap_dates(self):
if not self.name:
self.name = "New Shift Request"
d = frappe.db.sql("""
select
name, shift_type, from_date, to_date
from `tabShift Request`
where employee = %(employee)s and docstatus < 2
and ((%(from_date)s >= from_date
and %(from_date)s <= to_date) or
( %(to_date)s >= from_date
and %(to_date)s <= to_date ))
and name != %(name)s""", {
"employee": self.employee,
"shift_type": self.shift_type,
"from_date": self.from_date,
"to_date": self.to_date,
"name": self.name
}, as_dict=1)
for date_overlap in d:
if date_overlap ['name']:
self.throw_overlap_error(date_overlap)
def throw_overlap_error(self, d):
msg = _("Employee {0} has already applied for {1} between {2} and {3} : ").format(self.employee,
d['shift_type'], formatdate(d['from_date']), formatdate(d['to_date'])) \
+ """ <b><a href="#Form/Shift Request/{0}">{0}</a></b>""".format(d["name"])
frappe.throw(msg, OverlapError)
def get_working_days(self, start_date, end_date):
start_date, end_date = getdate(start_date), getdate(end_date)
from datetime import timedelta
date_list = []
employee_holiday_list = []
employee_holidays = frappe.db.sql("""select holiday_date from `tabHoliday`
where parent in (select holiday_list from `tabEmployee`
where name = %s)""",self.employee,as_dict=1)
for d in employee_holidays:
employee_holiday_list.append(d.holiday_date)
reference_date = start_date
while reference_date <= end_date:
if reference_date not in employee_holiday_list:
date_list.append(reference_date)
reference_date += timedelta(days=1)
return date_list

View File

@ -7,4 +7,4 @@ import frappe
from frappe.model.document import Document
class ShiftType(Document):
pass
pass