mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-23 15:09:20 +00:00
[fix] filters for calendars frappe/erpnext#9850 (#9870)
This commit is contained in:
committed by
Makarand Bauskar
parent
e012e24423
commit
660de515b5
@@ -69,27 +69,17 @@ def get_events(start, end, filters=None):
|
|||||||
:param end: End date-time.
|
:param end: End date-time.
|
||||||
:param filters: Filters (JSON).
|
:param filters: Filters (JSON).
|
||||||
"""
|
"""
|
||||||
condition = ''
|
|
||||||
values = {
|
|
||||||
"start_date": getdate(start),
|
|
||||||
"end_date": getdate(end)
|
|
||||||
}
|
|
||||||
|
|
||||||
if filters:
|
if filters:
|
||||||
if isinstance(filters, basestring):
|
filters = json.loads(filters)
|
||||||
filters = json.loads(filters)
|
else:
|
||||||
|
filters = []
|
||||||
|
|
||||||
if filters.get('holiday_list'):
|
if start:
|
||||||
condition = 'and hlist.name=%(holiday_list)s'
|
filters.append(['Holiday', 'holiday_date', '>', getdate(start)])
|
||||||
values['holiday_list'] = filters['holiday_list']
|
if end:
|
||||||
|
filters.append(['Holiday', 'holiday_date', '<', getdate(end)])
|
||||||
|
|
||||||
data = frappe.db.sql("""select hlist.name, h.holiday_date, h.description
|
return frappe.get_list('Holiday List',
|
||||||
from `tabHoliday List` hlist, tabHoliday h
|
fields=['name', '`tabHoliday`.holiday_date', '`tabHoliday`.description'],
|
||||||
where h.parent = hlist.name
|
filters = filters,
|
||||||
and h.holiday_date is not null
|
update={"allDay": 1})
|
||||||
and h.holiday_date >= %(start_date)s
|
|
||||||
and h.holiday_date <= %(end_date)s
|
|
||||||
{condition}""".format(condition=condition),
|
|
||||||
values, as_dict=True, update={"allDay": 1})
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|||||||
@@ -63,13 +63,13 @@ class LeaveApplication(Document):
|
|||||||
def validate_dates(self):
|
def validate_dates(self):
|
||||||
if self.from_date and self.to_date and (getdate(self.to_date) < getdate(self.from_date)):
|
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"))
|
frappe.throw(_("To date cannot be before from date"))
|
||||||
|
|
||||||
if self.half_day and self.half_day_date \
|
if self.half_day and self.half_day_date \
|
||||||
and (getdate(self.half_day_date) < getdate(self.from_date)
|
and (getdate(self.half_day_date) < getdate(self.from_date)
|
||||||
or getdate(self.half_day_date) > getdate(self.to_date)):
|
or getdate(self.half_day_date) > getdate(self.to_date)):
|
||||||
|
|
||||||
frappe.throw(_("Half Day Date should be between From Date and To Date"))
|
frappe.throw(_("Half Day Date should be between From Date and To Date"))
|
||||||
|
|
||||||
if not is_lwp(self.leave_type):
|
if not is_lwp(self.leave_type):
|
||||||
self.validate_dates_acorss_allocation()
|
self.validate_dates_acorss_allocation()
|
||||||
self.validate_back_dated_application()
|
self.validate_back_dated_application()
|
||||||
@@ -158,7 +158,7 @@ class LeaveApplication(Document):
|
|||||||
self.name = "New Leave Application"
|
self.name = "New Leave Application"
|
||||||
|
|
||||||
for d in frappe.db.sql("""
|
for d in frappe.db.sql("""
|
||||||
select
|
select
|
||||||
name, leave_type, posting_date, from_date, to_date, total_leave_days, half_day_date
|
name, leave_type, posting_date, from_date, to_date, total_leave_days, half_day_date
|
||||||
from `tabLeave Application`
|
from `tabLeave Application`
|
||||||
where employee = %(employee)s and docstatus < 2 and status in ("Open", "Approved")
|
where employee = %(employee)s and docstatus < 2 and status in ("Open", "Approved")
|
||||||
@@ -169,12 +169,12 @@ class LeaveApplication(Document):
|
|||||||
"to_date": self.to_date,
|
"to_date": self.to_date,
|
||||||
"name": self.name
|
"name": self.name
|
||||||
}, as_dict = 1):
|
}, as_dict = 1):
|
||||||
|
|
||||||
if cint(self.half_day)==1 and getdate(self.half_day_date) == getdate(d.half_day_date) and (
|
if cint(self.half_day)==1 and getdate(self.half_day_date) == getdate(d.half_day_date) and (
|
||||||
flt(self.total_leave_days)==0.5
|
flt(self.total_leave_days)==0.5
|
||||||
or getdate(self.from_date) == getdate(d.to_date)
|
or getdate(self.from_date) == getdate(d.to_date)
|
||||||
or getdate(self.to_date) == getdate(d.from_date)):
|
or getdate(self.to_date) == getdate(d.from_date)):
|
||||||
|
|
||||||
total_leaves_on_half_day = self.get_total_leaves_on_half_day()
|
total_leaves_on_half_day = self.get_total_leaves_on_half_day()
|
||||||
if total_leaves_on_half_day >= 1:
|
if total_leaves_on_half_day >= 1:
|
||||||
self.throw_overlap_error(d)
|
self.throw_overlap_error(d)
|
||||||
@@ -199,7 +199,7 @@ class LeaveApplication(Document):
|
|||||||
"half_day_date": self.half_day_date,
|
"half_day_date": self.half_day_date,
|
||||||
"name": self.name
|
"name": self.name
|
||||||
})[0][0]
|
})[0][0]
|
||||||
|
|
||||||
return leave_count_on_half_day_date * 0.5
|
return leave_count_on_half_day_date * 0.5
|
||||||
|
|
||||||
def validate_max_days(self):
|
def validate_max_days(self):
|
||||||
@@ -400,7 +400,7 @@ def is_lwp(leave_type):
|
|||||||
return lwp and cint(lwp[0][0]) or 0
|
return lwp and cint(lwp[0][0]) or 0
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_events(start, end):
|
def get_events(start, end, filters=None):
|
||||||
events = []
|
events = []
|
||||||
|
|
||||||
employee = frappe.db.get_value("Employee", {"user_id": frappe.session.user}, ["name", "company"],
|
employee = frappe.db.get_value("Employee", {"user_id": frappe.session.user}, ["name", "company"],
|
||||||
@@ -411,14 +411,14 @@ def get_events(start, end):
|
|||||||
employee=''
|
employee=''
|
||||||
company=frappe.db.get_value("Global Defaults", None, "default_company")
|
company=frappe.db.get_value("Global Defaults", None, "default_company")
|
||||||
|
|
||||||
from frappe.desk.reportview import build_match_conditions
|
from frappe.desk.reportview import get_filters_cond
|
||||||
match_conditions = build_match_conditions("Leave Application")
|
conditions = get_filters_cond("Leave Application")
|
||||||
|
|
||||||
# show department leaves for employee
|
# show department leaves for employee
|
||||||
if "Employee" in frappe.get_roles():
|
if "Employee" in frappe.get_roles():
|
||||||
add_department_leaves(events, start, end, employee, company)
|
add_department_leaves(events, start, end, employee, company)
|
||||||
|
|
||||||
add_leaves(events, start, end, match_conditions)
|
add_leaves(events, start, end, conditions)
|
||||||
|
|
||||||
add_block_dates(events, start, end, employee, company)
|
add_block_dates(events, start, end, employee, company)
|
||||||
add_holidays(events, start, end, employee, company)
|
add_holidays(events, start, end, employee, company)
|
||||||
|
|||||||
@@ -9,9 +9,8 @@ from frappe import _
|
|||||||
import json
|
import json
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from erpnext.controllers.queries import get_match_cond
|
from erpnext.controllers.queries import get_match_cond
|
||||||
from frappe.utils import flt, time_diff_in_hours, get_datetime, getdate, cint, get_datetime_str
|
from frappe.utils import flt, time_diff_in_hours, get_datetime, getdate, cint
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.model.mapper import get_mapped_doc
|
|
||||||
from erpnext.manufacturing.doctype.workstation.workstation import (check_if_within_operating_hours,
|
from erpnext.manufacturing.doctype.workstation.workstation import (check_if_within_operating_hours,
|
||||||
WorkstationHolidayError)
|
WorkstationHolidayError)
|
||||||
from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import get_mins_between_operations
|
from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import get_mins_between_operations
|
||||||
@@ -133,7 +132,7 @@ class Timesheet(Document):
|
|||||||
if data.name == timesheet.operation_id:
|
if data.name == timesheet.operation_id:
|
||||||
summary = self.get_actual_timesheet_summary(timesheet.operation_id)
|
summary = self.get_actual_timesheet_summary(timesheet.operation_id)
|
||||||
data.time_sheet = time_sheet
|
data.time_sheet = time_sheet
|
||||||
data.completed_qty = summary.completed_qty
|
data.completed_qty = summary.completed_qty
|
||||||
data.actual_operation_time = summary.mins
|
data.actual_operation_time = summary.mins
|
||||||
data.actual_start_time = summary.from_time
|
data.actual_start_time = summary.from_time
|
||||||
data.actual_end_time = summary.to_time
|
data.actual_end_time = summary.to_time
|
||||||
@@ -148,7 +147,7 @@ class Timesheet(Document):
|
|||||||
"""Returns 'Actual Operating Time'. """
|
"""Returns 'Actual Operating Time'. """
|
||||||
return frappe.db.sql("""select
|
return frappe.db.sql("""select
|
||||||
sum(tsd.hours*60) as mins, sum(tsd.completed_qty) as completed_qty, min(tsd.from_time) as from_time,
|
sum(tsd.hours*60) as mins, sum(tsd.completed_qty) as completed_qty, min(tsd.from_time) as from_time,
|
||||||
max(tsd.to_time) as to_time from `tabTimesheet Detail` as tsd, `tabTimesheet` as ts where
|
max(tsd.to_time) as to_time from `tabTimesheet Detail` as tsd, `tabTimesheet` as ts where
|
||||||
ts.production_order = %s and tsd.operation_id = %s and ts.docstatus=1 and ts.name = tsd.parent""",
|
ts.production_order = %s and tsd.operation_id = %s and ts.docstatus=1 and ts.name = tsd.parent""",
|
||||||
(self.production_order, operation_id), as_dict=1)[0]
|
(self.production_order, operation_id), as_dict=1)[0]
|
||||||
|
|
||||||
@@ -192,7 +191,7 @@ class Timesheet(Document):
|
|||||||
if fieldname == 'workstation':
|
if fieldname == 'workstation':
|
||||||
cond = "tsd.`{0}`".format(fieldname)
|
cond = "tsd.`{0}`".format(fieldname)
|
||||||
|
|
||||||
existing = frappe.db.sql("""select ts.name as name, tsd.from_time as from_time, tsd.to_time as to_time from
|
existing = frappe.db.sql("""select ts.name as name, tsd.from_time as from_time, tsd.to_time as to_time from
|
||||||
`tabTimesheet Detail` tsd, `tabTimesheet` ts where {0}=%(val)s and tsd.parent = ts.name and
|
`tabTimesheet Detail` tsd, `tabTimesheet` ts where {0}=%(val)s and tsd.parent = ts.name and
|
||||||
(
|
(
|
||||||
(%(from_time)s > tsd.from_time and %(from_time)s < tsd.to_time) or
|
(%(from_time)s > tsd.from_time and %(from_time)s < tsd.to_time) or
|
||||||
@@ -211,8 +210,8 @@ class Timesheet(Document):
|
|||||||
# check internal overlap
|
# check internal overlap
|
||||||
for time_log in self.time_logs:
|
for time_log in self.time_logs:
|
||||||
if (fieldname != 'workstation' or args.get(fieldname) == time_log.get(fieldname)) and \
|
if (fieldname != 'workstation' or args.get(fieldname) == time_log.get(fieldname)) and \
|
||||||
args.idx != time_log.idx and ((args.from_time > time_log.from_time and args.from_time < time_log.to_time) or
|
args.idx != time_log.idx and ((args.from_time > time_log.from_time and args.from_time < time_log.to_time) or
|
||||||
(args.to_time > time_log.from_time and args.to_time < time_log.to_time) or
|
(args.to_time > time_log.from_time and args.to_time < time_log.to_time) or
|
||||||
(args.from_time <= time_log.from_time and args.to_time >= time_log.to_time)):
|
(args.from_time <= time_log.from_time and args.to_time >= time_log.to_time)):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@@ -239,7 +238,7 @@ class Timesheet(Document):
|
|||||||
self.check_workstation_working_day(data)
|
self.check_workstation_working_day(data)
|
||||||
|
|
||||||
def get_last_working_slot(self, time_sheet, workstation):
|
def get_last_working_slot(self, time_sheet, workstation):
|
||||||
return frappe.db.sql(""" select max(from_time) as from_time, max(to_time) as to_time
|
return frappe.db.sql(""" select max(from_time) as from_time, max(to_time) as to_time
|
||||||
from `tabTimesheet Detail` where workstation = %(workstation)s""",
|
from `tabTimesheet Detail` where workstation = %(workstation)s""",
|
||||||
{'workstation': workstation}, as_dict=True)[0]
|
{'workstation': workstation}, as_dict=True)[0]
|
||||||
|
|
||||||
@@ -277,7 +276,7 @@ def get_projectwise_timesheet_data(project, parent=None):
|
|||||||
if parent:
|
if parent:
|
||||||
cond = "and parent = %(parent)s"
|
cond = "and parent = %(parent)s"
|
||||||
|
|
||||||
return frappe.db.sql("""select name, parent, billing_hours, billing_amount as billing_amt
|
return frappe.db.sql("""select name, parent, billing_hours, billing_amount as billing_amt
|
||||||
from `tabTimesheet Detail` where docstatus=1 and project = %(project)s {0} and billable = 1
|
from `tabTimesheet Detail` where docstatus=1 and project = %(project)s {0} and billable = 1
|
||||||
and sales_invoice is null""".format(cond), {'project': project, 'parent': parent}, as_dict=1)
|
and sales_invoice is null""".format(cond), {'project': project, 'parent': parent}, as_dict=1)
|
||||||
|
|
||||||
@@ -290,9 +289,9 @@ def get_timesheet(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
condition = "and tsd.project = %(project)s"
|
condition = "and tsd.project = %(project)s"
|
||||||
|
|
||||||
return frappe.db.sql("""select distinct tsd.parent from `tabTimesheet Detail` tsd,
|
return frappe.db.sql("""select distinct tsd.parent from `tabTimesheet Detail` tsd,
|
||||||
`tabTimesheet` ts where
|
`tabTimesheet` ts where
|
||||||
ts.status in ('Submitted', 'Payslip') and tsd.parent = ts.name and
|
ts.status in ('Submitted', 'Payslip') and tsd.parent = ts.name and
|
||||||
tsd.docstatus = 1 and ts.total_billable_amount > 0
|
tsd.docstatus = 1 and ts.total_billable_amount > 0
|
||||||
and tsd.parent LIKE %(txt)s {condition}
|
and tsd.parent LIKE %(txt)s {condition}
|
||||||
order by tsd.parent limit %(start)s, %(page_len)s"""
|
order by tsd.parent limit %(start)s, %(page_len)s"""
|
||||||
.format(condition=condition), {
|
.format(condition=condition), {
|
||||||
@@ -305,7 +304,7 @@ def get_timesheet_data(name, project):
|
|||||||
if project and project!='':
|
if project and project!='':
|
||||||
data = get_projectwise_timesheet_data(project, name)
|
data = get_projectwise_timesheet_data(project, name)
|
||||||
else:
|
else:
|
||||||
data = frappe.get_all('Timesheet',
|
data = frappe.get_all('Timesheet',
|
||||||
fields = ["(total_billable_amount - total_billed_amount) as billing_amt", "total_billable_hours as billing_hours"], filters = {'name': name})
|
fields = ["(total_billable_amount - total_billed_amount) as billing_amt", "total_billable_hours as billing_hours"], filters = {'name': name})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -332,7 +331,7 @@ def make_sales_invoice(source_name, target=None):
|
|||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_salary_slip(source_name, target_doc=None):
|
def make_salary_slip(source_name, target_doc=None):
|
||||||
target = frappe.new_doc("Salary Slip")
|
target = frappe.new_doc("Salary Slip")
|
||||||
set_missing_values(source_name, target)
|
set_missing_values(source_name, target)
|
||||||
target.run_method("get_emp_and_leave_details")
|
target.run_method("get_emp_and_leave_details")
|
||||||
|
|
||||||
return target
|
return target
|
||||||
@@ -364,32 +363,21 @@ def get_events(start, end, filters=None):
|
|||||||
:param filters: Filters (JSON).
|
:param filters: Filters (JSON).
|
||||||
"""
|
"""
|
||||||
filters = json.loads(filters)
|
filters = json.loads(filters)
|
||||||
|
from frappe.desk.calendar import get_event_conditions
|
||||||
|
conditions = get_event_conditions("Timesheet", filters)
|
||||||
|
|
||||||
conditions = get_conditions(filters)
|
return frappe.db.sql("""select `tabTimesheet Detail`.name as name,
|
||||||
return frappe.db.sql("""select `tabTimesheet Detail`.name as name,
|
|
||||||
`tabTimesheet Detail`.docstatus as status, `tabTimesheet Detail`.parent as parent,
|
`tabTimesheet Detail`.docstatus as status, `tabTimesheet Detail`.parent as parent,
|
||||||
from_time as start_date, hours, activity_type,
|
from_time as start_date, hours, activity_type,
|
||||||
`tabTimesheet Detail`.project, to_time as end_date,
|
`tabTimesheet Detail`.project, to_time as end_date,
|
||||||
CONCAT(`tabTimesheet Detail`.parent, ' (', ROUND(hours,2),' hrs)') as title
|
CONCAT(`tabTimesheet Detail`.parent, ' (', ROUND(hours,2),' hrs)') as title
|
||||||
from `tabTimesheet Detail`, `tabTimesheet`
|
from `tabTimesheet Detail`, `tabTimesheet`
|
||||||
where `tabTimesheet Detail`.parent = `tabTimesheet`.name
|
where `tabTimesheet Detail`.parent = `tabTimesheet`.name
|
||||||
and `tabTimesheet`.docstatus < 2
|
and `tabTimesheet`.docstatus < 2
|
||||||
and (from_time <= %(end)s and to_time >= %(start)s) {conditions} {match_cond}
|
and (from_time <= %(end)s and to_time >= %(start)s) {conditions} {match_cond}
|
||||||
""".format(conditions=conditions, match_cond = get_match_cond('Timesheet')),
|
""".format(conditions=conditions, match_cond = get_match_cond('Timesheet')),
|
||||||
{
|
{
|
||||||
"start": start,
|
"start": start,
|
||||||
"end": end
|
"end": end
|
||||||
}, as_dict=True, update={"allDay": 0})
|
}, as_dict=True, update={"allDay": 0})
|
||||||
|
|
||||||
def get_conditions(filters):
|
|
||||||
conditions = []
|
|
||||||
for key in filters:
|
|
||||||
if filters.get(key):
|
|
||||||
if frappe.get_meta("Timesheet").has_field(key):
|
|
||||||
dt = 'tabTimesheet'
|
|
||||||
elif frappe.get_meta("Timesheet Detail").has_field(key):
|
|
||||||
dt = 'tabTimesheet Detail'
|
|
||||||
|
|
||||||
conditions.append("`%s`.%s = '%s'"%(dt, key, filters.get(key)))
|
|
||||||
|
|
||||||
return " and {}".format(" and ".join(conditions)) if conditions else ""
|
|
||||||
|
|||||||
Reference in New Issue
Block a user