Пример #1
0
def daily_notifications():
    """
        sent notifications to user if 
        1 : ticket is open for more than 24 hrs
        2 : ticket is assigned but not Closed in 24 hrs
    """
    tickets = frappe.db.get_all("Ticket Escalation History", filters=[["status", "!=", "Closed"], ["status", "!=", "Deleted"]], fields=["*"])
    for ticket in tickets:
        # ticket is raised but not yet assigned
        issue_doc = frappe.get_doc("Issue", ticket.ticket_id)
        args = {
            "user": get_fullname(issue_doc.raised_by) or "User",
            "email": issue_doc.raised_by,
            "action": "user_issue_notification",
            "issue": issue_doc
        }
        if ticket.raised_email_notification and not ticket.assigned_email_notification:
            raised_time = ticket.raised_email_notification_datetime
            if time_diff_in_hours(get_datetime().now(), raised_time) >= 24:
                # send user notification mail
                msg = "Your support ticket {ticket_id} is pending our representative will \
                check the issue as soon as possible".format(ticket_id=ticket.ticket_id)
                
                args.update({"msg":msg})
                send_mail(args, "[HelpDesk] Daily Notifications")
        elif ticket.assigned_email_notification and not ticket.status_closed_email_notification:
            assigned_time = ticket.assigned_email_notification_datetime
            if time_diff_in_hours(get_datetime().now(), assigned_time) >= 24:
                # send the user notification mail
                msg = "Your support ticket {ticket_id} is assigned to our support representative \
                and issue will be solved as soon as possble".format(ticket_id=ticket.ticket_id)
                
                args.update({"msg":msg})
                send_mail(args, "[HelpDesk] Daily Notifications")
Пример #2
0
def get_billable_and_total_hours(activity, end, start, total_hours,
                                 total_billable_hours, total_amount):
    total_hours += abs(time_diff_in_hours(end, start))
    if activity.billable:
        total_billable_hours += abs(time_diff_in_hours(end, start))
        total_amount += total_billable_hours * activity.billing_rate
    return total_hours, total_billable_hours, total_amount
Пример #3
0
    def validate_dates(self):
        for data in self.time_logs:
            if data.from_time and data.to_time and time_diff_in_hours(
                    data.to_time, data.from_time) < 0:
                frappe.throw(_("To date cannot be before from date"))

            def_over = frappe.db.get_value(
                "HR Settings", None, "max_working_hours_against_timesheet")
            if time_diff_in_hours(data.to_time,
                                  data.from_time) >= float(def_over):
                frappe.throw(_("Overtime cannot be more than Max value"))

            if self.type != 'compensatory' and is_overtime_exceeded(
                    self.employee, data.from_time):
                frappe.throw(_("Overtime is exceeded!"))

            attendance_day = calendar.day_name[getdate(
                self.start_date).weekday()]
            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": attendance_day
            }, "start_work")

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

        if not employee_start_time:
            frappe.throw(
                _("Start Time Work Shift does not exist for that day"))

        if not employee_end_time:
            frappe.throw(_("End Time Work Shift does not exist for that day"))

            diff_time = frappe.db.sql(
                "select format(((TIME_TO_SEC('%s')-TIME_TO_SEC('%s'))),0)" %
                (str(employee_start_time), str(data.from_time)))[0][0]
            diff_time2 = frappe.db.sql(
                "select format(((TIME_TO_SEC('%s')-TIME_TO_SEC('%s'))),0)" %
                (str(employee_end_time), str(data.to_time)))[0][0]
            #frappe.msgprint(str(employee_start_time)+" v "+str(get_time(data.from_time))+" c "+str(employee_end_time)+" v "+str(get_time(data.to_time)))
            #if get_time(data.to_time) < get_time(employee_end_time) and get_time(data.to_time) > get_time(employee_start_time):
            #	frappe.msgprint(str(diff_time)+" f "+str(diff_time2))
            hold_f = False
            holiday_list = frappe.db.get_value("Employee", self.employee,
                                               "holiday_list")
            if holiday_list:
                holidays = frappe.get_all("Holiday",
                                          fields=["holiday_date"],
                                          filters={'parent': holiday_list})
                for holiday in holidays:
                    if holiday.holiday_date == getdate(
                            data.from_time) or holiday.holiday_date == getdate(
                                data.to_time):
                        hold_f = True
Пример #4
0
def set_service_level_agreement_variance(issue=None):
    current_time = frappe.flags.current_time or now_datetime()

    filters = {"status": "Open", "agreement_fulfilled": "Ongoing"}
    if issue:
        filters = {"name": issue}

    for issue in frappe.get_list("Issue", filters=filters):
        doc = frappe.get_doc("Issue", issue.name)

        if not doc.first_responded_on:  # first_responded_on set when first reply is sent to customer
            variance = round(time_diff_in_hours(doc.response_by, current_time),
                             2)
            frappe.db.set_value("Issue", doc.name, "response_by_variance",
                                variance)
            if variance < 0:
                frappe.db.set_value("Issue", doc.name, "agreement_fulfilled",
                                    "Failed")

        if not doc.resolution_date:  # resolution_date set when issue has been closed
            variance = round(
                time_diff_in_hours(doc.resolution_by, current_time), 2)
            frappe.db.set_value("Issue", doc.name, "resolution_by_variance",
                                variance)
            if variance < 0:
                frappe.db.set_value("Issue", doc.name, "agreement_fulfilled",
                                    "Failed")
Пример #5
0
 def update_agreement_status(self):
     current_time = frappe.flags.current_time or now_datetime()
     if self.service_level_agreement:
         if (round(time_diff_in_hours(self.response_by, current_time),
                   2) < 0 or
                 round(time_diff_in_hours(self.resolution_by, current_time),
                       2) < 0):
             self.agreement_status = "Failed"
         else:
             self.agreement_status = "Fulfilled"
Пример #6
0
    def add_overtime(self, attendance_day, employee_work_shift,
                     employee_end_time):
        #if is_overtime_exceeded(self.employee, self.attendance_date):
        #	frappe.throw(_("Overtime is exceeded!"))

        holiday_list = frappe.db.get_value("Employee", self.employee,
                                           "holiday_list")
        if holiday_list:
            #holidays = frappe.get_list("Holiday",fields=["holiday_date"], filters={'parent':holiday_list}, as_list=1)
            holidays = frappe.get_all("Holiday",
                                      fields=["holiday_date"],
                                      filters={'parent': holiday_list})
            from_time = frappe.db.sql(
                'select TIMESTAMP(%s , %s)',
                (self.attendance_date, self.attendance_time))[0][0]
            to_time = frappe.db.sql(
                'select TIMESTAMP(%s , %s)',
                (self.attendance_date, employee_end_time))[0][0]
            #hours = frappe.db.sql("select format(((TIME_TO_SEC('%s')-TIME_TO_SEC('%s'))/60),0)" %(str(to_time), str(from_time)))[0][0]
            for holiday in holidays:
                if holiday.holiday_date == getdate(self.attendance_date):
                    if att_over:
                        doc = frappe.db.sql(
                            'update `tabTimesheet Detail` set to_time=%s where parent=%s and from_time=%s and hours=%s',
                            (to_time, att_over, from_time,
                             str(time_diff_in_hours(to_time, from_time))))
                    else:
                        overtime = frappe.new_doc('Timesheet')
                        overtime.update({
                            'name':
                            self.employee_name,
                            'employee':
                            self.employee,
                            'start_date':
                            getdate(nowdate()),
                            'to_date':
                            getdate(nowdate()),
                            'time_logs': [{
                                'activity_type':
                                _('Auto Entry: Attendance in holiday date'),
                                'from_time':
                                from_time,
                                'to_time':
                                to_time,
                                'hours':
                                time_diff_in_hours(to_time, from_time)
                            }],
                            'type':
                            'Normal',
                            'docstatus':
                            0,
                            'workflow_state':
                            'Pending Request'
                        })
                        overtime.insert(ignore_permissions=True)
Пример #7
0
def validate_due_date(doc):
    # get the time limit for the role from escalation settings
    now = get_datetime().now()
    datetime_str = "{date} {time}".format(date=doc.date, time=doc.due_time)

    datetime_str = datetime.strptime(
        datetime_str.split(".")[0],
        "%Y-%m-%d %H:%M:%S").strftime("%Y-%m-%d %H:%M:%S")
    now_str = now.strftime("%Y-%m-%d %H:%M:%S")

    # if time_diff_in_hours(datetime_str, now_str) < 0:
    # 	frappe.throw("Can not assign past date")

    creation = datetime.strptime(doc.creation, "%Y-%m-%d %H:%M:%S.%f")

    if creation.replace(microsecond=0) == now.replace(microsecond=0):
        # current user highest role in doc.role
        if doc.assigned_by == frappe.session.user:
            doc.role = get_highest_role(frappe.session.user)
            doc.assigned_to_role = get_highest_role(doc.owner)
        else:
            doc.role = get_highest_role(doc.assigned_by)
            doc.assigned_to_role = get_highest_role(doc.owner)

    query = """	SELECT
				    er.time
				FROM
				    `tabTicket Escalation Settings Record` AS er
				JOIN
				    `tabTicket Escalation Settings` AS tes
				ON
				    er.parent=tes.name
				AND er.role='%s'
				AND tes.is_default=1""" % (doc.role or "Administrator")

    result = frappe.db.sql(query, as_dict=True)
    if not result:
        frappe.throw("Can not find the Role in Escalation Settings")
    else:
        time = result[0].get("time")
        if creation.replace(microsecond=0) == now.replace(microsecond=0):
            set_due_dttm(doc, now, time)
        elif time_diff_in_hours(datetime_str, now_str) < 0:
            set_due_dttm(doc, now, time)
        else:
            datetime_str = "{date} {time}".format(date=doc.date,
                                                  time=doc.due_time)
            time_diff = time_diff_in_hours(datetime_str, str(now))

            if time < time_diff:
                dttm = (now +
                        timedelta(hours=time)).strftime("%d-%m-%Y %H:%M:%S")
                frappe.throw(
                    "Invalid Due Date and Time, Due Date & time shoud be : %s"
                    % (dttm))
Пример #8
0
    def set_response_and_resolution_time(self,
                                         priority=None,
                                         service_level_agreement=None):
        service_level_agreement = get_active_service_level_agreement_for(
            priority=priority,
            customer=self.customer,
            service_level_agreement=service_level_agreement)

        if not service_level_agreement:
            if frappe.db.get_value("Issue", self.name,
                                   "service_level_agreement"):
                frappe.throw(
                    _("Couldn't Set Service Level Agreement {0}.".format(
                        self.service_level_agreement)))
            return

        if (service_level_agreement.customer and self.customer
            ) and not (service_level_agreement.customer == self.customer):
            frappe.throw(
                _("This Service Level Agreement is specific to Customer {0}".
                  format(service_level_agreement.customer)))

        self.service_level_agreement = service_level_agreement.name
        self.priority = service_level_agreement.default_priority if not priority else priority

        service_level_agreement = frappe.get_doc("Service Level Agreement",
                                                 service_level_agreement.name)
        priority = service_level_agreement.get_service_level_agreement_priority(
            self.priority)
        priority.update({
            "support_and_resolution":
            service_level_agreement.support_and_resolution,
            "holiday_list": service_level_agreement.holiday_list
        })

        if not self.creation:
            self.creation = now_datetime()
            self.service_level_agreement_creation = now_datetime()

        start_date_time = get_datetime(self.service_level_agreement_creation)
        self.response_by = get_expected_time_for(
            parameter='response',
            service_level=priority,
            start_date_time=start_date_time)
        self.resolution_by = get_expected_time_for(
            parameter='resolution',
            service_level=priority,
            start_date_time=start_date_time)

        self.response_by_variance = round(
            time_diff_in_hours(self.response_by, now_datetime()))
        self.resolution_by_variance = round(
            time_diff_in_hours(self.resolution_by, now_datetime()))
Пример #9
0
def validate_due_date(doc):
	# get the time limit for the role from escalation settings
	if doc.status == "Closed":
		return

	now = get_datetime().now()
	datetime_str = "{date} {time}".format(date=doc.date, time=doc.due_time)

	datetime_str = datetime.strptime(datetime_str.split(".")[0], "%Y-%m-%d %H:%M:%S").strftime("%Y-%m-%d %H:%M:%S")
	now_str = now.strftime("%Y-%m-%d %H:%M:%S")

	if time_diff_in_hours(datetime_str, now_str) < 0:
		frappe.throw("Can not assign past date")

	creation = datetime.strptime(doc.creation, "%Y-%m-%d %H:%M:%S.%f")

	if creation.replace(microsecond=0) == now.replace(microsecond=0):
		# current user highest role in doc.role
		if doc.assigned_by == frappe.session.user:
			doc.role = get_highest_role(frappe.session.user)
			doc.assigned_to_role = get_highest_role(doc.owner)
		else:
			doc.role = get_highest_role(doc.assigned_by)
			doc.assigned_to_role = get_highest_role(doc.owner)

	query = """	SELECT
				    er.time
				FROM
				    `tabTicket Escalation Settings Record` AS er
				JOIN
				    `tabTicket Escalation Settings` AS tes
				ON
				    er.parent=tes.name
				AND er.role='%s'
				AND tes.is_default=1"""%(doc.role or "Administrator")

	result = frappe.db.sql(query, as_dict=True)
	if not result:
		frappe.throw("Can not find the Role in Escalation Settings")
	else:
		time = result[0].get("time")
		if creation.replace(microsecond=0) == now.replace(microsecond=0):
			due_dttm = now + timedelta(hours=time)
			doc.due_time = due_dttm.strftime("%H:%M:%S")
			doc.date = due_dttm.strftime("%Y-%m-%d ")
		else:
			datetime_str = "{date} {time}".format(date=doc.date, time=doc.due_time)
			time_diff = time_diff_in_hours(datetime_str, str(now))
			
			if time < time_diff:
				dttm = (now + timedelta(hours=time)).strftime("%d-%m-%Y %H:%M:%S")
				frappe.throw("Invalid Due Date and Time, Due Date & time shoud be : %s"%(dttm))
Пример #10
0
    def update_agreement_fulfilled_on_custom_status(self):
        """
			Update Agreement Fulfilled status using Custom Scripts for Custom Issue Status
		"""
        if not self.first_responded_on:  # first_responded_on set when first reply is sent to customer
            self.response_by_variance = round(
                time_diff_in_hours(self.response_by, now_datetime()), 2)

        if not self.resolution_date:  # resolution_date set when issue has been closed
            self.resolution_by_variance = round(
                time_diff_in_hours(self.resolution_by, now_datetime()), 2)

        self.agreement_fulfilled = "Fulfilled" if self.response_by_variance > 0 and self.resolution_by_variance > 0 else "Failed"
Пример #11
0
def validate(doc, method):
    # frappe.errprint("validate")
    latest = doc
    row = None
    if len(latest.time_logs) == 0:
        row = latest.append("time_logs", {})
    else:
        row = latest.time_logs[0]
    row.from_time = latest.from_date
    row.to_time = latest.to_date
    row.hours = time_diff_in_hours(row.to_time, row.from_time)
    row.project = latest.project
    row.task = latest.task
    row.activity_type = latest.activity

    if latest.billable:
        row.billable = True
        row.billing_hours = row.hours

    else:
        row.billable = False
        row.billing_hours = 0
    rate = get_activity_cost(doc.employee, doc.activity)
    row.billing_rate = rate.billing_rate
    row.costing_rate = rate.costing_rate
    latest.validate()
Пример #12
0
    def validate_time_logs(self):
        self.total_completed_qty = 0.0
        self.total_time_in_mins = 0.0

        if self.get('time_logs'):
            for d in self.get('time_logs'):
                if get_datetime(d.from_time) > get_datetime(d.to_time):
                    frappe.throw(
                        _("Row {0}: From time must be less than to time").
                        format(d.idx))

                if not frappe.db.get_single_value(
                        "Projects Settings",
                        "ignore_workstation_time_overlap"):
                    data = self.get_overlap_for(d)
                    if data:
                        frappe.throw(
                            _("Row {0}: From Time and To Time of {1} is overlapping with {2}"
                              ).format(d.idx, self.name, data.name))

                if d.from_time and d.to_time:
                    d.time_in_mins = time_diff_in_hours(
                        d.to_time, d.from_time) * 60
                    self.total_time_in_mins += d.time_in_mins

                if d.completed_qty:
                    self.total_completed_qty += d.completed_qty
Пример #13
0
    def validate_time_logs(self):
        self.total_completed_qty = 0.0
        self.total_time_in_mins = 0.0

        if self.get('time_logs'):
            for d in self.get('time_logs'):
                if not d.pre_planning:
                    if get_datetime(d.from_time) > get_datetime(d.to_time):
                        frappe.throw(
                            _("Row {0}: From time must be less than to time").
                            format(d.idx))

                    data = self.get_overlap_for(d)
                    if data:
                        frappe.throw(
                            _("Row {0}: From Time and To Time of {1} is overlapping with {2}"
                              ).format(d.idx, self.name, data.name),
                            OverlapError)

                    if d.from_time and d.to_time:
                        d.time_in_mins = time_diff_in_hours(
                            d.to_time, d.from_time) * 60
                        self.total_time_in_mins += d.time_in_mins

                if d.completed_qty:
                    self.total_completed_qty += d.completed_qty
Пример #14
0
    def validate_time_logs(self):
        self.total_time_in_mins = 0.0
        self.total_completed_qty = 0.0

        if self.get("time_logs"):
            for d in self.get("time_logs"):
                if d.to_time and get_datetime(d.from_time) > get_datetime(
                        d.to_time):
                    frappe.throw(
                        _("Row {0}: From time must be less than to time").
                        format(d.idx))

                data = self.get_overlap_for(d)
                if data:
                    frappe.throw(
                        _("Row {0}: From Time and To Time of {1} is overlapping with {2}"
                          ).format(d.idx, self.name, data.name),
                        OverlapError,
                    )

                if d.from_time and d.to_time:
                    d.time_in_mins = time_diff_in_hours(
                        d.to_time, d.from_time) * 60
                    self.total_time_in_mins += d.time_in_mins

                if d.completed_qty and not self.sub_operations:
                    self.total_completed_qty += d.completed_qty

            self.total_completed_qty = flt(
                self.total_completed_qty,
                self.precision("total_completed_qty"))

        for row in self.sub_operations:
            self.total_completed_qty += row.completed_qty
Пример #15
0
def get_shifts():
    today = calendar.day_name[getdate(frappe.utils.today()).weekday()]
    data = frappe.db.sql(
        'select employee,department,designation,emp.work_shift,cast(concat(CURDATE(), " ", dsh.start_work) as datetime) as start,cast(concat(CURDATE(), " ", dsh.end_work) as datetime) as end,day from `tabEmployee Employment Detail` as emp join `tabWork Shift Details` as dsh on emp.work_shift=dsh.parent where day=%s',
        today,
        as_dict=1)
    for emp in data:
        hrs_diff = time_diff_in_hours(emp.end, emp.start)
        progress = 100
        wname = emp.employee + today
        if not frappe.db.get_value("Work Shifts Management", {"name": wname}):
            doc = frappe.new_doc('Work Shifts Management')
            doc.update({
                'name': wname,
                'employee': emp.employee,
                'department': emp.department,
                'designation': emp.designation,
                'work_shift': emp.work_shift,
                'day': today,
                'hours': hrs_diff,
                'progress': progress,
                'start_hour': emp.start,
                'end_hour': emp.end
            })
            doc.insert(ignore_permissions=True)
	def test_make_time_log(self):
		prod_order = make_prod_order_test_record(item="_Test FG Item 2",
			planned_start_date="2014-11-25 00:00:00", qty=1, do_not_save=True)

		prod_order.set_production_order_operations()
		prod_order.insert()
		prod_order.submit()

		d = prod_order.operations[0]

		d.completed_qty = flt(d.completed_qty)

		time_log = make_time_log(prod_order.name, d.operation, \
			d.planned_start_time, d.planned_end_time, prod_order.qty - d.completed_qty,
			operation_id=d.name)

		self.assertEqual(prod_order.name, time_log.production_order)
		self.assertEqual((prod_order.qty - d.completed_qty), time_log.completed_qty)
		self.assertEqual(time_diff_in_hours(d.planned_end_time, d.planned_start_time),time_log.hours)

		time_log.save()
		time_log.submit()

		manufacturing_settings = frappe.get_doc({
			"doctype": "Manufacturing Settings",
			"allow_production_on_holidays": 0
		})

		manufacturing_settings.save()

		prod_order.load_from_db()
		self.assertEqual(prod_order.operations[0].status, "Completed")
		self.assertEqual(prod_order.operations[0].completed_qty, prod_order.qty)

		self.assertEqual(get_datetime(prod_order.operations[0].actual_start_time),
			get_datetime(time_log.from_time))
		self.assertEqual(get_datetime(prod_order.operations[0].actual_end_time),
			get_datetime(time_log.to_time))

		self.assertEqual(prod_order.operations[0].actual_operation_time, 60)
		self.assertEqual(prod_order.operations[0].actual_operating_cost, 100)

		time_log.cancel()

		prod_order.load_from_db()
		self.assertEqual(prod_order.operations[0].status, "Pending")
		self.assertEqual(flt(prod_order.operations[0].completed_qty), 0)

		self.assertEqual(flt(prod_order.operations[0].actual_operation_time), 0)
		self.assertEqual(flt(prod_order.operations[0].actual_operating_cost), 0)

		time_log2 = frappe.copy_doc(time_log)
		time_log2.update({
			"completed_qty": 10,
			"from_time": "2014-11-26 00:00:00",
			"to_time": "2014-11-26 00:00:00",
			"docstatus": 0
		})
		self.assertRaises(OverProductionLoggedError, time_log2.save)
Пример #17
0
def get_billable_and_total_duration(activity, start_time, end_time):
	activity_duration = time_diff_in_hours(end_time, start_time)
	billing_duration = 0.0
	if activity.billable:
		billing_duration = activity.billing_hours
		if activity_duration != activity.billing_hours:
			billing_duration = activity_duration * activity.billing_hours / activity.hours

	return flt(activity_duration, 2), flt(billing_duration, 2)
Пример #18
0
def get_billable_and_total_duration(activity, start_time, end_time):
    activity_duration = time_diff_in_hours(end_time, start_time)
    billing_duration = 0.0
    if activity.billable:
        billing_duration = activity.billing_hours
        if activity_duration != activity.billing_hours:
            billing_duration = activity_duration * activity.billing_hours / activity.hours

    return flt(activity_duration, 2), flt(billing_duration, 2)
Пример #19
0
	def calculate_std_hours(self):
		std_working_hours = frappe.get_value("Company", self.company, 'standard_working_hours')

		for time in self.time_logs:
			if time.from_time and time.to_time:
				if flt(std_working_hours) > 0:
					time.hours = flt(std_working_hours) * date_diff(time.to_time, time.from_time)
				else:
					if not time.hours:
						time.hours = time_diff_in_hours(time.to_time, time.from_time)
Пример #20
0
def get_billable_and_total_duration(activity, start_time, end_time):
    precision = frappe.get_precision("Timesheet Detail", "hours")
    activity_duration = time_diff_in_hours(end_time, start_time)
    billing_duration = 0.0
    if activity.billable:
        billing_duration = activity.billing_hours
        if activity_duration != activity.billing_hours:
            billing_duration = activity_duration * activity.billing_hours / activity.hours

    return flt(activity_duration, precision), flt(billing_duration, precision)
Пример #21
0
def validate_attendance(self, method):
	if self.in_time > self.out_time:
		frappe.throw(_("Out time should be greater than in time"))
	time_diff_hours = time_diff_in_hours(self.out_time, self.in_time)
	if self.status in ["Present", "Half Day"]:
		if time_diff_hours >= 8:
			self.status = "Present"
		elif (time_diff_hours >= 4 and time_diff_hours < 8):
			self.status = "Half Day"
		else:
			frappe.throw(_("To mark attendance as Present or Half Day, hours should be greater than or equal to 4"))
def shift_type_validate(doc, method):
    if get_datetime(doc.end_time) > get_datetime(doc.start_time):
        time_diff = time_diff_in_hours(doc.end_time, doc.start_time)
        doc.total_hours = time_diff
    else:
        time_start_str = '23:59:59'
        time_start_obj = datetime.strptime(time_start_str, '%H:%M:%S')
        shift_start = time_start_obj.time()
        start_time = time_diff_in_hours(str(shift_start), doc.start_time)

        time_end_str = '00:00:00'
        time_end_obj = datetime.strptime(time_end_str, '%H:%M:%S')
        shift_end = time_end_obj.time()
        end_time = time_diff_in_hours(doc.end_time, str(shift_end))
        time_diff = end_time + start_time

        doc.total_hours = time_diff

    doc.total_hours = int(doc.total_hours) + \
        (doc.total_hours-int(doc.total_hours))*0.60
def get_leagend(start, end):
	time_diff = time_diff_in_hours(end, start)
	if time_diff <= 24.0:
		return "Winthin 1 day"
	elif time_diff <= 72.0:
		return "2-3 days"
	elif time_diff <= 120.0:
		return "3-5 days"
	elif time_diff <= 168.0:
		return "5-7 days"
	else:
		return "more than 7 days"
Пример #24
0
def get_ip_services_to_invoice(patient, company):
    services_to_invoice = []
    ip_services = frappe.db.sql('''
			SELECT
				ips.*
			FROM
				`tabInpatient Record` ip, `tabIP Services` ips
			WHERE
				ip.patient=%s
				and ip.company=%s
				and ips.parent=ip.name
				and ips.stopped=1
				and ips.invoiced=0
		''', (patient.name, company),
                                as_dict=1)

    for ip_service in ip_services:
        service_type = frappe.get_cached_doc('InPatient Service',
                                             ip_service.inpatient_service)
        if service_type and service_type.is_billable:
            if service_type.uom == 'Nos':
                if service_type.uom_per_day > 0:
                    days_used = date_diff(ip_service.end_date,
                                          ip_service.start_date) + 1
                    qty = service_type.uom_per_day * days_used
                else:
                    qty = ip_service.qty
            else:
                hours_occupied = time_diff_in_hours(ip_service.end_date,
                                                    ip_service.start_date)
                qty = 0.5
                if hours_occupied > 0:
                    actual_qty = hours_occupied / service_type.no_of_hours
                    floor = math.floor(actual_qty)
                    decimal_part = actual_qty - floor
                    if decimal_part > 0.5:
                        qty = rounded(floor + 1, 1)
                    elif decimal_part < 0.5 and decimal_part > 0:
                        qty = rounded(floor + 0.5, 1)
                    elif decimal_part == 0:
                        qty = floor
                    if qty <= 0:
                        qty = 0.5

            services_to_invoice.append({
                'reference_type': 'IP Services',
                'reference_name': ip_service.name,
                'service': service_type.item,
                'qty': qty
            })

    return services_to_invoice
Пример #25
0
def get_emp_work_shift(employee, day):
    emp_wshift = frappe.db.get_value("Employee", employee, "work_shift")
    if emp_wshift:
        employee_start_time = frappe.db.get_value("Work Shift Details", {
            "parent": emp_wshift,
            "day": day
        }, "start_work")
        employee_end_time = frappe.db.get_value("Work Shift Details", {
            "parent": emp_wshift,
            "day": day
        }, "end_work")
        shift_hrs = time_diff_in_hours(employee_end_time, employee_start_time)
        return shift_hrs
Пример #26
0
def daily_notifications():
    """
        sent notifications to user if 
        1 : ticket is open for more than 24 hrs
        2 : ticket is assigned but not Closed in 24 hrs
    """
    tickets = frappe.db.get_all("Ticket Escalation History",
                                filters=[["status", "!=", "Closed"],
                                         ["status", "!=", "Deleted"]],
                                fields=["*"])
    for ticket in tickets:
        # ticket is raised but not yet assigned
        issue_doc = frappe.get_doc("Issue", ticket.ticket_id)
        args = {
            "user": get_fullname(issue_doc.raised_by) or "User",
            "email": issue_doc.raised_by,
            "action": "user_issue_notification",
            "issue": issue_doc
        }
        if ticket.raised_email_notification and not ticket.assigned_email_notification:
            raised_time = ticket.raised_email_notification_datetime
            if time_diff_in_hours(get_datetime().now(), raised_time) >= 24:
                # send user notification mail
                msg = "Your support ticket {ticket_id} is pending our representative will \
                check the issue as soon as possible".format(
                    ticket_id=ticket.ticket_id)

                args.update({"msg": msg})
                send_mail(args, "[HelpDesk] Daily Notifications")
        elif ticket.assigned_email_notification and not ticket.status_closed_email_notification:
            assigned_time = ticket.assigned_email_notification_datetime
            if time_diff_in_hours(get_datetime().now(), assigned_time) >= 24:
                # send the user notification mail
                msg = "Your support ticket {ticket_id} is assigned to our support representative \
                and issue will be solved as soon as possble".format(
                    ticket_id=ticket.ticket_id)

                args.update({"msg": msg})
                send_mail(args, "[HelpDesk] Daily Notifications")
Пример #27
0
	def set_minimum_reposting_time_slot(self):
		"""Ensure that timeslot for reposting is at least 12 hours."""
		if not self.limit_reposting_timeslot:
			return

		start_time = get_datetime(self.start_time)
		end_time = get_datetime(self.end_time)

		if start_time > end_time:
			end_time = add_to_date(end_time, days=1, as_datetime=True)

		diff = time_diff_in_hours(end_time, start_time)

		if diff < 10:
			self.end_time = get_time_str(add_to_date(self.start_time, hours=10, as_datetime=True))
Пример #28
0
def execute_pos_invoices():
    make_closing_entry()
    last_execution_time = frappe.db.get_single_value('POS Process Settings', 'last_execution_time')
    enabled = frappe.db.get_single_value('POS Process Settings', 'enabled')
    execution_interval = 5  # set Interval
    if enabled:
        hours = time_diff_in_hours(now_datetime(), last_execution_time)
        execution_interval = frappe.db.get_single_value('POS Process Settings', 'execution_interval')
        if hours >= execution_interval:
            check_before_exe_time_pos_invoices(last_execution_time)
            settings = frappe.get_single("POS Process Settings")
            settings.last_execution_time = now_datetime()
            settings.save()
    pos_profiles = frappe.get_list("POS Profile", filters={"disabled": 0}, fields=["name"], order_by="creation")
    for res in pos_profiles:
        make_opening_entry(res.name)
Пример #29
0
def check_for_open_support_tickets(records, esc_setting):
    open_tickets = []
    time = 0

    for record in records:
        opening_date = record.get("opening_date")
        opening_time = record.get("opening_time")
        datetime_str = "{date} {time}".format(date=opening_date, time=opening_time)
        now = str(get_datetime().now())
        
        time = get_time_difference(esc_setting)
        
        if time_diff_in_hours(now, datetime_str) >= time or 2:
            open_tickets.append(record.get("ticket_id"))

    return open_tickets
Пример #30
0
 def validate(self):
     # self.validate_reel_size()
     if self.scrap_weight_approved:
         if not self.approved_by:
             self.approved_by = frappe.session.user
     else:
         self.approved_by = ""
     if self.all_weight_approved:
         if not self.all_weight_approved_by:
             self.all_weight_approved_by = frappe.session.user
     else:
         self.all_weight_approved_by = ""
     self.manage_reel()
     if self.end_dt and self.start_dt:
         hours = time_diff_in_hours(self.end_dt, self.start_dt)
         frappe.db.set(self, 'operation_hours', hours)
	def test_make_time_log(self):
		from erpnext.projects.doctype.time_log.test_time_log import make_time_log_test_record
		prod_order = make_prod_order_test_record(item="_Test FG Item 2",
			planned_start_date=now(), qty=1, do_not_save=True)

		prod_order.set_production_order_operations()
		prod_order.insert()
		prod_order.submit()

		d = prod_order.operations[0]

		d.completed_qty = flt(d.completed_qty)

		time_log = make_time_log_test_record(hours=1, production_order= prod_order.name, operation= d.operation,
			completed_qty= prod_order.qty - d.completed_qty, operation_id=d.name, for_manufacturing=1, simulate=True)

		self.assertEqual(prod_order.name, time_log.production_order)
		self.assertEqual((prod_order.qty - d.completed_qty), time_log.completed_qty)
		self.assertEqual(time_diff_in_hours(d.planned_end_time, d.planned_start_time),time_log.hours)
		
		manufacturing_settings = frappe.get_doc({
			"doctype": "Manufacturing Settings",
			"allow_production_on_holidays": 0
		})

		manufacturing_settings.save()

		prod_order.load_from_db()
		self.assertEqual(prod_order.operations[0].status, "Completed")
		self.assertEqual(prod_order.operations[0].completed_qty, prod_order.qty)

		self.assertEqual(prod_order.operations[0].actual_operation_time, 60)
		self.assertEqual(prod_order.operations[0].actual_operating_cost, 100)

		time_log.cancel()

		prod_order.load_from_db()
		self.assertEqual(prod_order.operations[0].status, "Pending")
		self.assertEqual(flt(prod_order.operations[0].completed_qty), 0)

		self.assertEqual(flt(prod_order.operations[0].actual_operation_time), 0)
		self.assertEqual(flt(prod_order.operations[0].actual_operating_cost), 0)

		time_log2 = make_time_log_test_record(from_time= add_days(time_log.to_time, 1) ,production_order= prod_order.name, operation= d.operation,
			completed_qty= 5, operation_id=d.name, for_manufacturing=1, do_not_save=True)

		self.assertRaises(OverProductionLoggedError, time_log2.save)
Пример #32
0
def get_inpatient_services_to_invoice(patient, company):
    services_to_invoice = []
    inpatient_services = frappe.db.sql(
        """
			SELECT
				io.*
			FROM
				`tabInpatient Record` ip, `tabInpatient Occupancy` io
			WHERE
				ip.patient=%s
				and ip.company=%s
				and io.parent=ip.name
				and io.left=1
				and io.invoiced=0
		""",
        (patient.name, company),
        as_dict=1,
    )

    for inpatient_occupancy in inpatient_services:
        service_unit_type = frappe.db.get_value(
            "Healthcare Service Unit", inpatient_occupancy.service_unit,
            "service_unit_type")
        service_unit_type = frappe.get_cached_doc(
            "Healthcare Service Unit Type", service_unit_type)
        if service_unit_type and service_unit_type.is_billable:
            hours_occupied = time_diff_in_hours(inpatient_occupancy.check_out,
                                                inpatient_occupancy.check_in)
            qty = 0.5
            if hours_occupied > 0:
                actual_qty = hours_occupied / service_unit_type.no_of_hours
                floor = math.floor(actual_qty)
                decimal_part = actual_qty - floor
                if decimal_part > 0.5:
                    qty = rounded(floor + 1, 1)
                elif decimal_part < 0.5 and decimal_part > 0:
                    qty = rounded(floor + 0.5, 1)
                if qty <= 0:
                    qty = 0.5
            services_to_invoice.append({
                "reference_type": "Inpatient Occupancy",
                "reference_name": inpatient_occupancy.name,
                "service": service_unit_type.item,
                "qty": qty,
            })

    return services_to_invoice
Пример #33
0
	def test_make_time_log(self):
		from erpnext.projects.doctype.time_log.test_time_log import make_time_log_test_record
		prod_order = make_prod_order_test_record(item="_Test FG Item 2",
			planned_start_date=now(), qty=1, do_not_save=True)

		prod_order.set_production_order_operations()
		prod_order.insert()
		prod_order.submit()

		d = prod_order.operations[0]

		d.completed_qty = flt(d.completed_qty)

		time_log = make_time_log_test_record(hours=1, production_order= prod_order.name, operation= d.operation,
			completed_qty= prod_order.qty - d.completed_qty, operation_id=d.name, for_manufacturing=1, simulate=True)

		self.assertEqual(prod_order.name, time_log.production_order)
		self.assertEqual((prod_order.qty - d.completed_qty), time_log.completed_qty)
		self.assertEqual(time_diff_in_hours(d.planned_end_time, d.planned_start_time),time_log.hours)

		manufacturing_settings = frappe.get_doc({
			"doctype": "Manufacturing Settings",
			"allow_production_on_holidays": 0
		})

		manufacturing_settings.save()

		prod_order.load_from_db()
		self.assertEqual(prod_order.operations[0].status, "Completed")
		self.assertEqual(prod_order.operations[0].completed_qty, prod_order.qty)

		self.assertEqual(prod_order.operations[0].actual_operation_time, 60)
		self.assertEqual(prod_order.operations[0].actual_operating_cost, 100)

		time_log.cancel()

		prod_order.load_from_db()
		self.assertEqual(prod_order.operations[0].status, "Pending")
		self.assertEqual(flt(prod_order.operations[0].completed_qty), 0)

		self.assertEqual(flt(prod_order.operations[0].actual_operation_time), 0)
		self.assertEqual(flt(prod_order.operations[0].actual_operating_cost), 0)

		time_log2 = make_time_log_test_record(from_time= add_days(time_log.to_time, 1) ,production_order= prod_order.name, operation= d.operation,
			completed_qty= 5, operation_id=d.name, for_manufacturing=1, do_not_save=True)

		self.assertRaises(OverProductionLoggedError, time_log2.save)
Пример #34
0
def check_for_open_support_tickets(records, esc_setting):
    open_tickets = []
    time = 0

    for record in records:
        opening_date = record.get("opening_date")
        opening_time = record.get("opening_time")
        datetime_str = "{date} {time}".format(date=opening_date,
                                              time=opening_time)
        now = str(get_datetime().now())

        time = get_time_difference(esc_setting)

        if time_diff_in_hours(now, datetime_str) >= time or 2:
            open_tickets.append(record.get("ticket_id"))

    return open_tickets
Пример #35
0
def check_and_escalate_assigned_tickets(records, esc_setting):
    time = 0
    rec_cant_be_escalate = {}

    for record in records:
        datetime_str = record.get("assigned_on")
        now = str(get_datetime().now())
        time = get_time_difference(esc_setting, record.get("current_role")) or 2

        if time_diff_in_hours(now, datetime_str) >= time:
            ch_entry = esc_setting.escalation_hierarchy
            if record.current_role in [ch.role for ch in ch_entry[:2]]:
                key = frappe.db.get_value("Issue", record.get("ticket_id"), "department")
                val = rec_cant_be_escalate.get("department").append(record) if rec_cant_be_escalate.get("department") else [record]
                rec_cant_be_escalate.update({
                    key: val,
                })
            else:
                escalate_ticket_to_higher_authority(esc_setting, record)
Пример #36
0
 def validate_total_hours(self):
     lenof = len(self.punching)
     if lenof >= 1:
         punch_in = [
             i.punch_time for i in self.punching
             if i.punch_in_out == 'Punch In'
         ]
         punch_out = [
             i.punch_time for i in self.punching
             if i.punch_in_out == 'Punch Out'
         ]
         if len(punch_in) != len(punch_out):
             punch_in.pop()
         differences = [
             time_diff_in_hours(y, x) for x, y in zip(punch_in, punch_out)
         ]
         self.total_hours = round(sum(differences), 2)
     else:
         self.total_hours = 0
Пример #37
0
	def set_se_items_finish(self, se):
		#set from and to warehouse

		se.to_warehouse = self.to_warehouse
		se.from_warehouse = self.source_warehouse

		#TODO allow multiple raw material transfer
		raw_material_cost = 0
		operating_cost = 0
		
		#TODO calc raw_material_cost

		#no timesheet entries, calculate operating cost based on workstation hourly rate and process start, end
		hourly_rate = None
		# hourly_rate = frappe.db.get_value("Workstation", self.workstation, "hour_rate")
		if hourly_rate:
			if self.operation_hours > 0:
				hours = self.operation_hours
			else:
				hours = time_diff_in_hours(self.end_dt, self.start_dt)
				frappe.db.set(self, 'operation_hours', hours)
			operating_cost = hours * float(hourly_rate)
		production_cost = raw_material_cost + operating_cost

		#calc total_qty and total_sale_value
		qty_of_total_production = 0
		total_sale_value = 0
		
		qty_of_total_production = float(qty_of_total_production) + float(self.total_stock)
		
		#add carton to stock entry
		cartons = {}
		for row in self.carton_data:
			if row.carton_item:
				count = cartons.get(row.carton_item, 0)
				cartons.update({row.carton_item:(count + 1)})
		for data in cartons:
			se = self.set_se_items(se, data, None, se.from_warehouse, True, qty_of_total_production, total_sale_value, production_cost, raw_material = cartons[data])

		#add paper cup item to stockentry
		se = self.set_se_items(se, self.item, se.to_warehouse, None, True, qty_of_total_production, total_sale_value, production_cost)
		return se
Пример #38
0
def check_and_escalate_assigned_tickets(records, esc_setting):
    time = 0
    rec_cant_be_escalate = {}

    for record in records:
        datetime_str = record.get("assigned_on")
        now = str(get_datetime().now())
        time = get_time_difference(esc_setting, record.get("current_role")) or 2

        if time_diff_in_hours(now, datetime_str) >= time:
            ch_entry = esc_setting.escalation_hierarchy
            if record.current_role in [ch.role for ch in ch_entry[:2]]:
                key = frappe.db.get_value("Issue", record.get("ticket_id"), "department")
                val = rec_cant_be_escalate.get("department").append(record) if rec_cant_be_escalate.get("department") else [record]
                rec_cant_be_escalate.update({
                    key: val,
                })
            else:
                escalate_ticket_to_higher_authority(esc_setting, record)

    if rec_cant_be_escalate:
        args = get_tickets_details_that_cant_be_escalate(rec_cant_be_escalate)
        for dept_head, mail_args in args.iteritems():
            send_mail(mail_args, "[HelpDesk][Open Tickets] HelpDesk Notifications")
Пример #39
0
	def calculate_total_hours(self):
		from frappe.utils import time_diff_in_hours
		self.hours = time_diff_in_hours(self.to_time, self.from_time)
	def test_make_time_log(self):
		from erpnext.manufacturing.doctype.production_order.production_order import make_time_log
		from frappe.utils import cstr
		from frappe.utils import time_diff_in_hours

		prod_order = frappe.get_doc({
			"doctype": "Production Order",
			"production_item": "_Test FG Item 2",
			"bom_no": "BOM/_Test FG Item 2/001",
			"qty": 1,
			"wip_warehouse": "_Test Warehouse - _TC",
			"fg_warehouse": "_Test Warehouse 1 - _TC",
			"company": "_Test Company",
			"planned_start_date": "2014-11-25 00:00:00"
		})

		prod_order.set_production_order_operations()
		prod_order.insert()
		prod_order.submit()
		d = prod_order.operations[0]

		d.completed_qty = flt(d.completed_qty)

		time_log = make_time_log(prod_order.name, cstr(d.idx) + ". " + d.operation, \
			d.planned_start_time, d.planned_end_time, prod_order.qty - d.completed_qty,
			operation_id=d.name)

		self.assertEqual(prod_order.name, time_log.production_order)
		self.assertEqual((prod_order.qty - d.completed_qty), time_log.completed_qty)
		self.assertEqual(time_diff_in_hours(d.planned_end_time, d.planned_start_time),time_log.hours)

		time_log.save()
		time_log.submit()

		manufacturing_settings = frappe.get_doc({
			"doctype": "Manufacturing Settings",
			"allow_production_on_holidays": 0
		})

		manufacturing_settings.save()

		prod_order.load_from_db()
		self.assertEqual(prod_order.operations[0].status, "Completed")
		self.assertEqual(prod_order.operations[0].completed_qty, prod_order.qty)

		self.assertEqual(get_datetime(prod_order.operations[0].actual_start_time), get_datetime(time_log.from_time))
		self.assertEqual(get_datetime(prod_order.operations[0].actual_end_time), get_datetime(time_log.to_time))

		self.assertEqual(prod_order.operations[0].actual_operation_time, 60)
		self.assertEqual(prod_order.operations[0].actual_operating_cost, 100)

		time_log.cancel()

		prod_order.load_from_db()
		self.assertEqual(prod_order.operations[0].status, "Pending")
		self.assertEqual(flt(prod_order.operations[0].completed_qty), 0)

		self.assertEqual(flt(prod_order.operations[0].actual_operation_time), 0)
		self.assertEqual(flt(prod_order.operations[0].actual_operating_cost), 0)

		time_log2 = frappe.copy_doc(time_log)
		time_log2.update({
			"completed_qty": 10,
			"from_time": "2014-11-26 00:00:00",
			"to_time": "2014-11-26 00:00:00",
			"docstatus": 0
		})
		self.assertRaises(OverProductionLoggedError, time_log2.save)
Пример #41
0
def get_billable_and_total_hours(activity, end, start, total_hours, total_billable_hours, total_amount):
	total_hours += abs(time_diff_in_hours(end, start))
	if activity.billable:
		total_billable_hours += abs(time_diff_in_hours(end, start))
		total_amount += total_billable_hours * activity.billing_rate
	return total_hours, total_billable_hours, total_amount
Пример #42
0
	def validate_dates(self):
		for data in self.time_logs:
			if data.from_time and data.to_time and time_diff_in_hours(data.to_time, data.from_time) < 0:
				frappe.throw(_("To date cannot be before from date"))
Пример #43
0
def get_downtime(failure_date, completion_date):
	downtime = time_diff_in_hours(completion_date, failure_date)
	return round(downtime, 2)
Пример #44
0
def get_healthcare_services_to_invoice(patient):
	patient = frappe.get_doc("Patient", patient)
	if patient:
		if patient.customer:
			item_to_invoice = []
			patient_appointments = frappe.get_list("Patient Appointment",{'patient': patient.name, 'invoiced': False},
			order_by="appointment_date")
			if patient_appointments:
				fee_validity_details = []
				valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
				max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
				for patient_appointment in patient_appointments:
					patient_appointment_obj = frappe.get_doc("Patient Appointment", patient_appointment['name'])

					if patient_appointment_obj.procedure_template:
						if frappe.db.get_value("Clinical Procedure Template", patient_appointment_obj.procedure_template, "is_billable") == 1:
							item_to_invoice.append({'reference_type': 'Patient Appointment', 'reference_name': patient_appointment_obj.name, 'service': patient_appointment_obj.procedure_template})
					else:
						practitioner_exist_in_list = False
						skip_invoice = False
						if fee_validity_details:
							for validity in fee_validity_details:
								if validity['practitioner'] == patient_appointment_obj.practitioner:
									practitioner_exist_in_list = True
									if validity['valid_till'] >= patient_appointment_obj.appointment_date:
										validity['visits'] = validity['visits']+1
										if int(max_visit) > validity['visits']:
											skip_invoice = True
									if not skip_invoice:
										validity['visits'] = 1
										validity['valid_till'] = patient_appointment_obj.appointment_date + datetime.timedelta(days=int(valid_days))
						if not practitioner_exist_in_list:
							valid_till = patient_appointment_obj.appointment_date + datetime.timedelta(days=int(valid_days))
							visits = 0
							validity_exist = validity_exists(patient_appointment_obj.practitioner, patient_appointment_obj.patient)
							if validity_exist:
								fee_validity = frappe.get_doc("Fee Validity", validity_exist[0][0])
								valid_till = fee_validity.valid_till
								visits = fee_validity.visited
							fee_validity_details.append({'practitioner': patient_appointment_obj.practitioner,
							'valid_till': valid_till, 'visits': visits})

						if not skip_invoice:
							practitioner_charge = 0
							income_account = None
							service_item = None
							if patient_appointment_obj.practitioner:
								service_item, practitioner_charge = service_item_and_practitioner_charge(patient_appointment_obj)
								income_account = get_income_account(patient_appointment_obj.practitioner, patient_appointment_obj.company)
							item_to_invoice.append({'reference_type': 'Patient Appointment', 'reference_name': patient_appointment_obj.name,
							'service': service_item, 'rate': practitioner_charge,
							'income_account': income_account})

			encounters = frappe.get_list("Patient Encounter", {'patient': patient.name, 'invoiced': False, 'docstatus': 1})
			if encounters:
				for encounter in encounters:
					encounter_obj = frappe.get_doc("Patient Encounter", encounter['name'])
					if not encounter_obj.appointment:
						practitioner_charge = 0
						income_account = None
						service_item = None
						if encounter_obj.practitioner:
							service_item, practitioner_charge = service_item_and_practitioner_charge(encounter_obj)
							income_account = get_income_account(encounter_obj.practitioner, encounter_obj.company)

						item_to_invoice.append({'reference_type': 'Patient Encounter', 'reference_name': encounter_obj.name,
						'service': service_item, 'rate': practitioner_charge,
						'income_account': income_account})

			lab_tests = frappe.get_list("Lab Test", {'patient': patient.name, 'invoiced': False})
			if lab_tests:
				for lab_test in lab_tests:
					lab_test_obj = frappe.get_doc("Lab Test", lab_test['name'])
					if frappe.db.get_value("Lab Test Template", lab_test_obj.template, "is_billable") == 1:
						item_to_invoice.append({'reference_type': 'Lab Test', 'reference_name': lab_test_obj.name,
						'service': frappe.db.get_value("Lab Test Template", lab_test_obj.template, "item")})

			lab_rxs = frappe.db.sql("""select lp.name from `tabPatient Encounter` et, `tabLab Prescription` lp
			where et.patient=%s and lp.parent=et.name and lp.lab_test_created=0 and lp.invoiced=0""", (patient.name))
			if lab_rxs:
				for lab_rx in lab_rxs:
					rx_obj = frappe.get_doc("Lab Prescription", lab_rx[0])
					if rx_obj.lab_test_code and (frappe.db.get_value("Lab Test Template", rx_obj.lab_test_code, "is_billable") == 1):
						item_to_invoice.append({'reference_type': 'Lab Prescription', 'reference_name': rx_obj.name,
						'service': frappe.db.get_value("Lab Test Template", rx_obj.lab_test_code, "item")})

			procedures = frappe.get_list("Clinical Procedure", {'patient': patient.name, 'invoiced': False})
			if procedures:
				for procedure in procedures:
					procedure_obj = frappe.get_doc("Clinical Procedure", procedure['name'])
					if not procedure_obj.appointment:
						if procedure_obj.procedure_template and (frappe.db.get_value("Clinical Procedure Template", procedure_obj.procedure_template, "is_billable") == 1):
							item_to_invoice.append({'reference_type': 'Clinical Procedure', 'reference_name': procedure_obj.name,
							'service': frappe.db.get_value("Clinical Procedure Template", procedure_obj.procedure_template, "item")})

			procedure_rxs = frappe.db.sql("""select pp.name from `tabPatient Encounter` et,
			`tabProcedure Prescription` pp where et.patient=%s and pp.parent=et.name and
			pp.procedure_created=0 and pp.invoiced=0 and pp.appointment_booked=0""", (patient.name))
			if procedure_rxs:
				for procedure_rx in procedure_rxs:
					rx_obj = frappe.get_doc("Procedure Prescription", procedure_rx[0])
					if frappe.db.get_value("Clinical Procedure Template", rx_obj.procedure, "is_billable") == 1:
						item_to_invoice.append({'reference_type': 'Procedure Prescription', 'reference_name': rx_obj.name,
						'service': frappe.db.get_value("Clinical Procedure Template", rx_obj.procedure, "item")})

			procedures = frappe.get_list("Clinical Procedure",
			{'patient': patient.name, 'invoice_separately_as_consumables': True, 'consumption_invoiced': False,
			'consume_stock': True, 'status': 'Completed'})
			if procedures:
				service_item = get_healthcare_service_item('clinical_procedure_consumable_item')
				if not service_item:
					msg = _(("Please Configure {0} in ").format("Clinical Procedure Consumable Item") \
						+ """<b><a href="#Form/Healthcare Settings">Healthcare Settings</a></b>""")
					frappe.throw(msg)
				for procedure in procedures:
					procedure_obj = frappe.get_doc("Clinical Procedure", procedure['name'])
					item_to_invoice.append({'reference_type': 'Clinical Procedure', 'reference_name': procedure_obj.name,
					'service': service_item, 'rate': procedure_obj.consumable_total_amount, 'description': procedure_obj.consumption_details})

			inpatient_services = frappe.db.sql("""select io.name, io.parent from `tabInpatient Record` ip,
			`tabInpatient Occupancy` io where ip.patient=%s and io.parent=ip.name and
			io.left=1 and io.invoiced=0""", (patient.name))
			if inpatient_services:
				for inpatient_service in inpatient_services:
					inpatient_occupancy = frappe.get_doc("Inpatient Occupancy", inpatient_service[0])
					service_unit_type = frappe.get_doc("Healthcare Service Unit Type", frappe.db.get_value("Healthcare Service Unit", inpatient_occupancy.service_unit, "service_unit_type"))
					if service_unit_type and service_unit_type.is_billable == 1:
						hours_occupied = time_diff_in_hours(inpatient_occupancy.check_out, inpatient_occupancy.check_in)
						qty = 0.5
						if hours_occupied > 0:
							actual_qty = hours_occupied / service_unit_type.no_of_hours
							floor = math.floor(actual_qty)
							decimal_part = actual_qty - floor
							if decimal_part > 0.5:
								qty = rounded(floor + 1, 1)
							elif decimal_part < 0.5 and decimal_part > 0:
								qty = rounded(floor + 0.5, 1)
							if qty <= 0:
								qty = 0.5
						item_to_invoice.append({'reference_type': 'Inpatient Occupancy', 'reference_name': inpatient_occupancy.name,
						'service': service_unit_type.item, 'qty': qty})

			return item_to_invoice
		else:
			frappe.throw(_("The Patient {0} do not have customer refrence to invoice").format(patient.name))
Пример #45
0
def check_follow_up_time(time, now):
	send_reminder = 0
	if 1 < (time_diff_in_hours(time, now)) < 2:
		send_reminder = 1
	return send_reminder
Пример #46
0
	def calculate_total_hours(self):
		from frappe.utils import time_diff_in_hours
		self.hours = time_diff_in_hours(self.to_time, self.from_time)
		if self.hours < 0:
			frappe.throw(_("'From Time' cannot be later than 'To Time'"))