Example #1
0
 def validate(self):
     if not is_holiday("Holiday List test", self.work_date):
         odr_list = frappe.db.sql(
             """select name,work_date from `tabOffice Daily Report` where project = %s order by work_date desc""",
             (self.project),
             as_dict=1)
         if len(odr_list) != 0:
             prev_date = add_days(self.work_date, -1)
             if is_holiday("Holiday List test", prev_date):
                 prev_date = add_days(prev_date, -1)
             frappe.errprint(prev_date)
             if not frappe.db.exists("Office Daily Report", {
                     'work_date': prev_date,
                     'project': self.project
             }):
                 frappe.throw(_("Previous day Report is still pending"))
             else:
                 odr = frappe.get_doc("Office Daily Report",
                                      odr_list[0].name)
                 if not self.manpower:
                     for od in odr.manpower:
                         self.append("manpower", {
                             "manpower": od.manpower,
                             "prev": od.cum_hours
                         })
                 if not self.major_equipment:
                     for od in odr.major_equipment:
                         self.append(
                             "major_equipment", {
                                 "major_equipment": od.major_equipment,
                                 "prev": od.cum_hours
                             })
     else:
         frappe.throw(_("Work Date cannot be a Holiday"))
Example #2
0
def send_project_update_email_to_users(project):
    doc = frappe.get_doc('Project', project)

    if is_holiday(doc.holiday_list) or not doc.users: return

    project_update = frappe.get_doc({
        "doctype":
        "Project Update",
        "project":
        project,
        "sent":
        0,
        "date":
        today(),
        "time":
        nowtime(),
        "naming_series":
        "UPDATE-.project.-.YY.MM.DD.-",
    }).insert()

    subject = "For project %s, update your status" % (project)

    incoming_email_account = frappe.db.get_value(
        'Email Account', dict(enable_incoming=1, default_incoming=1),
        'email_id')

    frappe.sendmail(recipients=get_users_email(doc),
                    message=doc.message,
                    subject=_(subject),
                    reference_doctype=project_update.doctype,
                    reference_name=project_update.name,
                    reply_to=incoming_email_account)
Example #3
0
def setup_attendance():
    from erpnext.hr.doctype.holiday_list.holiday_list import is_holiday
    import pandas as pd

    for employee in frappe.get_all("Employee"):
        for date in pd.date_range(start="2019-01-01", end=getdate(today())):
            doc = {
                "doctype": "Attendance",
                "employee": employee.name,
                "attendance_date": date.date(),
            }
            if is_holiday(str(date.year), date):
                doc["status"] = "Absent"
            elif random.random() < 0.05:
                doc["status"] = "On Leave"
                doc["leave_type"] = "Congés payés" if random.random(
                ) < 0.7 else "RTT"
            else:
                doc["status"] = "Present"

            try:
                inserted_doc = frappe.get_doc(doc).insert()
                inserted_doc.submit()
            except frappe.ValidationError as e:
                continue
Example #4
0
def get_employee_shift(employee, for_date=nowdate(), consider_default_shift=False, next_shift_direction=None):
	"""Returns a Shift Type for the given employee on the given date. (excluding the holidays)

	:param employee: Employee for which shift is required.
	:param for_date: Date on which shift are required
	:param consider_default_shift: If set to true, default shift is taken when no shift assignment is found.
	:param next_shift_direction: One of: None, 'forward', 'reverse'. Direction to look for next shift if shift not found on given date.
	"""
	default_shift = frappe.db.get_value('Employee', employee, 'default_shift')
	shift_type_name = None
	shift_assignment_details = frappe.db.get_value('Shift Assignment', {'employee':employee, 'start_date':('<=', for_date), 'docstatus': '1', 'status': "Active"}, ['shift_type', 'end_date'])

	if shift_assignment_details:
		shift_type_name = shift_assignment_details[0]

		# if end_date present means that shift is over after end_date else it is a ongoing shift.
		if shift_assignment_details[1] and for_date >= shift_assignment_details[1] :
			shift_type_name = None

	if not shift_type_name and consider_default_shift:
		shift_type_name = default_shift
	if shift_type_name:
		holiday_list_name = frappe.db.get_value('Shift Type', shift_type_name, 'holiday_list')
		if not holiday_list_name:
			holiday_list_name = get_holiday_list_for_employee(employee, False)
		if holiday_list_name and is_holiday(holiday_list_name, for_date):
			shift_type_name = None

	if not shift_type_name and next_shift_direction:
		MAX_DAYS = 366
		if consider_default_shift and default_shift:
			direction = -1 if next_shift_direction == 'reverse' else +1
			for i in range(MAX_DAYS):
				date = for_date+timedelta(days=direction*(i+1))
				shift_details = get_employee_shift(employee, date, consider_default_shift, None)
				if shift_details:
					shift_type_name = shift_details.shift_type.name
					for_date = date
					break
		else:
			direction = '<' if next_shift_direction == 'reverse' else '>'
			sort_order = 'desc' if next_shift_direction == 'reverse' else 'asc'
			dates = frappe.db.get_all('Shift Assignment',
				['start_date', 'end_date'],
				{'employee':employee, 'start_date':(direction, for_date), 'docstatus': '1', "status": "Active"},
				as_list=True,
				limit=MAX_DAYS, order_by="start_date "+sort_order)

			if dates:
				for date in dates:
					if date[1] and date[1] < for_date:
						continue
					shift_details = get_employee_shift(employee, date[0], consider_default_shift, None)
					if shift_details:
						shift_type_name = shift_details.shift_type.name
						for_date = date[0]
						break

	return get_shift_details(shift_type_name, for_date)
Example #5
0
	def validate_is_holiday(self):
		holiday_list = get_holiday_list()
		if is_holiday(holiday_list, self.date):
			frappe.throw(
				_("Attendance cannot be marked for {0} as it is a holiday.").format(
					frappe.bold(formatdate(self.date))
				)
			)
Example #6
0
def is_holiday_date(employee: str, shift_details: Dict) -> bool:
	holiday_list_name = frappe.db.get_value(
		"Shift Type", shift_details.shift_type.name, "holiday_list"
	)

	if not holiday_list_name:
		holiday_list_name = get_holiday_list_for_employee(employee, False)

	return holiday_list_name and is_holiday(holiday_list_name, shift_details.start_datetime.date())
Example #7
0
def execute(filters=None):
    if not filters:
        filters = {}

    if not filters.get("date"):
        msgprint(_("Please select date"), raise_exception=1)

    columns = get_columns(filters)
    date = filters.get("date")

    holiday_list = get_holiday_list()
    if is_holiday(holiday_list, filters.get("date")):
        msgprint(
            _("No attendance has been marked for {0} as it is a Holiday").
            format(frappe.bold(formatdate(filters.get("date")))))

    absent_students = get_absent_students(date)
    leave_applicants = get_leave_applications(date)
    if absent_students:
        student_list = [d["student"] for d in absent_students]
        transportation_details = get_transportation_details(date, student_list)

    data = []
    for student in absent_students:
        if not student.student in leave_applicants:
            row = [
                student.student, student.student_name, student.student_group
            ]
            stud_details = frappe.db.get_value(
                "Student",
                student.student, ['student_email_id', 'student_mobile_number'],
                as_dict=True)

            if stud_details.student_email_id:
                row += [stud_details.student_email_id]
            else:
                row += [""]

            if stud_details.student_mobile_number:
                row += [stud_details.student_mobile_number]
            else:
                row += [""]
            if transportation_details.get(student.student):
                row += transportation_details.get(student.student)

            data.append(row)

    return columns, data
Example #8
0
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(group_doc.holiday_list)
                and group_doc.enabled):
            emails = get_user_emails_from_group(group_doc)
            # 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)
Example #9
0
    def mark_absent_for_dates_with_no_attendance(self, employee):
        """Marks Absents for the given employee on working days in this shift which have no attendance marked.
		The Absent is marked starting from 'process_attendance_after' or employee creation date.
		"""
        start_date, end_date = self.get_start_and_end_dates(employee)

        # no shift assignment found, no need to process absent attendance records
        if start_date is None:
            return

        holiday_list_name = self.holiday_list
        if not holiday_list_name:
            holiday_list_name = get_holiday_list_for_employee(employee, False)

        start_time = get_time(self.start_time)

        for date in daterange(getdate(start_date), getdate(end_date)):
            if is_holiday(holiday_list_name, date):
                # skip marking absent on a holiday
                continue

            timestamp = datetime.combine(date, start_time)
            shift_details = get_employee_shift(employee, timestamp, True)

            if shift_details and shift_details.shift_type.name == self.name:
                attendance = mark_attendance(employee, date, "Absent",
                                             self.name)
                if attendance:
                    frappe.get_doc({
                        "doctype":
                        "Comment",
                        "comment_type":
                        "Comment",
                        "reference_doctype":
                        "Attendance",
                        "reference_name":
                        attendance,
                        "content":
                        frappe.
                        _("Employee was marked Absent due to missing Employee Checkins."
                          ),
                    }).insert(ignore_permissions=True)
Example #10
0
def execute(filters=None):
    if not filters:
        filters = {}

    if not filters.get("date"):
        msgprint(_("Please select date"), raise_exception=1)

    holiday_list = get_holiday_list()
    if is_holiday(holiday_list, filters.get("date")):
        msgprint(
            _("No attendance has been marked for {0} as it is a Holiday").
            format(frappe.bold(formatdate(filters.get("date")))))

    columns = get_columns(filters)

    active_student_group = get_active_student_group()

    data = []
    for student_group in active_student_group:
        row = [student_group.name]
        present_students = 0
        absent_students = 0
        student_group_strength = get_student_group_strength(student_group.name)
        student_attendance = get_student_attendance(student_group.name,
                                                    filters.get("date"))
        if student_attendance:
            for attendance in student_attendance:
                if attendance.status == "Present":
                    present_students = attendance.count
                elif attendance.status == "Absent":
                    absent_students = attendance.count

        unmarked_students = student_group_strength - \
            (present_students + absent_students)
        row += [
            student_group_strength, present_students, absent_students,
            unmarked_students
        ]
        data.append(row)

    return columns, data
    def update_attendance(self):
        holiday_list = get_holiday_list()

        for dt in daterange(getdate(self.from_date), getdate(self.to_date)):
            date = dt.strftime("%Y-%m-%d")

            if is_holiday(holiday_list, date):
                continue

            attendance = frappe.db.exists("Student Attendance", {
                "student": self.student,
                "date": date,
                "docstatus": ("!=", 2)
            })

            status = "Present" if self.mark_as_present else "Absent"
            if attendance:
                # update existing attendance record
                values = dict()
                values["status"] = status
                values["leave_application"] = self.name
                frappe.db.set_value("Student Attendance", attendance, values)
            else:
                # make a new attendance record
                doc = frappe.new_doc("Student Attendance")
                doc.student = self.student
                doc.student_name = self.student_name
                doc.date = date
                doc.leave_application = self.name
                doc.status = status
                if self.attendance_based_on == "Student Group":
                    doc.student_group = self.student_group
                else:
                    doc.course_schedule = self.course_schedule
                doc.insert(ignore_permissions=True, ignore_mandatory=True)
                doc.submit()
    def update_attendance(self):
        holiday_list = get_holiday_list()

        for dt in daterange(getdate(self.from_date), getdate(self.to_date)):
            date = dt.strftime('%Y-%m-%d')

            if is_holiday(holiday_list, date):
                continue

            attendance = frappe.db.exists('Student Attendance', {
                'student': self.student,
                'date': date,
                'docstatus': ('!=', 2)
            })

            status = 'Present' if self.mark_as_present else 'Absent'
            if attendance:
                # update existing attendance record
                values = dict()
                values['status'] = status
                values['leave_application'] = self.name
                frappe.db.set_value('Student Attendance', attendance, values)
            else:
                # make a new attendance record
                doc = frappe.new_doc('Student Attendance')
                doc.student = self.student
                doc.student_name = self.student_name
                doc.date = date
                doc.leave_application = self.name
                doc.status = status
                if self.attendance_based_on == 'Student Group':
                    doc.student_group = self.student_group
                else:
                    doc.course_schedule = self.course_schedule
                doc.insert(ignore_permissions=True, ignore_mandatory=True)
                doc.submit()
Example #13
0
 def update_if_holiday(self, date):
     holiday_list = self.holiday_list or get_holiday_list(self.company)
     while is_holiday(holiday_list, date):
         date = add_days(date, 1)
     return date
Example #14
0
def get_employee_shift(employee,
                       for_date=None,
                       consider_default_shift=False,
                       next_shift_direction=None):
    """Returns a Shift Type for the given employee on the given date. (excluding the holidays)

	:param employee: Employee for which shift is required.
	:param for_date: Date on which shift are required
	:param consider_default_shift: If set to true, default shift is taken when no shift assignment is found.
	:param next_shift_direction: One of: None, 'forward', 'reverse'. Direction to look for next shift if shift not found on given date.
	"""
    if for_date is None:
        for_date = nowdate()
    default_shift = frappe.db.get_value("Employee", employee, "default_shift")
    shift_type_name = None
    shift_assignment_details = frappe.db.get_value(
        "Shift Assignment",
        {
            "employee": employee,
            "start_date": ("<=", for_date),
            "docstatus": "1",
            "status": "Active"
        },
        ["shift_type", "end_date"],
    )

    if shift_assignment_details:
        shift_type_name = shift_assignment_details[0]

        # if end_date present means that shift is over after end_date else it is a ongoing shift.
        if shift_assignment_details[
                1] and for_date >= shift_assignment_details[1]:
            shift_type_name = None

    if not shift_type_name and consider_default_shift:
        shift_type_name = default_shift
    if shift_type_name:
        holiday_list_name = frappe.db.get_value("Shift Type", shift_type_name,
                                                "holiday_list")
        if not holiday_list_name:
            holiday_list_name = get_holiday_list_for_employee(employee, False)
        if holiday_list_name and is_holiday(holiday_list_name, for_date):
            shift_type_name = None

    if not shift_type_name and next_shift_direction:
        MAX_DAYS = 366
        if consider_default_shift and default_shift:
            direction = -1 if next_shift_direction == "reverse" else +1
            for i in range(MAX_DAYS):
                date = for_date + timedelta(days=direction * (i + 1))
                shift_details = get_employee_shift(employee, date,
                                                   consider_default_shift,
                                                   None)
                if shift_details:
                    shift_type_name = shift_details.shift_type.name
                    for_date = date
                    break
        else:
            direction = "<" if next_shift_direction == "reverse" else ">"
            sort_order = "desc" if next_shift_direction == "reverse" else "asc"
            dates = frappe.db.get_all(
                "Shift Assignment",
                ["start_date", "end_date"],
                {
                    "employee": employee,
                    "start_date": (direction, for_date),
                    "docstatus": "1",
                    "status": "Active",
                },
                as_list=True,
                limit=MAX_DAYS,
                order_by="start_date " + sort_order,
            )

            if dates:
                for date in dates:
                    if date[1] and date[1] < for_date:
                        continue
                    shift_details = get_employee_shift(employee, date[0],
                                                       consider_default_shift,
                                                       None)
                    if shift_details:
                        shift_type_name = shift_details.shift_type.name
                        for_date = date[0]
                        break

    return get_shift_details(shift_type_name, for_date)
Example #15
0
def update_if_holiday(holiday_list, date):
    holiday_list = holiday_list or get_holiday_list()
    while is_holiday(holiday_list, date):
        date = add_days(date, 1)
    return date
 def update_if_holiday(self, date, holiday_list):
     while is_holiday(holiday_list, date):
         date = add_days(date, 1)
     return date