コード例 #1
0
ファイル: attendance.py プロジェクト: kardmode/erpnext
	def calculate_total_hours(self):
		
		if self.arrival_time == "#--:--" or self.arrival_time == "00:00" or self.arrival_time == "0:00:00":
			self.arrival_time = "00:00:00"
			
		if self.departure_time == "#--:--" or self.departure_time == "00:00" or self.departure_time == "0:00:00":
			self.departure_time = "00:00:00"
		
		
		try:
			totalworkhours = flt(time_diff_in_seconds(self.departure_time,self.arrival_time))/3600
		except:
			try:
				time = time_diff(self.departure_time,self.arrival_time)
				totalworkhours = flt(time.hour) + flt(time.minute)/60 + flt(time.second)/3600
			except:
				frappe.throw(_("Possible error in arrival time {0} or departure time {1} for employee {2}").format(self.arrival_time,self.departure_time,self.employee))

		
		
		self.working_time = totalworkhours
		weekday = get_datetime(self.att_date).weekday()
		
		working_hours = frappe.db.sql("""select working_hours from `tabWorking Hours`
				where %s between from_date and to_date and docstatus < 2""", (self.att_date))

		if working_hours:
			self.normal_time = flt(working_hours[0][0])
		else:
			self.normal_time = flt(frappe.db.get_single_value("Regulations", "working_hours"))
			
		self.overtime = 0
		self.overtime_fridays = 0
		self.overtime_holidays = 0
		self.status = 'Present'
		
		if len(self.get_holidays_for_employee(self.att_date,self.att_date)):
			self.normal_time = 0
			self.overtime_holidays = flt(totalworkhours) - flt(self.normal_time)
		elif weekday == 4:
			self.normal_time = 0
			self.overtime_fridays = flt(totalworkhours) - flt(self.normal_time)
		else:		
			if totalworkhours > self.normal_time:
				self.overtime = flt(totalworkhours) - flt(self.normal_time)
			elif totalworkhours > 2:
				self.normal_time = totalworkhours
			elif totalworkhours > 0:
				frappe.throw(_("Work Hours under 2. Please check the time for employee {0}, date {1}").format(self.employee,self.att_date))
			elif totalworkhours < 0:
				frappe.throw(_("Work Hours negative. Please check the time for employee {0}, date {1}").format(self.employee,self.att_date))
			else:
				if self.arrival_time == "00:00:00" and self.departure_time == "00:00:00":
					self.normal_time = 0
					self.status = 'Absent'
				else:
					frappe.throw(_("Please check the time for employee {0}, date {1}").format(self.employee,self.att_date))
コード例 #2
0
def verify_otp(otp_auth_attempt_name, incoming_otp, action):
    settings = frappe.get_single('CD User Management Settings')
    frappe.set_user(settings.default_user)
    otp_auth_attempt_doc = frappe.get_doc("CD OTP Auth Attempt", {
        "name": otp_auth_attempt_name,
        "login_status": "OTP Generated"
    })
    verification_time = now_datetime().__str__()[:-7]
    otp_expiry_limit = settings.otp_expiry_limit_in_mins
    max_otp_attempts = settings.max_otp_attempts

    if not (time_diff(verification_time,
                      otp_auth_attempt_doc.generated_time).total_seconds() /
            60) <= otp_expiry_limit:
        otp_auth_attempt_doc.login_status = 'Expired'
        otp_auth_attempt_doc.save()
        frappe.local.response.http_status_code = 429
        frappe.local.response["message"] = "OTP Expired"

    if otp_auth_attempt_doc.generated_otp == incoming_otp:
        otp_auth_attempt_doc.login_status = 'Success'
        otp_auth_attempt_doc.verify_action = action.replace('_', ' ').title()
        otp_auth_attempt_doc.save()

        user = frappe.get_doc(
            "User", {'mobile_no': otp_auth_attempt_doc.mobile_number})
        if action == 'get_reset_password_key':
            user.reset_password()
            frappe.local.response[
                "reset_password_key"] = user.reset_password_key

        if action == 'get_api_credentials':
            frappe.local.response["api_key"] = user.api_key
            frappe.local.response["api_secret"] = generate_keys(
                user.name)['api_secret']

    else:
        if len(otp_auth_attempt_doc.failed_attempts) == max_otp_attempts:
            otp_auth_attempt_doc.login_status = 'Blocked'
            otp_auth_attempt_doc.save()
            frappe.local.response.http_status_code = 429
            frappe.local.response["message"] = "Maximum Limit Reached"
        else:
            otp_auth_attempt_doc.append('failed_attempts',
                                        {'failed_incoming_otp': incoming_otp})
            otp_auth_attempt_doc.save()
            frappe.local.response.http_status_code = 401
            frappe.local.response["message"] = "Incorrect OTP"
コード例 #3
0
	def make_time_sheet(self):
		if self.calculate_instructor_hour_rate and not frappe.db.exists("Timesheet", {"course_schedule": self.name}):
			from frappe.utils import time_diff
			from frappe.utils import get_datetime
			ts = frappe.new_doc("Timesheet")
			ts.update({
				"employee": frappe.get_value("Instructor", {"name": self.instructor}, "employee"),
				"company": self.company,
				"course_schedule": self.name
			})
			ts.append("time_logs", {
				"activity_type": "Teaching",
				"hours": round(float(time_diff(self.to_time, self.from_time).total_seconds()) / 3600, 6),

				"from_time": get_datetime(str(self.schedule_date) + " "+str(self.from_time)),
				"to_time":  get_datetime(str(self.schedule_date) + " "+str(self.to_time))
			})
			ts.save()
			ts.submit()
コード例 #4
0
def time_diff_in_minutes(string_ed_date, string_st_date):
    return time_diff(string_ed_date, string_st_date).total_seconds() / 60
コード例 #5
0
def time_diff_in_hours(start, end):
    print(start)
    print(end)
    print(time_diff(end, start).total_seconds() / 60)
    return round(time_diff(end, start).total_seconds() / 60, 1)
コード例 #6
0
def get_result_as_list(data, filters):

    result = []

    key_data = frappe._dict()
    key_list = []

    employees = []
    dates = []

    time_duty_in = to_timedelta("07:30:00")
    time_duty_in_round = to_timedelta("07:15:00")
    time_duty_in_from = to_timedelta("07:00:00")
    time_duty_in_to = to_timedelta("11:00:00")

    time_lunch_out = to_timedelta("11:45:00")
    time_lunch_out_round = to_timedelta("11:45:00")
    time_lunch_out_from = to_timedelta("11:30:01")
    time_lunch_out_to = to_timedelta("12:15:00")

    time_lunch_in = to_timedelta("12:30:00")
    time_lunch_in_round = to_timedelta("12:30:00")
    time_lunch_in_from = to_timedelta("12:15:01")
    time_lunch_in_to = to_timedelta("12:45:00")

    time_duty_out = to_timedelta("17:00:00")
    time_duty_out_round = to_timedelta("17:15:00")
    time_duty_out_from = to_timedelta("12:45:01")
    time_duty_out_to = to_timedelta("20:00:00")

    time_one_day = 8.75

    time_late_in = to_timedelta("07:45:00")
    time_early_out = to_timedelta("16:59:59")

    max_morning_float = 4.25
    max_evening_float = 4.5
    max_day_float = 8.75

    for d in data:
        key = (d.employee, d.c_date)

        if d.employee not in employees:
            employees.append(d.employee)

        if d.c_date not in dates:
            dates.append(d.c_date)

        if not key_data.get(key):

            key_data[key] = frappe._dict()
            key_data[key]["employee"] = d.employee
            key_data[key]["employee_name"] = d.employee_name
            key_data[key]["department"] = d.department
            key_data[key]["employee_number"] = d.employee_number
            key_data[key]["c_date"] = d.c_date
            key_data[key]["c_time"] = d.c_time
            key_data[key]["duty_in_name"] = "--------"
            key_data[key]["lunch_out_name"] = "--------"
            key_data[key]["lunch_in_name"] = "--------"
            key_data[key]["duty_out_name"] = "--------"

        c_time = to_timedelta(d.c_time)

        if not key_data[key].get("all_checkin"):
            key_data[key]["all_checkin"] = []

        key_data[key]["all_checkin"].append(cstr(d.c_time))

        if c_time > time_duty_in_from and c_time < time_duty_in_to and not key_data[
                key].get("duty_in"):
            key_data[key]["duty_in_name"] = d.c_name
            key_data[key]["duty_in"] = d.c_time

        if c_time > time_lunch_out_from and c_time < time_lunch_out_to and not key_data[
                key].get("lunch_out"):
            key_data[key]["lunch_out_name"] = d.c_name
            key_data[key]["lunch_out"] = d.c_time

        if c_time > time_lunch_in_from and c_time < time_lunch_in_to and not key_data[
                key].get("lunch_in"):
            key_data[key]["lunch_in_name"] = d.c_name
            key_data[key]["lunch_in"] = d.c_time

        if c_time > time_duty_out_from and c_time < time_duty_out_to and not key_data[
                key].get("duty_out"):
            key_data[key]["duty_out_name"] = d.c_name
            key_data[key]["duty_out"] = d.c_time

    for employee in employees:
        for c_date in dates:

            key = (employee, c_date)
            if key_data.get(key):

                error = ""

                # if c_date.strftime("%a") == "Sat":
                # 	if not (key_data[key].get("duty_in") and key_data[key].get("lunch_out")):
                # 		error = "@"
                # else:
                # 	if not (key_data[key].get("duty_in") and key_data[key].get("lunch_out") and key_data[key].get("lunch_in") and key_data[key].get("duty_out")):
                # 		error = "@"

                key_data[key]["morning"] = 0
                key_data[key]["lunch"] = 0
                key_data[key]["evening"] = 0
                key_data[key]["full_duty"] = 0
                key_data[key]["ot_hours"] = 0

                key_data[key]["late_in"] = ""
                key_data[key]["early_out"] = ""

                if key_data[key].get("duty_in"):
                    if key_data[key].get("duty_in") > time_late_in:
                        key_data[key]["late_in"] = "Late In"

                if key_data[key].get("duty_out"):
                    if key_data[key].get("duty_out") < time_early_out:
                        key_data[key]["early_out"] = "Early Out"

                row_show = True

                if filters.get("grace_period"):
                    if filters.get("grace_period") == "Late or Early":
                        if key_data[key]["late_in"] or key_data[key][
                                "early_out"]:
                            row_show = True
                        else:
                            row_show = False
                    elif (filters.get("grace_period")
                          == key_data[key]["late_in"]
                          or filters.get("grace_period")
                          == key_data[key]["early_out"]):
                        row_show = True
                    else:
                        row_show = False

                if row_show == True:

                    if key_data[key].get("duty_in"):
                        if key_data[key]["duty_in"] <= time_duty_in_round:
                            key_data[key]["duty_in"] = time_duty_in_round
                        elif key_data[key]["duty_in"] <= time_duty_in:
                            key_data[key]["duty_in"] = time_duty_in

                    if key_data[key].get("lunch_out"):
                        if key_data[key]["lunch_out"] >= time_lunch_out_round:
                            key_data[key]["lunch_out"] = time_lunch_out_round

                    if key_data[key].get("lunch_in"):
                        if key_data[key]["lunch_in"] <= time_lunch_in_round:
                            key_data[key]["lunch_in"] = time_lunch_in_round

                    if key_data[key].get("duty_out"):
                        if key_data[key]["duty_out"] >= time_duty_out:
                            key_data[key]["duty_out"] = time_duty_out

                    if key_data[key].get("lunch_out") and key_data[key].get(
                            "duty_in"):

                        key_data[key]["morning_from"] = key_data[key][
                            "duty_in"]
                        if key_data[key]["morning_from"] <= time_duty_in:
                            key_data[key]["morning_from"] = time_duty_in

                        key_data[key]["morning_to"] = key_data[key][
                            "lunch_out"]

                        key_data[key]["morning"] = time_diff(
                            key_data[key].get("morning_from"),
                            key_data[key].get("morning_to"))

                    if key_data[key].get("lunch_in") and key_data[key].get(
                            "lunch_out"):
                        key_data[key]["lunch"] = time_diff(
                            key_data[key].get("lunch_in"),
                            key_data[key].get("lunch_out"))

                    if key_data[key].get("duty_out") and key_data[key].get(
                            "lunch_in"):
                        key_data[key]["evening"] = time_diff(
                            key_data[key].get("duty_out"),
                            key_data[key].get("lunch_in"))

                    if key_data[key].get(
                            "duty_in") and not key_data[key].get("lunch_out"):
                        key_data[key]["error"] = "@"
                    elif key_data[key].get(
                            "lunch_out") and not key_data[key].get("duty_in"):
                        key_data[key]["error"] = "@"
                    elif key_data[key].get(
                            "lunch_in") and not key_data[key].get("duty_out"):
                        key_data[key]["error"] = "@"
                    elif key_data[key].get(
                            "duty_out") and not key_data[key].get("lunch_in"):
                        key_data[key]["error"] = "@"

                    if key_data[key].get("morning") and key_data[key].get(
                            "evening"):
                        key_data[key]["full_duty"] = 1
                    elif key_data[key].get("morning") or key_data[key].get(
                            "evening"):
                        key_data[key]["full_duty"] = 0.5

                    key_data[key]["total_hours_float"] = 0
                    key_data[key]["morning_float"] = 0
                    key_data[key]["lunch_float"] = 0
                    key_data[key]["evening_float"] = 0
                    key_data[key]["ot_hours_float"] = 0

                    if key_data[key].get("morning") != 0:
                        key_data[key]["morning_float"] = key_data[key].get(
                            "morning").seconds / (60 * 60)
                        if key_data[key]["morning_float"] > max_morning_float:
                            key_data[key]["morning_float"] = max_morning_float
                        # key_data[key]["morning_float"] = round_time_up(key_data[key]["morning_float"])

                    if key_data[key].get("lunch") != 0:
                        key_data[key]["lunch_float"] = key_data[key].get(
                            "lunch").seconds / (60 * 60)

                    if key_data[key].get("evening") != 0:
                        key_data[key]["evening_float"] = key_data[key].get(
                            "evening").seconds / (60 * 60)
                        if key_data[key]["evening_float"] > max_evening_float:
                            key_data[key]["evening_float"] = max_evening_float
                        # key_data[key]["evening_float"] = round_time_up(key_data[key]["evening_float"])

                    key_data[key]["total_hours_float"] = key_data[key][
                        "morning_float"] + key_data[key]["evening_float"]

                    if key_data[key].get("morning") and key_data[key].get(
                            "evening"):
                        if key_data[key][
                                "total_hours_float"] - time_one_day > 0:
                            key_data[key]["ot_hours_float"] = key_data[key][
                                "total_hours_float"] - time_one_day

                    key_data[key]["all_checkin"] = " || ".join(
                        key_data[key]["all_checkin"])
                    key_data[key]["morning"] = key_data[key].get(
                        "morning") or ""
                    key_data[key]["lunch"] = key_data[key].get("lunch") or ""
                    key_data[key]["evening"] = key_data[key].get(
                        "evening") or ""

                    key_data[key]["total_hours_float"] = key_data[key].get(
                        "total_hours_float") if (
                            key_data[key].get("total_hours_float") > 0) else ""
                    key_data[key]["full_duty"] = key_data[key].get(
                        "full_duty") or ""
                    key_data[key]["ot_hours"] = key_data[key].get(
                        "ot_hours") or ""

                    key_data[key]["duty_in"] = key_data[key].get(
                        "duty_in") or "--------"
                    key_data[key]["lunch_out"] = key_data[key].get(
                        "lunch_out") or "--------"
                    key_data[key]["lunch_in"] = key_data[key].get(
                        "lunch_in") or "--------"
                    key_data[key]["duty_out"] = key_data[key].get(
                        "duty_out") or "--------"

                    row = key_data[key]

                    result.append(row)

    return result
コード例 #7
0
    def add_overtime(self, att_over, to_time, att_from_time,
                     employee_start_time, employee_end_time):
        #if is_overtime_exceeded(self.employee, self.attendance_date):
        #	frappe.throw(_("Overtime is exceeded!"))

        overtime_max_minutes = frappe.db.get_value("HR Settings", None,
                                                   "overtime_max_minutes")
        if not overtime_max_minutes:
            frappe.throw(_("Enter the value of max overtime in HR settings"))

        total_att = time_diff(str(self.departure_time),
                              str(self.attendance_time))
        shift_att = time_diff(str(employee_end_time), str(employee_start_time))
        diff = time_diff_in_hours(str(total_att), str(shift_att))

        att_time = frappe.db.get_value(
            "Attendance", {
                "docstatus": ("<", 2),
                "employee": self.employee,
                "attendance_date": self.attendance_date
            }, "attendance_time")
        if not att_time: att_time = self.attendance_time

        dep_time = att_time + shift_att
        dep_timedate = dt.datetime.combine(
            getdate(self.attendance_date),
            dt.datetime.strptime(str(dep_time), '%H:%M:%S').time())

        total_exit = self.validate_permissions()
        #frappe.msgprint(str(total_exit))
        discount_permissions_from_attendance_hours = frappe.db.get_value(
            "HR Settings", None, "discount_permissions_from_attendance_hours")
        if discount_permissions_from_attendance_hours and total_exit != 0.0:
            if diff > total_exit:
                diff = diff - total_exit
            else:
                diff = total_exit - diff

        if self.attendance_time:
            if total_att > shift_att and diff * 60 > float(
                    overtime_max_minutes):

                if att_over:
                    over_det = frappe.get_doc('Timesheet', att_over)
                    if frappe.db.exists(
                            'Timesheet Detail', {
                                'parent': over_det.name,
                                'activity_type':
                                _('Auto Entry: Overtime Attendance')
                            }):
                        time_det = frappe.get_doc(
                            'Timesheet Detail', {
                                'parent':
                                over_det.name,
                                'activity_type':
                                _('Auto Entry: Overtime Attendance')
                            })
                        time_det.update({
                            'from_time': dep_timedate,
                            'to_time': to_time,
                            'hours': diff
                        })
                        #time_det.from_time = dep_timedate
                        #time_det.to_time = to_time
                        time_det.flags.ignore_validate = True
                        time_det.flags.ignore_validate_update_after_submit = True
                        time_det.save(ignore_permissions=True)
                        update_overtime_total_hrs(over_det)
                    else:
                        over_det.update({
                            'time_logs': [{
                                'activity_type':
                                _('Auto Entry: Overtime Attendance'),
                                'from_time':
                                dep_timedate,
                                'to_time':
                                to_time,
                                'hours':
                                diff
                            }]
                        })
                        over_det.flags.ignore_validate = True
                        over_det.flags.ignore_validate_update_after_submit = True
                        over_det.save(ignore_permissions=True)
                        update_overtime_total_hrs(over_det)

                else:
                    overtime = frappe.new_doc('Timesheet')
                    overtime.update({
                        'name':
                        self.employee,
                        'employee':
                        self.employee,
                        'start_date':
                        getdate(self.attendance_date),
                        'to_date':
                        getdate(self.attendance_date),
                        'time_logs': [{
                            'activity_type':
                            _('Auto Entry: Overtime Attendance'),
                            'from_time':
                            dep_timedate,
                            'to_time':
                            to_time,
                            'hours':
                            diff
                        }],
                        'type':
                        'compensatory',
                        'docstatus':
                        0,
                        'workflow_state':
                        'Pending Request'
                    })
                    overtime.insert(ignore_permissions=True)
        return "done"
コード例 #8
0
    def validate_attendance_date(self):
        att_time = frappe.db.get_value(
            "Attendance", {
                "docstatus": ("<", 2),
                "employee": self.employee,
                "attendance_date": self.departure_date
            }, "attendance_time")
        departure_date = self.departure_date
        if self.departure_date and (isinstance(self.departure_date, str) or
                                    isinstance(self.departure_date, unicode)):
            departure_date = datetime.datetime.strptime(
                self.departure_date, '%Y-%m-%d')
        att_time_next = frappe.db.get_value(
            "Attendance", {
                "docstatus": ("<", 2),
                "employee": self.employee,
                "attendance_date": (departure_date - timedelta(days=1))
            }, "attendance_time")
        if not att_time and att_time_next:
            att_time = att_time_next
        elif not att_time and not att_time_next:
            frappe.throw(_("Attendance does not exist"))

        attendance_day = calendar.day_name[getdate(
            self.departure_date).weekday()]
        attendance_day_next = calendar.day_name[
            getdate(self.departure_date).weekday() - 1]
        employee_work_shift = frappe.db.get_value("Employee", self.employee,
                                                  "work_shift")
        employee_end_time = frappe.db.get_value("Work Shift Details", {
            "parent": employee_work_shift,
            "day": attendance_day
        }, "end_work")

        employee_end_time_next = frappe.db.get_value(
            "Work Shift Details", {
                "parent": employee_work_shift,
                "day": attendance_day_next,
                "next_day": 1
            }, "end_work")

        #if not employee_end_time and not employee_end_time_next:
        #	frappe.throw(_("End Time Work Shift does not exist for that day"))
        #if get_time(self.departure_time) > get_time(employee_end_time):
        #	frappe.throw(_("Departure time can not be more than employee's end time shift"))

        if self.departure_time:
            exit_per = frappe.db.get_value(
                "Exit permission", {
                    'employee': self.employee,
                    'permission_type': 'Exit with return',
                    'permission_date': self.departure_date,
                    'type': 'Exit',
                    'docstatus': ("<", 2)
                }, "name")
            ret_per = frappe.db.get_value(
                "Exit permission", {
                    'employee': self.employee,
                    'permission_type': 'Exit with return',
                    'permission_date': self.departure_date,
                    'type': 'Return',
                    'docstatus': ("<", 2)
                }, ["name", "to_date"])

            if exit_per and not ret_per:
                frappe.throw(
                    _("Not Allowed! You have an Exit permission with no return"
                      ))

            if ret_per:
                if get_time(self.departure_time) < get_time(ret_per[1]):
                    frappe.throw(
                        _("Departure time can not be less than return time permission"
                          ))

        day = calendar.day_name[getdate(self.departure_date).weekday()]
        day_next = calendar.day_name[getdate(self.departure_date).weekday() -
                                     1]
        employee_work_shift = frappe.db.get_value("Employee", self.employee,
                                                  "work_shift")

        employee_start_time = frappe.db.get_value("Work Shift Details", {
            "parent": employee_work_shift,
            "day": day
        }, "start_work")
        employee_end_time = frappe.db.get_value("Work Shift Details", {
            "parent": employee_work_shift,
            "day": day
        }, "end_work")

        employee_start_time_next = frappe.db.get_value("Work Shift Details", {
            "parent": employee_work_shift,
            "day": day_next,
            "next_day": 1
        }, "start_work")
        employee_end_time_next = frappe.db.get_value("Work Shift Details", {
            "parent": employee_work_shift,
            "day": day_next,
            "next_day": 1
        }, "end_work")
        #shift_diff = str(time_diff_in_hours(employee_end_time,employee_start_time))
        #if not employee_start_time and not employee_start_time_next:
        #	frappe.throw(_("Start Time Work Shift does not exist for that day"))

        if employee_end_time_next:
            att_from_time = frappe.db.sql(
                'select TIMESTAMP(%s , %s)',
                (self.departure_date, employee_end_time_next))[0][0]
        if employee_end_time:
            att_from_time = frappe.db.sql(
                'select TIMESTAMP(%s , %s)',
                (self.departure_date, employee_end_time))[0][0]

        if employee_end_time_next:
            to_time = frappe.db.sql(
                'select TIMESTAMP(%s , %s)',
                (self.departure_date, self.departure_time))[0][0]
            from_time = frappe.db.sql(
                'select TIMESTAMP(%s , %s)',
                (departure_date - timedelta(days=1), att_time))[0][0]
        else:
            to_time = frappe.db.sql(
                'select TIMESTAMP(%s , %s)',
                (self.departure_date, self.departure_time))[0][0]
            from_time = frappe.db.sql('select TIMESTAMP(%s , %s)',
                                      (self.departure_date, att_time))[0][0]

        #### In Holiday >>overtime ###
        holiday_list = frappe.db.get_value("Employee", self.employee,
                                           "holiday_list")
        att_over = frappe.db.get_value(
            "Timesheet", {
                "employee": self.employee,
                "start_date": self.departure_date,
                "docstatus": ("<", 2)
            }, "name")
        over_diff = str(time_diff_in_hours(to_time, from_time))
        is_holiday = False
        if holiday_list:
            holidays = frappe.get_all("Holiday",
                                      fields=["holiday_date"],
                                      filters={'parent': holiday_list})
            for holiday in holidays:
                if holiday.holiday_date == getdate(self.departure_date):
                    is_holiday = True

            overtime_max_minutes = frappe.db.get_value("HR Settings", None,
                                                       "overtime_max_minutes")
            if not overtime_max_minutes:
                frappe.throw(
                    _("Enter the value of max overtime in HR settings"))

            #if is_overtime_exceeded(self.employee, self.departure_date):
            #	frappe.throw(_("Overtime is exceeded!"))
            diff = 0
            if is_holiday:
                if employee_start_time_next:
                    total_att = datetime.timedelta(hours=24) - time_diff(
                        str(att_time), str(self.departure_time))
                    shift_att = datetime.timedelta(hours=24) - time_diff(
                        str(employee_start_time_next), str(employee_end_time))
                    diff = time_diff_in_hours(str(total_att), str(shift_att))

                else:
                    total_att = time_diff(str(self.departure_time),
                                          str(att_time))
                    shift_att = time_diff(str(employee_end_time),
                                          str(employee_start_time))
                    #diff = time_diff_in_hours(str(total_att),str(shift_att))
                    diff = 0

            if is_holiday and total_att > shift_att and diff * 60 > float(
                    overtime_max_minutes):
                dep_time = att_time + shift_att
                if employee_start_time_next:
                    dep_timedate = frappe.db.sql(
                        'select TIMESTAMP(%s , %s)',
                        ((departure_date - timedelta(days=1)), dep_time))[0][0]
                #dep_timedate= dt.datetime.combine(getdate(self.departure_date), dt.datetime.strptime(str(dep_time), '%H:%M:%S.%f').time())
                else:
                    dep_timedate = frappe.db.sql(
                        'select TIMESTAMP(%s , %s)',
                        (self.departure_date, dep_time))[0][0]

                if att_over:
                    over_det = frappe.get_doc('Timesheet', att_over)
                    if frappe.get_value(
                            'Timesheet Detail', {
                                'parent': over_det.name,
                                'activity_type':
                                _('Auto Entry: Overtime Attendance')
                            }):
                        time_det = frappe.get_doc(
                            'Timesheet Detail', {
                                'parent':
                                over_det.name,
                                'activity_type':
                                _('Auto Entry: Overtime Attendance')
                            })
                        time_det.update({
                            'from_time': dep_timedate,
                            'to_time': to_time,
                            'hours': diff
                        })
                        time_det.flags.ignore_validate = True
                        time_det.flags.ignore_validate_update_after_submit = True
                        time_det.save(ignore_permissions=True)

                        from erpnext.hr.doctype.employee_edit_time.employee_edit_time import update_overtime_total_hrs
                        update_overtime_total_hrs(over_det)

                else:
                    hol_overtime = frappe.new_doc('Timesheet')
                    hol_overtime.update({
                        'name':
                        self.employee,
                        'employee':
                        self.employee,
                        'start_date':
                        getdate(self.departure_date),
                        'to_date':
                        getdate(self.departure_date),
                        'time_logs': [{
                            'activity_type':
                            _('Auto Entry: Overtime Attendance'),
                            'from_time':
                            dep_timedate,
                            'to_time':
                            to_time,
                            'hours':
                            diff
                        }],
                        'type':
                        'compensatory',
                        'docstatus':
                        0,
                        'workflow_state':
                        'Pending Request'
                    })
                    hol_overtime.insert(ignore_permissions=True)

            else:

                self.add_overtime(att_time, att_over, to_time, att_from_time,
                                  employee_start_time, employee_end_time,
                                  employee_start_time_next)

    ########Early Departure

        early_departure_in_minutes = frappe.db.get_value(
            "HR Settings", None, "early_departure_in_minutes")
        if not early_departure_in_minutes:
            frappe.throw(
                _("Add a value for Early Departure In Minutes in HR Settings"))

        if self.is_new(
        ) and employee_end_time and self.departure_time and self.docstatus < 2 and not is_holiday:
            diff = 0
            #if get_time(self.departure_time) < get_time(employee_end_time):
            #diff_time = frappe.db.sql("select format(((TIME_TO_SEC('%s')-TIME_TO_SEC('%s'))/60),0)" %(str(employee_end_time), str(self.departure_time)))
            if employee_start_time_next:
                total_att = datetime.timedelta(hours=24) - time_diff(
                    str(att_time), str(self.departure_time))
                shift_att = datetime.timedelta(hours=24) - time_diff(
                    str(employee_start_time_next), str(employee_end_time))
                diff = time_diff_in_hours(str(shift_att), str(total_att))

            else:
                total_att = time_diff(str(self.departure_time), str(att_time))
                shift_att = time_diff(str(employee_end_time),
                                      str(employee_start_time))
                diff = time_diff_in_hours(str(shift_att), str(total_att))

                #frappe.msgprint(str(diff))

            if total_att < shift_att:
                if abs(diff * 60) > float(early_departure_in_minutes):
                    doc = frappe.new_doc('Exit permission')
                    doc.update({
                        'employee':
                        self.employee,
                        'permission_date':
                        getdate(self.departure_date),
                        'from_date':
                        get_time(att_time),
                        'to_date':
                        get_time(self.departure_time),
                        'reason':
                        _("System Auto Entry: Early Departure"),
                        'permission_type':
                        "Early Departure",
                        'early_diff':
                        round(diff, 2),
                        'docstatus':
                        0,
                        'workflow_state':
                        'Pending Request'
                    })
                    doc.insert(ignore_permissions=True)
コード例 #9
0
    def add_overtime(self, att_time, att_over, to_time, att_from_time,
                     employee_start_time, employee_end_time,
                     employee_start_time_next):
        diff = 0
        overtime_max_minutes = frappe.db.get_value("HR Settings", None,
                                                   "overtime_max_minutes")
        if not overtime_max_minutes:
            frappe.throw(_("Enter the value of max overtime in HR settings"))

        #if is_overtime_exceeded(self.employee, self.departure_date):
        #	frappe.throw(_("Overtime is exceeded!"))
        if employee_start_time_next:
            total_att = datetime.timedelta(hours=24) - time_diff(
                str(att_time), str(self.departure_time))
            shift_att = datetime.timedelta(hours=24) - time_diff(
                str(employee_start_time_next), str(employee_end_time))
            diff = time_diff_in_hours(str(total_att), str(shift_att))
        else:
            total_att = time_diff(str(self.departure_time), str(att_time))
            shift_att = time_diff(str(employee_end_time),
                                  str(employee_start_time))
            #diff = time_diff_in_hours(str(total_att),str(shift_att))
            diff = 0

        dep_time = att_time + shift_att
        dep_timedate = frappe.db.sql('select TIMESTAMP(%s , %s)',
                                     (self.departure_date, dep_time))[0][0]
        #dep_timedate= dt.datetime.combine(getdate(self.departure_date), dt.datetime.strptime(str(dep_time), '%H:%M:%S.%f').time())
        total_exit = self.validate_permissions()
        #frappe.msgprint("bb "+str(total_exit))
        discount_permissions_from_attendance_hours = frappe.db.get_value(
            "HR Settings", None, "discount_permissions_from_attendance_hours")
        if discount_permissions_from_attendance_hours and total_exit != 0.0:
            if diff > total_exit:
                diff = diff - total_exit
            else:
                diff = total_exit - diff
        #### attendance > shift time ####

        if att_time:
            #diff_time=str(time_diff_in_hours(self.departure_time,att_time))
            #diff_time = frappe.db.sql("select format(((TIME_TO_SEC('%s')-TIME_TO_SEC('%s'))/60),0)" %(str(self.departure_time), str(att_from_time)))[0][0]
            #shift_diff1 = frappe.db.sql("select format(((TIME_TO_SEC('%s')-TIME_TO_SEC('%s'))/60),0)" %(str(employee_end_time), str(employee_start_time)))[0][0]

            #frappe.msgprint(str(rem_dt))
            #frappe.msgprint(str(get_time(self.departure_time)+to_timedelta(diff_dep_shift)))
            #if shift_diff1 and float(diff_time) > 0:
            if total_att > shift_att and diff * 60 > float(
                    overtime_max_minutes):
                if att_over:
                    over_det = frappe.get_doc('Timesheet', att_over)
                    if frappe.get_value(
                            'Timesheet Detail', {
                                'parent': over_det.name,
                                'activity_type':
                                _('Auto Entry: Overtime Attendance')
                            }):
                        time_det = frappe.get_doc(
                            'Timesheet Detail', {
                                'parent':
                                over_det.name,
                                'activity_type':
                                _('Auto Entry: Overtime Attendance')
                            })
                        time_det.update({
                            'from_time':
                            dep_timedate.replace(microsecond=0),
                            'to_time':
                            to_time,
                            'hours':
                            diff
                        })
                        time_det.flags.ignore_validate = True
                        time_det.flags.ignore_validate_update_after_submit = True
                        time_det.save(ignore_permissions=True)

                        from erpnext.hr.doctype.employee_edit_time.employee_edit_time import update_overtime_total_hrs
                        update_overtime_total_hrs(over_det)

                else:
                    overtime = frappe.new_doc('Timesheet')
                    overtime.update({
                        'name':
                        self.employee,
                        'employee':
                        self.employee,
                        'start_date':
                        getdate(self.departure_date),
                        'to_date':
                        getdate(self.departure_date),
                        'time_logs': [{
                            'activity_type':
                            _('Auto Entry: Overtime Attendance'),
                            'from_time':
                            dep_timedate.replace(microsecond=0),
                            'to_time':
                            to_time,
                            'hours':
                            diff
                        }],
                        'type':
                        'compensatory',
                        'docstatus':
                        0,
                        'workflow_state':
                        'Pending Request'
                    })
                    overtime.insert(ignore_permissions=True)
        return "done"
コード例 #10
0
            frappe.throw(
                _("Possible error in arrival time {0} for employee {1}").
                format(self.arrival_time, self.employee, cstr(e)))
        except:
            frappe.throw(
                _("Possible error in arrival time {0} for employee {1}").
                format(self.arrival_time, self.employee))

        totalworkhours = 0
        try:
            totalworkhours = flt(
                time_diff_in_seconds(self.departure_time,
                                     self.arrival_time)) / 3600
        except:
            try:
                time = time_diff(self.departure_time, self.arrival_time)
                totalworkhours = flt(time.hour) + flt(time.minute) / 60 + flt(
                    time.second) / 3600
            except:
                frappe.throw(
                    _("Possible error in arrival time {0} or departure time {1} for employee {2}"
                      ).format(self.arrival_time, self.departure_time,
                               self.employee))

        if totalworkhours < 0:
            frappe.throw(
                _("Working time cannot be negative. Please check arrival time {0} or departure time {1} for employee {2} on date {3}"
                  ).format(self.arrival_time, self.departure_time,
                           self.employee, self.attendance_date))
        elif totalworkhours > 24:
            frappe.throw(
コード例 #11
0
def mark_attendance(**args):
    args = frappe._dict(args)
    employee = args.get("userid")
    posix_timestamp = args.get("att_time")
    att_type = args.get("att_type")
    stgid = args.get("stgid")
    token = args.get("auth_token")
    # create the custom response
    response = Response()
    response.mimetype = 'text/plain'
    response.charset = 'utf-8'
    response.data = "ok"

    if not employee or not posix_timestamp or not stgid or not token:
        log_error("invalid data", args)
        return response
    # TODO validate URL/IP if provided
    if not frappe.db.exists("Custom Biometric Unit Integration Settings",
                            {"device_id": stgid}):
        log_error("settings for device missing", args)
        return response
    auth_token = frappe.db.get_value(
        "Custom Biometric Unit Integration Settings", {"device_id": stgid},
        "auth_token")
    if not auth_token or (auth_token and auth_token != token):
        log_error("device auth error", args)
        return response
    if not frappe.db.exists("Employee", employee):
        log_error("employee not found", args)
        return response
    try:
        timestamp = float(posix_timestamp)
        tz = pytz.timezone('UTC')
        dt = datetime.fromtimestamp(timestamp, tz)
        dt = get_datetime_str(dt)
        date = getdate(dt)
    except:
        log_error("invalid timestamp", args)
        return response
    attendance = None
    company = frappe.db.get_value("Employee", employee, "company")
    attendance_name = frappe.db.exists("Attendance", {
        "employee": employee,
        "attendance_date": date
    })
    if attendance_name:
        attendance = frappe.get_doc("Attendance", attendance_name)

    if attendance:
        if attendance.docstatus == 1:
            log_error("attendance already submitted", args)
            return response
        else:
            attendance.cams_out = dt
            attendance.cams_out_device = stgid
    else:
        try:
            attendance = frappe.get_doc({
                "doctype": "Attendance",
                "employee": employee,
                "attendance_date": date,
                "company": company,
                "status": "Present",
                "cams_in": dt,
                "cams_in_device": stgid,
                "cams_spend": None
            }).insert(ignore_permissions=1)
            frappe.db.commit()
            return response
        except:
            log_error("insert attendance", args)
            return response

    if attendance.cams_in and attendance.cams_out:
        attendance.cams_spend = time_diff(attendance.cams_out,
                                          attendance.cams_in)
    try:
        attendance.db_update()
        frappe.db.commit()
    except:
        log_error("update attendance", args)
        return response
    return response
コード例 #12
0
def get_shift_hours(toTime, fromTime):
    hours = time_diff(toTime, fromTime)
    return hours
コード例 #13
0
ファイル: late_in.py プロジェクト: thispl/teampro
def time_diff_in_minutes(in_time, s_time):
    return time_diff(in_time, s_time).total_seconds() / 60