Merge pull request #5769 from rohitwaghchaure/timesheet_workstation_holiday_issue

[Fix] Timesheet workstation holiday issue
This commit is contained in:
Nabin Hait 2016-07-16 10:49:17 +05:30 committed by GitHub
commit 26452cb7eb
2 changed files with 41 additions and 19 deletions

View File

@ -7,6 +7,7 @@ import frappe
import json
from frappe.utils import flt, get_datetime, getdate, date_diff, cint, nowdate
from frappe import _
from frappe.utils import time_diff_in_seconds
from frappe.model.document import Document
from frappe.model.mapper import get_mapped_doc
from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
@ -262,12 +263,14 @@ class ProductionOrder(Document):
original_start_time = d.planned_start_time
# validate operating hours if workstation [not mandatory] is specified
self.check_operation_fits_in_working_hours(d)
try:
timesheet.validate_time_logs()
except OverlapError:
if frappe.message_log: frappe.message_log.pop()
timesheet.move_to_next_non_overlapping_slot(d.idx)
timesheet.schedule_for_production_order(d.idx)
except WorkstationHolidayError:
if frappe.message_log: frappe.message_log.pop()
timesheet.schedule_for_production_order(d.idx)
from_time, to_time = self.get_start_end_time(timesheet, d.name)
@ -294,7 +297,7 @@ class ProductionOrder(Document):
def get_operations_data(self, data):
return {
'from_time': data.planned_start_time,
'hours': data.time_in_mins / 60,
'hours': data.time_in_mins / 60.0,
'to_time': data.planned_end_time,
'project': self.project,
'operation': data.operation,

View File

@ -6,9 +6,12 @@ from __future__ import unicode_literals
import frappe
from frappe import _
from datetime import timedelta
from frappe.utils import flt, time_diff_in_hours, get_datetime, getdate, cint, get_datetime_str
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,
WorkstationHolidayError)
from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import get_mins_between_operations
class OverlapError(frappe.ValidationError): pass
@ -136,8 +139,8 @@ class Timesheet(Document):
def validate_time_logs(self):
for data in self.get('time_logs'):
self.validate_overlap(data)
self.check_workstation_timings(data)
self.validate_overlap(data)
def validate_overlap(self, data):
if self.production_order:
@ -179,29 +182,45 @@ class Timesheet(Document):
def check_workstation_timings(self, args):
"""Checks if **Time Log** is between operating hours of the **Workstation**."""
if args.workstation and args.from_time and args.to_time:
from erpnext.manufacturing.doctype.workstation.workstation import check_if_within_operating_hours
check_if_within_operating_hours(args.workstation, args.operation, args.from_time, args.to_time)
def move_to_next_non_overlapping_slot(self, index):
from datetime import timedelta
if self.time_logs:
for data in self.time_logs:
if data.idx == index:
overlapping = self.get_overlap_for("workstation", data, data.workstation)
if not overlapping:
frappe.throw(_("Logical error: Must find overlapping"))
if overlapping:
time_sheet = self.get_last_working_slot(overlapping.name, data.workstation)
data.from_time = get_datetime(time_sheet.to_time) + get_mins_between_operations()
data.to_time = get_datetime(data.from_time) + timedelta(hours=data.hours)
break
def schedule_for_production_order(self, index):
for data in self.time_logs:
if data.idx == index:
self.move_to_next_day(data) #check for workstation holiday
self.move_to_next_non_overlapping_slot(data) #check for overlap
break
def move_to_next_non_overlapping_slot(self, data):
overlapping = self.get_overlap_for("workstation", data, data.workstation)
if overlapping:
time_sheet = self.get_last_working_slot(overlapping.name, data.workstation)
data.from_time = get_datetime(time_sheet.to_time) + get_mins_between_operations()
data.to_time = self.get_to_time(data)
self.check_workstation_working_day(data)
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
from `tabTimesheet Detail` where workstation = %(workstation)s""",
{'workstation': workstation}, as_dict=True)[0]
def move_to_next_day(self, data):
"""Move start and end time one day forward"""
self.check_workstation_working_day(data)
def check_workstation_working_day(self, data):
while True:
try:
self.check_workstation_timings(data)
break
except WorkstationHolidayError:
if frappe.message_log: frappe.message_log.pop()
data.from_time = get_datetime(data.from_time) + timedelta(hours=24)
data.to_time = self.get_to_time(data)
def get_to_time(self, data):
return get_datetime(data.from_time) + timedelta(hours=data.hours)
def update_cost(self):
for data in self.time_logs:
if data.activity_type and not data.billing_amount: