def get_history_records(customer_agreement):
	total_transaction_amount = ""
	history_record_dict = frappe.db.sql("""select payment_id,due_date,payment_date,
											monthly_rental_amount,"balance" as balance,pmt,
											"asso" as associate, "late" as late_days,total_transaction_amount from `tabPayments Record`
											where parent ='{0}' and check_box_of_submit = 1 order by idx""".format(customer_agreement),as_dict=1)
	# balance = frappe.db.get_value("Customer Agreement",{"name":customer_agreement},"balance")
	agreement = frappe.get_doc("Customer Agreement",customer_agreement)
	balance = "{0:.2f}".format(float(agreement.agreement_period) * float(agreement.monthly_rental_payment))
	for i in history_record_dict:
		i['associate'] = frappe.session.user
		total_transaction_amount = i["total_transaction_amount"]
		i["total_transaction_amount"] = total_transaction_amount.split("/")[0] if total_transaction_amount else 0
		i["total_calculated_payment_amount"] = total_transaction_amount.split("/")[1]  if total_transaction_amount else 0
		if float(balance) > float(i["monthly_rental_amount"]):
			i["balance"] = "{0:.2f}".format(float(balance) - float(i['monthly_rental_amount']))
			balance = float(balance) - float(i['monthly_rental_amount'])
		if date_diff(i['payment_date'],i['due_date']) > 0:
			i["late_days"] = "+" + str(date_diff(i['payment_date'],i['due_date']))
		elif date_diff(i['payment_date'],i['due_date']) == 0:
			i["late_days"] = 0
		elif date_diff(i['payment_date'],i['due_date']) < 0:
			i["late_days"] = date_diff(i['payment_date'],i['due_date'])
	print history_record_dict,"history_record_dict history_record_dict","\n\n\n\n\n\n"		
	return history_record_dict
예제 #2
0
def execute(filters=None):

    columns = get_columns()
    item_details = get_fifo_queue(filters)
    to_date = filters["to_date"]
    data = []
    for item, item_dict in item_details.items():
        fifo_queue = item_dict["fifo_queue"]
        details = item_dict["details"]
        if not fifo_queue:
            continue

        average_age = get_average_age(fifo_queue, to_date)
        earliest_age = date_diff(to_date, fifo_queue[0][1])
        latest_age = date_diff(to_date, fifo_queue[-1][1])

        data.append(
            [
                item,
                details.item_name,
                details.description,
                details.item_group,
                details.brand,
                average_age,
                earliest_age,
                latest_age,
                details.stock_uom,
            ]
        )

    return columns, data
def execute(filters=None):

	columns = get_columns(filters)
	items, item_map = get_item_details(filters)
	item_details = get_fifo_queue(filters, items)
	to_date = filters["to_date"]
	data = []
	for item, item_dict in iteritems(item_details):
		fifo_queue = item_dict["fifo_queue"]
		details = item_dict["details"]
		if not fifo_queue: continue

		average_age = get_average_age(fifo_queue, to_date)
		earliest_age = date_diff(to_date, fifo_queue[0][1])
		latest_age = date_diff(to_date, fifo_queue[-1][1])
		item_detail_dict = item_map[details.name]
		row = [details.name, item_detail_dict["desc"]]

		if filters.get("show_ageing_warehouse_wise"):
			row.append(details.warehouse)

		row.extend([item_dict.get("total_qty"), average_age,
			earliest_age, latest_age,
			item_detail_dict["stock_uom"], item_detail_dict["rm"], item_detail_dict["bm"],
			item_detail_dict["tt"], item_detail_dict["brand"], item_detail_dict["quality"], item_detail_dict["spl"],
			item_detail_dict["d1"], item_detail_dict["w1"], item_detail_dict["l1"], item_detail_dict["d2"],
			item_detail_dict["l2"], item_detail_dict["zn"]])

		data.append(row)

	return columns, data
예제 #4
0
def validate_service_stop_date(doc):
	''' Validates service_stop_date for Purchase Invoice and Sales Invoice '''

	enable_check = "enable_deferred_revenue" \
		if doc.doctype=="Sales Invoice" else "enable_deferred_expense"

	old_stop_dates = {}
	old_doc = frappe.db.get_all("{0} Item".format(doc.doctype),
		{"parent": doc.name}, ["name", "service_stop_date"])

	for d in old_doc:
		old_stop_dates[d.name] = d.service_stop_date or ""

	for item in doc.items:
		if not item.get(enable_check): continue

		if item.service_stop_date:
			if date_diff(item.service_stop_date, item.service_start_date) < 0:
				frappe.throw(_("Service Stop Date cannot be before Service Start Date"))

			if date_diff(item.service_stop_date, item.service_end_date) > 0:
				frappe.throw(_("Service Stop Date cannot be after Service End Date"))

		if old_stop_dates and old_stop_dates.get(item.name) and item.service_stop_date!=old_stop_dates[item.name]:
			frappe.throw(_("Cannot change Service Stop Date for item in row {0}".format(item.idx)))
	def check_date_diff_of_first_and_second_month_due_date(self):
		due_date_of_next_month = datetime.strptime(self.due_date_of_next_month, '%Y-%m-%dT%H:%M:%S.%fZ') if isinstance(self.due_date_of_next_month, unicode) else getdate(self.due_date_of_next_month)
		diff_of_first_and_second_due_date = date_diff(due_date_of_next_month,self.date)
		if date_diff(due_date_of_next_month,self.date) > 44 :
			self.due_date_of_next_month = str(self.get_next_due_date(due_date_of_next_month,-1))+"T00:00:00.000Z"
			#frappe.throw("Decrease Payment Day")
		if date_diff(due_date_of_next_month,self.date) <= 14:
			self.due_date_of_next_month = str(self.get_next_due_date(due_date_of_next_month,1))+"T00:00:00.000Z"
예제 #6
0
	def get_period_factor(self, period_start, period_end, start_date=None, end_date=None):
		payroll_days = date_diff(period_end, period_start) + 1
		if start_date and end_date:
			salary_days = date_diff(end_date, start_date) + 1
			return flt(payroll_days)/flt(salary_days)
		# if period configured for a year and monthly frequency return 12 to make tax calc consistent
		if 360 <= payroll_days <= 370 and self.payroll_frequency == "Monthly":
			return 12
		salary_days = date_diff(self.end_date, self.start_date) + 1
		return flt(payroll_days)/flt(salary_days)
예제 #7
0
	def get_amount(self, sal_start_date, sal_end_date):
		start_date = getdate(sal_start_date)
		end_date = getdate(sal_end_date)
		total_days = date_diff(getdate(self.to_date), getdate(self.from_date)) + 1
		amount_per_day = self.amount / total_days
		if getdate(sal_start_date) <= getdate(self.from_date):
			start_date = getdate(self.from_date)
		if getdate(sal_end_date) > getdate(self.to_date):
			end_date = getdate(self.to_date)
		no_of_days = date_diff(getdate(end_date), getdate(start_date)) + 1
		return amount_per_day * no_of_days
예제 #8
0
def get_number_of_leave_days(employee, leave_type, from_date, to_date, half_day = None, half_day_date = None):
	number_of_days = 0
	if cint(half_day) == 1:
		if from_date == to_date:
			number_of_days = 0.5
		else:
			number_of_days = date_diff(to_date, from_date) + .5
	else:
		number_of_days = date_diff(to_date, from_date) + 1

	if not frappe.db.get_value("Leave Type", leave_type, "include_holiday"):
		number_of_days = flt(number_of_days) - flt(get_holidays(employee, from_date, to_date))
	return number_of_days
예제 #9
0
파일: event.py 프로젝트: deveninfotech/phr
def create_event(data):
	response = ''
	request_type="POST"
	url = "%s/createEvent"%get_base_url()

	event_data={
			"event_title": data.get('event_title'),
			"profile_id": data.get('profile_id'),
			"str_event_date": data.get('event_date'),
			"received_from": "Desktop",
			"event_symptoms" : data.get('complaints'),
			"event_descripton": data.get('event_descripton')
		}

	event_date = datetime.datetime.strptime(event_data.get('str_event_date'), "%d/%m/%Y").strftime('%Y-%m-%d')
	
	if date_diff(event_date, nowdate()) > 0:
		frappe.msgprint("Event Date should be past or current")
		return {"exe":"Event Date should be past or current"}

	else:
		response=get_response(url, json.dumps(event_data), request_type)
		make_log(json.loads(response.text).get('entityid'),"Event","Create","Event Created")

	return json.loads(response.text)
예제 #10
0
	def set_rates(self):
		self.net_total = 0
		for d in self.items:
			net_rate = 0.0
			for i in range(date_diff(self.to_date, self.from_date)):
				day = add_days(self.from_date, i)
				if not d.item:
					continue
				day_rate = frappe.db.sql("""
					select 
						item.rate 
					from 
						`tabHotel Room Pricing Item` item,
						`tabHotel Room Pricing` pricing
					where
						item.parent = pricing.name
						and item.item = %s
						and %s between pricing.from_date 
							and pricing.to_date""", (d.item, day))

				if day_rate:
					net_rate += day_rate[0][0]
				else:
					frappe.throw(
						_("Please set Hotel Room Rate on {}".format(
							frappe.format(day, dict(fieldtype="Date")))), exc=HotelRoomPricingNotSetError)
			d.rate = net_rate
			d.amount = net_rate * flt(d.qty)
			self.net_total += d.amount
예제 #11
0
def get_number_of_days(end_date=None, start_date=None):
	if start_date and end_date:
		num_of_days = date_diff(start_date, end_date)
	else:
		num_of_days = 0
	
	return num_of_days
예제 #12
0
	def get_leave_details(self, joining_date=None, relieving_date=None, lwp=None):
		if not self.fiscal_year:
			# if default fiscal year is not set, get from nowdate
			self.fiscal_year = get_fiscal_year(nowdate())[0]

		if not self.month:
			self.month = "%02d" % getdate(nowdate()).month
			self.set_month_dates()

		if not joining_date:
			joining_date, relieving_date = frappe.db.get_value("Employee", self.employee,
				["date_of_joining", "relieving_date"])

		holidays = self.get_holidays_for_employee(self.start_date, self.end_date)

		working_days = date_diff(self.end_date, self.start_date) + 1
		if not cint(frappe.db.get_value("HR Settings", None, "include_holidays_in_total_working_days")):
			working_days -= len(holidays)
			if working_days < 0:
				frappe.throw(_("There are more holidays than working days this month."))

		if not lwp:
			lwp = self.calculate_lwp(holidays, working_days)
		self.total_days_in_month = working_days
		self.leave_without_pay = lwp
		payment_days = flt(self.get_payment_days(joining_date, relieving_date)) - flt(lwp)
		self.payment_days = payment_days > 0 and payment_days or 0
def execute(filters=None):
	if not filters: filters = {}

	from_date = get_first_day(filters["month"] + '-' + filters["year"])
	to_date = get_last_day(filters["month"] + '-' + filters["year"])
	total_days_in_month = date_diff(to_date, from_date) +1
	columns = get_columns(total_days_in_month)
	students = get_student_group_students(filters.get("student_group"),1)
	students_list = get_students_list(students)
	att_map = get_attendance_list(from_date, to_date, filters.get("student_group"), students_list)
	data = []
	for stud in students:
		row = [stud.student, stud.student_name]
		student_status = frappe.db.get_value("Student", stud.student, "enabled")
		date = from_date
		total_p = total_a = 0.0
		for day in range(total_days_in_month):
			status="None"
			if att_map.get(stud.student):
				status = att_map.get(stud.student).get(date, "None")
			elif not student_status:
				status = "Inactive"
			else:
				status = "None"
			status_map = {"Present": "P", "Absent": "A", "None": "", "Inactive":"-"}
			row.append(status_map[status])
			if status == "Present":
				total_p += 1
			elif status == "Absent":
				total_a += 1
			date = add_days(date, 1)
		row += [total_p, total_a]
		data.append(row)
	return columns, data
예제 #14
0
	def get_context(self, context):
		paid_backers = get_paid_backers(self.bounty_backer)
		no_of_backers = len(paid_backers)
		if no_of_backers == 0:
			no_of_backers = 'Be the first to back this bounty'
		elif no_of_backers == 1:
			no_of_backers = str(no_of_backers) + ' backer'
		else:
			no_of_backers = str(no_of_backers) + ' backers'

		bounty_left = self.goal - self.bounty_collected
		if bounty_left > (self.goal * 0.1) or bounty_left < 0:
			bounty_left = self.goal * 0.1

		# edit permission
		can_edit = self.owner == frappe.session.user

		context.no_cache = True
		context.no_breadcrumbs = False
		context.days_to_go = date_diff(self.end_date, nowdate())
		context.paid_backers = ", ".join([backer.full_name or backer.user for backer in paid_backers])
		context.no_of_backers = no_of_backers
		context.fmt_money = fmt_money
		context.bounty_left = bounty_left
		context.comment_list = get_comment_list(self.doctype, self.name)
		context.can_edit = can_edit
예제 #15
0
def make_new_invoice(ref_wrapper, posting_date):
	from erpnext.accounts.utils import get_fiscal_year
	new_invoice = frappe.copy_doc(ref_wrapper)

	mcount = month_map[ref_wrapper.recurring_type]

	invoice_period_from_date = get_next_date(ref_wrapper.invoice_period_from_date, mcount)

	# get last day of the month to maintain period if the from date is first day of its own month
	# and to date is the last day of its own month
	if (cstr(get_first_day(ref_wrapper.invoice_period_from_date)) == \
			cstr(ref_wrapper.invoice_period_from_date)) and \
		(cstr(get_last_day(ref_wrapper.invoice_period_to_date)) == \
			cstr(ref_wrapper.invoice_period_to_date)):
		invoice_period_to_date = get_last_day(get_next_date(ref_wrapper.invoice_period_to_date,
			mcount))
	else:
		invoice_period_to_date = get_next_date(ref_wrapper.invoice_period_to_date, mcount)

	new_invoice.update({
		"posting_date": posting_date,
		"aging_date": posting_date,
		"due_date": add_days(posting_date, cint(date_diff(ref_wrapper.due_date,
			ref_wrapper.posting_date))),
		"invoice_period_from_date": invoice_period_from_date,
		"invoice_period_to_date": invoice_period_to_date,
		"fiscal_year": get_fiscal_year(posting_date)[0],
		"owner": ref_wrapper.owner,
	})

	new_invoice.submit()

	return new_invoice
예제 #16
0
	def mark_employee_times(self):
		
		employee_list = get_employees_list(self.department,self.branch,self.company)
		#days = date_diff(self.date, self.date)+1
		days = date_diff(self.date, self.date)+1
		for d in range(days):
			dt = add_days(cstr(self.date), d)
			
			for e in employee_list:
				leave = frappe.db.sql("""
				select t1.name
				from `tabAttendance` t1
				where t1.docstatus < 2
				and t1.employee = %s
				and att_date = %s
				""", (e, dt))
				if leave:
					frappe.msgprint(_("Employee %s has a pre-existing attendance record for this date: %s").format(e,dt))
				else:
					attendance = frappe.new_doc("Attendance")
					attendance.employee = employee['employee']
					attendance.employee_name = employee['employee_name']
					attendance.att_date = self.date
					attendance.arrival_time = self.arrival_time
					attendance.departure_time = self.departure_time
					if self.company:
						attendance.company = self.company
					else:
						attendance.company = frappe.db.get_value("Employee", employee['employee'], "Company")
					attendance.submit()
예제 #17
0
파일: event.py 프로젝트: pawaranand/phr
def update_event(data):
	response = ''
	request_type="POST"
	url="%s/createupdateevent"%get_base_url()

	event_data =	{
			"entityid":data.get('entityid'),
			"event_complaint_list":[],
			"profile_owner_name": frappe.db.get_value('User', {'profile_id':data.get('profile_id')}, 'first_name'),
			"status": "active",
			"event_diseasemontoring": False,
			"event_symptoms" :data.get('complaints'),
			"event_title": data.get('event_title'),
			"profile_id": data.get('profile_id'),
			"str_event_date": data.get('event_date'),
			"event_descripton": data.get('event_descripton'),
			"visit_files": data.get('dms_file_list'),
			"doctor_id": data.get('doctor_id'),
			"doctor_name": data.get("doctor_name"),
			"visit_descripton": data.get('event_descripton'),
			"received_from": "Desktop",
			"str_visit_date": data.get('visit_date'),
			"diagnosis_desc": data.get('diagnosis_desc')
	}

	import datetime
	event_date = datetime.datetime.strptime(event_data.get('str_event_date'), "%d/%m/%Y").strftime('%Y-%m-%d')
	visit_date = datetime.datetime.strptime(event_data.get('str_visit_date'), "%d/%m/%Y").strftime('%Y-%m-%d')

	if date_diff(visit_date, nowdate()) > 0:
		frappe.msgprint("Visit Date could not be greater than current date")
		return {"exe":"Visit Date could not be greater than current date"}

	elif date_diff(visit_date, event_date) < 0:
		frappe.msgprint("Visit Date should not be less than Event Date")
		return {"exe":"Event Date should be past or current"}

	else:
		response=get_response(url, json.dumps(event_data), request_type)
		make_log(data.get('entityid'),"Event","Update","Event Updated")
		if data.get('cname'):
			text_msg = "%s Has Updated Event,\n\n Team Healthsnapp"%data.get('cname')
			email_msg = ""
			from phr.templates.pages.profile import notify_about_linked_phrs
			notify_about_linked_phrs(data.get('pid'),email_msg,text_msg,"Event",data.get('cname'))

	return json.loads(response.text)
예제 #18
0
def get_number_of_leave_days(employee, leave_type, from_date, to_date, half_day=None):
	if half_day:
		return 0.5
	number_of_days = date_diff(to_date, from_date) + 1
	if not frappe.db.get_value("Leave Type", leave_type, "include_holiday"):
		number_of_days = flt(number_of_days) - flt(get_holidays(employee, from_date, to_date))

	return number_of_days
예제 #19
0
 def get_total_leave_days(self):
     """Calculates total leave days based on input and holidays"""
     ret = {"total_leave_days": 0.5}
     if not self.half_day:
         tot_days = date_diff(self.to_date, self.from_date) + 1
         holidays = self.get_holidays()
         ret = {"total_leave_days": flt(tot_days) - flt(holidays)}
     return ret
예제 #20
0
def get_average_age(fifo_queue, to_date):
	batch_age = age_qty = total_qty = 0.0
	for batch in fifo_queue:
		batch_age = date_diff(to_date, batch[1])
		age_qty += batch_age * batch[0]
		total_qty += batch[0]

	return (age_qty / total_qty) if total_qty else 0.0
예제 #21
0
	def make_time_logs(self):
		"""Capacity Planning. Plan time logs based on earliest availablity of workstation after
			Planned Start Date. Time logs will be created and remain in Draft mode and must be submitted
			before manufacturing entry can be made."""

		if not self.operations:
			return

		time_logs = []
		plan_days = frappe.db.get_single_value("Manufacturing Settings", "capacity_planning_for_days") or 30

		for i, d in enumerate(self.operations):
			self.set_operation_start_end_time(i, d)

			time_log = make_time_log(self.name, d.operation, d.planned_start_time, d.planned_end_time,
				flt(self.qty) - flt(d.completed_qty), self.project, d.workstation, operation_id=d.name)

			if d.workstation:
				# validate operating hours if workstation [not mandatory] is specified
				self.check_operation_fits_in_working_hours(d)

			original_start_time = time_log.from_time
			while True:
				_from_time = time_log.from_time

				try:
					time_log.save()
					break
				except WorkstationHolidayError:
					time_log.move_to_next_day()
				except NotInWorkingHoursError:
					time_log.move_to_next_working_slot()
				except OverlapError:
					time_log.move_to_next_non_overlapping_slot()

				# reset end time
				time_log.to_time = get_datetime(time_log.from_time) + relativedelta(minutes=d.time_in_mins)

				if date_diff(time_log.from_time, original_start_time) > plan_days:
					frappe.msgprint(_("Unable to find Time Slot in the next {0} days for Operation {1}").format(plan_days, d.operation))
					break

				# if time log needs to be moved, make sure that the from time is not the same
				if _from_time == time_log.from_time:
					frappe.throw("Capacity Planning Error")

			d.planned_start_time = time_log.from_time
			d.planned_end_time = time_log.to_time
			d.db_update()

			if time_log.name:
				time_logs.append(time_log.name)

		self.planned_end_date = self.operations[-1].planned_end_time

		if time_logs:
			frappe.local.message_log = []
			frappe.msgprint(_("Time Logs created:") + "\n" + "\n".join(time_logs))
예제 #22
0
	def calculate_pro_rata_tax(self, salary_component):
		# Calculate total tax payable earnings
		tax_applicable_components = []
		for earning in self._salary_structure_doc.earnings:
			#all tax applicable earnings which are not flexi
			if earning.is_tax_applicable and not earning.is_flexible_benefit:
				tax_applicable_components.append(earning.salary_component)
		total_taxable_earning = 0
		for earning in self.earnings:
			if earning.salary_component in tax_applicable_components:
				total_taxable_earning += earning.amount

		# Get payroll period, prorata frequency
		days = date_diff(self.end_date, self.start_date) + 1
		payroll_period = get_payroll_period(self.start_date, self.end_date, self.company)
		if not payroll_period:
			frappe.throw(_("Start and end dates not in a valid Payroll Period"))
		total_days = date_diff(payroll_period.end_date, payroll_period.start_date) + 1
		prorata_frequency = flt(total_days)/flt(days)
		annual_earning = total_taxable_earning * prorata_frequency

		# Calculate total exemption declaration
		exemption_amount = 0
		if frappe.db.exists("Employee Tax Exemption Declaration", {"employee": self.employee,
		"payroll_period": payroll_period.name, "docstatus": 1}):
			exemption_amount = frappe.db.get_value("Employee Tax Exemption Declaration",
				{"employee": self.employee, "payroll_period": payroll_period.name, "docstatus": 1}, #fix period
				"total_exemption_amount")
		annual_earning = annual_earning - exemption_amount

		# Get tax calc by component
		component = frappe.get_doc("Salary Component", salary_component)
		annual_tax = component.calculate_tax(annual_earning)

		# Calc prorata tax
		pro_rata_tax = annual_tax/prorata_frequency

		# Data for update_component_row
		struct_row = {}
		struct_row['depends_on_lwp'] = 0
		struct_row['salary_component'] = component.name
		struct_row['abbr'] = component.salary_component_abbr
		struct_row['do_not_include_in_total'] = 0

		return struct_row, pro_rata_tax
예제 #23
0
	def add_event(e, date):
		new_event = e.copy()

		enddate = add_days(date,int(date_diff(e.ends_on.split(" ")[0], e.starts_on.split(" ")[0]))) \
			if (e.starts_on and e.ends_on) else date
		new_event.starts_on = date + " " + e.starts_on.split(" ")[1]
		if e.ends_on:
			new_event.ends_on = enddate + " " + e.ends_on.split(" ")[1]
		add_events.append(new_event)
예제 #24
0
	def make_time_logs(self, open_new=False):
		"""Capacity Planning. Plan time logs based on earliest availablity of workstation after
			Planned Start Date. Time logs will be created and remain in Draft mode and must be submitted
			before manufacturing entry can be made."""

		if not self.operations:
			return

		timesheets = []
		plan_days = frappe.db.get_single_value("Manufacturing Settings", "capacity_planning_for_days") or 30

		timesheet = make_timesheet(self.name)
		workstation_list = []
		last_workstation_idx = {}
		timesheet.set('time_logs', [])

		for i, d in enumerate(self.operations):
			if d.workstation and d.status != 'Completed':
				last_workstation_idx[d.workstation] = i # set last row index of workstation
				self.set_start_end_time_for_workstation(d, workstation_list, last_workstation_idx.get(d.workstation))

				args = self.get_operations_data(d)
				add_timesheet_detail(timesheet, args)
				original_start_time = d.planned_start_time

				# validate operating hours if workstation [not mandatory] is specified
				try:
					timesheet.validate_time_logs()
				except OverlapError:
					if frappe.message_log: frappe.message_log.pop()
					timesheet.schedule_for_production_order(d.idx)
				except WorkstationHolidayError:
					if frappe.message_log: frappe.message_log.pop()
					timesheet.schedule_for_production_order(d.idx)

				from_time, to_time = self.get_start_end_time(timesheet, d.name)

				if date_diff(from_time, original_start_time) > plan_days:
					frappe.throw(_("Unable to find Time Slot in the next {0} days for Operation {1}").format(plan_days, d.operation))
					break

				d.planned_start_time = from_time
				d.planned_end_time = to_time
				d.db_update()

		if timesheet and open_new:
			return timesheet

		if timesheet:
			timesheet.save()
			timesheets.append(timesheet.name)

		self.planned_end_date = self.operations[-1].planned_end_time
		if timesheets:
			frappe.local.message_log = []
			frappe.msgprint(_("Timesheet created:") + "\n" + "\n".join(timesheets))
예제 #25
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)
예제 #26
0
	def get_period_factor(self, period_start, period_end, start_date=None, end_date=None):
		# TODO if both deduct checked update the factor to make tax consistent
		joining_date, relieving_date = frappe.db.get_value("Employee", self.employee, ["date_of_joining", "relieving_date"])
		if getdate(joining_date) > getdate(period_start):
			period_start = joining_date
		if relieving_date and getdate(relieving_date) < getdate(period_end):
			period_end = relieving_date

		payroll_days = date_diff(period_end, period_start) + 1
		if start_date and end_date:
			salary_days = date_diff(end_date, start_date) + 1
			return flt(payroll_days)/flt(salary_days)

		# if period configured for a year and monthly frequency return 12 to make tax calc consistent
		if 360 <= payroll_days <= 370 and self.payroll_frequency == "Monthly":
			return 12

		salary_days = date_diff(self.end_date, self.start_date) + 1
		return flt(payroll_days)/flt(salary_days)
예제 #27
0
def get_data(filters):
	out = []
	for room_type in frappe.get_all('Hotel Room Type'):
		total_booked = 0
		for i in range(date_diff(filters.to_date, filters.from_date)):
			day = add_days(filters.from_date, i)
			total_booked += get_rooms_booked(room_type.name, day)

		out.append([room_type.name, total_booked])

	return out
예제 #28
0
	def validate(self):
		if self.starts_on and self.ends_on and self.starts_on > self.ends_on:
			frappe.msgprint(frappe._("Event end must be after start"), raise_exception=True)

		if self.starts_on == self.ends_on:
			# this scenario doesn't make sense i.e. it starts and ends at the same second!
			self.ends_on = None

		if self.starts_on and self.ends_on and int(date_diff(self.ends_on.split(" ")[0], self.starts_on.split(" ")[0])) > 0 \
			and self.repeat_on == "Every Day":
			frappe.msgprint(frappe._("Every day events should finish on the same day."), raise_exception=True)
예제 #29
0
def send_reminder():
	frappe.has_permission('GST Settings', throw=True)

	last_sent = frappe.db.get_single_value('GST Settings', 'gstin_email_sent_on')
	if last_sent and date_diff(nowdate(), last_sent) < 3:
		frappe.throw("Please wait 3 days before resending the reminder.")

	frappe.db.set_value('GST Settings', 'GST Settings', 'gstin_email_sent_on', nowdate())

	# enqueue if large number of customers, suppliser
	frappe.enqueue('erpnext.regional.doctype.gst_settings.gst_settings.send_gstin_reminder_to_all_parties')
	frappe.msgprint('Email Reminders will be sent to all parties with email contacts')
예제 #30
0
파일: party.py 프로젝트: njmube/erpnext
def validate_due_date(posting_date, due_date, party_type, party, company):
	if getdate(due_date) < getdate(posting_date):
		frappe.throw(_("Due Date cannot be before Posting Date"))
	else:
		default_due_date = get_due_date(posting_date, party_type, party, company)
		if default_due_date != posting_date and getdate(due_date) > getdate(default_due_date):
			is_credit_controller = frappe.db.get_single_value("Accounts Settings", "credit_controller") in frappe.get_roles()
			if is_credit_controller:
				msgprint(_("Note: Due / Reference Date exceeds allowed customer credit days by {0} day(s)")
					.format(date_diff(due_date, default_due_date)))
			else:
				frappe.throw(_("Due / Reference Date cannot be after {0}").format(formatdate(default_due_date)))
예제 #31
0
def autocreate_leave_allocation():
    auto_create = frappe.db.get_value("HR Settings", None,
                                      "sc_auto_create_leave_allocation")
    if auto_create == '1':
        yesterday = add_days(today(), -1)
        leave_allocations = frappe.get_list("Leave Allocation", {
            'to_date': yesterday,
            'docstatus': 1,
            'carry_forward': True
        })

        first_day_yes = get_first_day(yesterday)
        last_day_yes = get_last_day(yesterday)

        for leave_alloc in leave_allocations:
            from_date = today()
            to_date = today()
            leave_allocation = frappe.get_doc("Leave Allocation",
                                              leave_alloc['name'])
            new_leave_allocation = frappe.new_doc("Leave Allocation")
            new_leave_allocation.employee = leave_allocation.employee
            new_leave_allocation.employee_name = leave_allocation.employee_name
            new_leave_allocation.leave_type = leave_allocation.leave_type
            if leave_allocation.from_date == first_day_yes and leave_allocation.to_date == last_day_yes:
                from_date = today()
                to_date = get_last_day(today())
            else:
                diff_no = date_diff(leave_allocation.to_date,
                                    leave_allocation.from_date)
                from_date = today()
                to_date = add_days(from_date, diff_no)
            new_leave_allocation.from_date = from_date
            new_leave_allocation.to_date = to_date
            new_leave_allocation.new_leaves_allocated = leave_allocation.new_leaves_allocated
            if leave_allocation.carry_forward:
                new_leave_allocation.carry_forward = leave_allocation.carry_forward

            new_leave_allocation.save(ignore_permissions=True)
            new_leave_allocation.submit()
예제 #32
0
파일: utils.py 프로젝트: ravik0007/erpnext
def validate_house_rent_dates(doc):
	if not doc.rented_to_date or not doc.rented_from_date:
		frappe.throw(_("House rented dates required for exemption calculation"))

	if date_diff(doc.rented_to_date, doc.rented_from_date) < 14:
		frappe.throw(_("House rented dates should be atleast 15 days apart"))

	proofs = frappe.db.sql("""
		select name
		from `tabEmployee Tax Exemption Proof Submission`
		where
			docstatus=1 and employee=%(employee)s and payroll_period=%(payroll_period)s
			and (rented_from_date between %(from_date)s and %(to_date)s or rented_to_date between %(from_date)s and %(to_date)s)
	""", {
		"employee": doc.employee,
		"payroll_period": doc.payroll_period,
		"from_date": doc.rented_from_date,
		"to_date": doc.rented_to_date
	})

	if proofs:
		frappe.throw(_("House rent paid days overlapping with {0}").format(proofs[0][0]))
예제 #33
0
    def get_leave_details(self,
                          joining_date=None,
                          relieving_date=None,
                          lwp=None):
        if not joining_date:
            joining_date, relieving_date = frappe.db.get_value(
                "Employee", self.employee,
                ["date_of_joining", "relieving_date"])

        holidays = self.get_holidays_for_employee(self.start_date,
                                                  self.end_date)

        working_days = date_diff(self.end_date, self.start_date) + 1
        actual_lwp = self.calculate_lwp(holidays, working_days)
        if not cint(
                frappe.db.get_value("HR Settings", None,
                                    "include_holidays_in_total_working_days")):
            working_days -= len(holidays)
            if working_days < 0:
                frappe.throw(
                    _("There are more holidays than working days this month."))

        if not lwp:
            lwp = actual_lwp
        elif lwp != actual_lwp:
            frappe.msgprint(
                _("Leave Without Pay does not match with approved Leave Application records"
                  ))

        self.total_working_days = working_days
        self.leave_without_pay = lwp

        self.monthly_total_hours = (working_days - len(holidays)) * 8

        payment_days = flt(self.get_payment_days(joining_date,
                                                 relieving_date)) - flt(lwp)
        self.payment_days = payment_days > 0 and payment_days or 0
        self.get_worked_hours()
        self.get_overtime_info()
예제 #34
0
	def on_submit(self):
		company = frappe.db.get_value("Employee", self.employee, "company")
		date_difference = date_diff(self.work_end_date, self.work_from_date) + 1
		if self.half_day:
			date_difference -= 0.5
		leave_period = get_leave_period(self.work_from_date, self.work_end_date, company)
		if leave_period:
			leave_allocation = self.get_existing_allocation_for_period(leave_period)
			if leave_allocation:
				leave_allocation.new_leaves_allocated += date_difference
				leave_allocation.validate()
				leave_allocation.db_set("new_leaves_allocated", leave_allocation.total_leaves_allocated)
				leave_allocation.db_set("total_leaves_allocated", leave_allocation.total_leaves_allocated)

				# generate additional ledger entry for the new compensatory leaves off
				create_additional_leave_ledger_entry(leave_allocation, date_difference, add_days(self.work_end_date, 1))

			else:
				leave_allocation = self.create_leave_allocation(leave_period, date_difference)
			self.leave_allocation=leave_allocation.name
		else:
			frappe.throw(_("There is no leave period in between {0} and {1}").format(self.work_from_date, self.work_end_date))
예제 #35
0
    def reschedule_dependent_tasks(self):
        end_date = self.exp_end_date or self.act_end_date
        if end_date:
            for task_name in frappe.db.sql(
                    """select name from `tabTask` as parent where parent.project = %(project)s and parent.name in \
				(select parent from `tabTask Depends On` as child where child.task = %(task)s and child.project = %(project)s)""",
                {
                    'project': self.project,
                    'task': self.name
                },
                    as_dict=1):

                task = frappe.get_doc("Task", task_name.name)
                if task.exp_start_date and task.exp_end_date and task.exp_start_date < getdate(
                        end_date) and task.status == "Open":
                    task_duration = date_diff(task.exp_end_date,
                                              task.exp_start_date)
                    task.exp_start_date = add_days(end_date, 1)
                    task.exp_end_date = add_days(task.exp_start_date,
                                                 task_duration)
                    task.flags.ignore_recursion_check = True
                    task.save()
예제 #36
0
    def validate_availability(self):
        for i in range(date_diff(self.to_date, self.from_date)):
            day = add_days(self.from_date, i)
            self.rooms_booked = {}

            for d in self.items:
                if not d.item in self.rooms_booked:
                    self.rooms_booked[d.item] = 0

                room_type = frappe.db.get_value("Hotel Room Package", d.item,
                                                'hotel_room_type')
                rooms_booked = get_rooms_booked(room_type, day, exclude_reservation=self.name) \
                    + d.qty + self.rooms_booked.get(d.item)
                total_rooms = self.get_total_rooms(d.item)
                if total_rooms < rooms_booked:
                    frappe.throw(
                        _("Hotel Rooms of type {0} are unavailable on {1}"
                          ).format(d.item,
                                   frappe.format(day, dict(fieldtype="Date"))),
                        exc=HotelRoomUnavailableError)

                self.rooms_booked[d.item] += rooms_booked
예제 #37
0
 def validate_employee_attendance(self):
     employees_to_mark_attendance = []
     days_in_payroll, days_holiday, days_attendance_marked = 0, 0, 0
     for employee_detail in self.employees:
         employee_joining_date = frappe.db.get_value(
             "Employee", employee_detail.employee, 'date_of_joining')
         start_date = self.start_date
         if employee_joining_date > getdate(self.start_date):
             start_date = employee_joining_date
         days_holiday = self.get_count_holidays_of_employee(
             employee_detail.employee, start_date)
         days_attendance_marked = self.get_count_employee_attendance(
             employee_detail.employee, start_date)
         days_in_payroll = date_diff(self.end_date, start_date) + 1
         if days_in_payroll > days_holiday + days_attendance_marked:
             employees_to_mark_attendance.append({
                 "employee":
                 employee_detail.employee,
                 "employee_name":
                 employee_detail.employee_name
             })
     return employees_to_mark_attendance
예제 #38
0
    def create_job_card(self):
        manufacturing_settings_doc = frappe.get_doc("Manufacturing Settings")

        enable_capacity_planning = not cint(
            manufacturing_settings_doc.disable_capacity_planning)
        plan_days = cint(
            manufacturing_settings_doc.capacity_planning_for_days) or 30

        for i, row in enumerate(self.operations):
            self.set_operation_start_end_time(i, row)

            if not row.workstation:
                frappe.throw(
                    _("Row {0}: select the workstation against the operation {1}"
                      ).format(row.idx, row.operation))

            original_start_time = row.planned_start_time
            job_card_doc = create_job_card(
                self,
                row,
                enable_capacity_planning=enable_capacity_planning,
                auto_create=True)

            if enable_capacity_planning and job_card_doc:
                row.planned_start_time = job_card_doc.time_logs[0].from_time
                row.planned_end_time = job_card_doc.time_logs[-1].to_time

                if date_diff(row.planned_start_time,
                             original_start_time) > plan_days:
                    frappe.throw(
                        _("Unable to find the time slot in the next {0} days for the operation {1}."
                          ).format(plan_days, row.operation), CapacityError)

                row.db_update()

        planned_end_date = self.operations and self.operations[
            -1].planned_end_time
        if planned_end_date:
            self.db_set("planned_end_date", planned_end_date)
예제 #39
0
파일: party.py 프로젝트: andiyan1/erpnext
def validate_due_date(posting_date, due_date, party_type, party, company):
    if getdate(due_date) < getdate(posting_date):
        frappe.throw(_("Due Date cannot be before Posting Date"))
    else:
        default_due_date = get_due_date(posting_date, party_type, party,
                                        company)
        if not default_due_date:
            return

        if default_due_date != posting_date and getdate(due_date) > getdate(
                default_due_date):
            is_credit_controller = frappe.db.get_single_value(
                "Accounts Settings",
                "credit_controller") in frappe.get_roles()
            if is_credit_controller:
                msgprint(
                    _("Note: Due / Reference Date exceeds allowed customer credit days by {0} day(s)"
                      ).format(date_diff(due_date, default_due_date)))
            else:
                frappe.throw(
                    _("Due / Reference Date cannot be after {0}").format(
                        formatdate(default_due_date)))
예제 #40
0
 def validate_applicable_after(self):
     if self.leave_type:
         leave_type = frappe.get_doc("Leave Type", self.leave_type)
         if leave_type.applicable_after > 0:
             date_of_joining = frappe.db.get_value("Employee",
                                                   self.employee,
                                                   "date_of_joining")
             leave_days = get_approved_leaves_for_period(
                 self.employee, False, date_of_joining, self.from_date)
             number_of_days = date_diff(getdate(self.from_date),
                                        date_of_joining)
             if number_of_days >= 0:
                 holidays = 0
                 if not frappe.db.get_value("Leave Type", self.leave_type,
                                            "include_holiday"):
                     holidays = get_holidays(self.employee, date_of_joining,
                                             self.from_date)
                 number_of_days = number_of_days - leave_days - holidays
                 if number_of_days < leave_type.applicable_after:
                     frappe.throw(
                         _("{0} applicable after {1} working days").format(
                             self.leave_type, leave_type.applicable_after))
예제 #41
0
	def get_payment_days(self, joining_date, relieving_date):
		start_date = getdate(self.start_date)
		if joining_date:
			if getdate(self.start_date) <= joining_date <= getdate(self.end_date):
				start_date = joining_date
			elif joining_date > getdate(self.end_date):
				return

		end_date = getdate(self.end_date)
		if relieving_date:
			if getdate(self.start_date) <= relieving_date <= getdate(self.end_date):
				end_date = relieving_date
			elif relieving_date < getdate(self.start_date):
				frappe.throw(_("Employee relieved on {0} must be set as 'Left'")
					.format(relieving_date))

		payment_days = date_diff(end_date, start_date) + 1

		if not cint(frappe.db.get_value("HR Settings", None, "include_holidays_in_total_working_days")):
			holidays = self.get_holidays_for_employee(start_date, end_date)
			payment_days -= len(holidays)
		return payment_days
    def test_loan_interest_accural(self):
        pledges = []
        pledges.append({
            "loan_security": "Test Security 1",
            "qty": 4000.00,
            "haircut": 50,
            "loan_security_price": 500.00
        })

        loan_security_pledge = create_loan_security_pledge(
            self.applicant, pledges)

        loan = create_demand_loan(self.applicant,
                                  "Demand Loan",
                                  loan_security_pledge.name,
                                  posting_date=get_first_day(nowdate()))

        loan.submit()

        first_date = '2019-10-01'
        last_date = '2019-10-30'

        no_of_days = date_diff(last_date, first_date) + 1

        accrued_interest_amount = (loan.loan_amount * loan.rate_of_interest * no_of_days) \
         / (days_in_year(get_datetime(first_date).year) * 100)

        make_loan_disbursement_entry(loan.name,
                                     loan.loan_amount,
                                     disbursement_date=first_date)

        process_loan_interest_accrual(posting_date=last_date)

        loan_interest_accural = frappe.get_doc("Loan Interest Accrual",
                                               {'loan': loan.name})

        self.assertEquals(flt(loan_interest_accural.interest_amount, 2),
                          flt(accrued_interest_amount, 2))
예제 #43
0
	def test_regular_loan_repayment(self):
		pledges = []
		pledges.append({
			"loan_security": "Test Security 1",
			"qty": 4000.00,
			"haircut": 50
		})

		loan_security_pledge = create_loan_security_pledge(self.applicant2, pledges)

		loan = create_demand_loan(self.applicant2, "Demand Loan", loan_security_pledge.name,
			posting_date=get_first_day(nowdate()))

		loan.submit()

		self.assertEquals(loan.loan_amount, 1000000)

		first_date = '2019-10-01'
		last_date = '2019-10-30'

		no_of_days = date_diff(last_date, first_date) + 1

		accrued_interest_amount = (loan.loan_amount * loan.rate_of_interest * no_of_days) \
			/ (days_in_year(get_datetime(first_date).year) * 100)

		make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=first_date)

		process_loan_interest_accrual(posting_date = last_date)

		repayment_entry = create_repayment_entry(loan.name, self.applicant2, add_days(last_date, 10), "Regular Payment", 111118.68)
		repayment_entry.save()

		penalty_amount = (accrued_interest_amount * 5 * 25) / (100 * days_in_year(get_datetime(first_date).year))

		self.assertEquals(flt(repayment_entry.interest_payable, 2), flt(accrued_interest_amount, 2))
		self.assertEquals(flt(repayment_entry.penalty_amount, 2), flt(penalty_amount, 2))

		repayment_entry.submit()
예제 #44
0
    def get_payment_days(self, joining_date, relieving_date):
        start_date = getdate(self.start_date)
        if joining_date:
            if getdate(self.start_date) <= joining_date <= getdate(
                    self.end_date):
                start_date = joining_date
            elif joining_date > getdate(self.end_date):
                return

        end_date = getdate(self.end_date)
        if relieving_date:
            if getdate(self.start_date) <= relieving_date <= getdate(
                    self.end_date):
                end_date = relieving_date
            elif relieving_date < getdate(self.start_date):
                frappe.throw(
                    _("Employee relieved on {0} must be set as 'Left'").format(
                        relieving_date))

        payment_days = date_diff(end_date, start_date) + 1

        #vin code start
        if ((self.get_holiday_setting_from_salary_stucture() < 2)
                and (self.get_holiday_setting_from_salary_stucture() == 0)):

            #frappe.msgprint(_("0:"+str(holidays)+","+ str(working_days)));
            holidays = self.get_holidays_for_employee(start_date, end_date)
            payment_days -= len(holidays)

        elif ((self.get_holiday_setting_from_salary_stucture() < 2)
              and (self.get_holiday_setting_from_salary_stucture() == 1)):
            #frappe.msgprint(_("1:"+str(holidays)+","+ str(working_days)));
            pass

        #if not cint(frappe.db.get_value("HR Settings", None, "include_holidays_in_total_working_days")):
        #vin code end

        return payment_days
예제 #45
0
def get_overdue(loan_period):
    # check for overdue articles
    today = nowdate()

    overdue_by_member = {}
    articles_transacted = []

    for d in frappe.db.sql("""select name, article, article_name,
        library_member, member_name
        from `tabLibrary Transaction`
        order by transaction_date desc, modified desc""",
                           as_dict=1):

        if d.article in articles_transacted:
            continue

        if d.transaction_type=="Issue" and \
            date_diff(today, d.transaction_date) > loan_period:
            overdue_by_member.setdefault(d.library_member, [])
            overdue_by_member[d.library_member].append(d)

        articles_transacted.append(d.article)
    return overdue_by_member
예제 #46
0
    def check_due_date(self):
        if self.cheque_date:
            for d in self.get("accounts"):
                if d.party_type and d.party and d.get(
                        "credit" if d.party_type ==
                        "Customer" else "debit") > 0:
                    due_date = None
                    if d.against_invoice:
                        due_date = frappe.db.get_value("Sales Invoice",
                                                       d.against_invoice,
                                                       "due_date")
                    elif d.against_voucher:
                        due_date = frappe.db.get_value("Purchase Invoice",
                                                       d.against_voucher,
                                                       "due_date")

                    if due_date and getdate(
                            self.cheque_date) > getdate(due_date):
                        diff = date_diff(self.cheque_date, due_date)
                        if diff > 0:
                            msgprint(
                                _("Note: Reference Date exceeds invoice due date by {0} days for {1} {2}"
                                  ).format(diff, d.party_type, d.party))
예제 #47
0
	def test_loan_topup(self):
		pledge = [{
			"loan_security": "Test Security 1",
			"qty": 4000.00
		}]

		loan_application = create_loan_application('_Test Company', self.applicant, 'Demand Loan', pledge)
		create_pledge(loan_application)

		loan = create_demand_loan(self.applicant, "Demand Loan", loan_application, posting_date=get_first_day(nowdate()))

		loan.submit()

		first_date = get_first_day(nowdate())
		last_date = get_last_day(nowdate())

		no_of_days = date_diff(last_date, first_date) + 1

		accrued_interest_amount = (loan.loan_amount * loan.rate_of_interest * no_of_days) \
			/ (days_in_year(get_datetime().year) * 100)

		make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=first_date)

		process_loan_interest_accrual_for_demand_loans(posting_date=add_days(last_date, 1))

		# Should not be able to create loan disbursement entry before repayment
		self.assertRaises(frappe.ValidationError, make_loan_disbursement_entry, loan.name,
			500000, first_date)

		repayment_entry = create_repayment_entry(loan.name, self.applicant, add_days(get_last_day(nowdate()), 5),
			"Regular Payment", 611095.89)

		repayment_entry.submit()
		loan.reload()

		# After repayment loan disbursement entry should go through
		make_loan_disbursement_entry(loan.name, 500000, disbursement_date=add_days(last_date, 16))
예제 #48
0
def passport_validate_check():
    from frappe.core.doctype.communication.email import make
    frappe.flags.sent_mail = None

    emp = frappe.db.sql(
        "select name,valid_upto,user_id,passport_notification from `tabEmployee`"
    )
    for i in emp:
        if i[1] and i[3]:
            date_difference = date_diff(i[1], getdate(nowdate()))

            if date_difference <= 30 and date_difference > 0:
                content_msg_emp = "Your Passport validity will end after {0} days".format(
                    date_difference)

                prefered_email = frappe.get_value("Employee",
                                                  filters={"name": i[0]},
                                                  fieldname="prefered_email")

                if prefered_email:
                    try:
                        sent = 0
                        make(subject="Passport Validity Notification",
                             content=content_msg_emp,
                             recipients=prefered_email,
                             send_email=True,
                             sender="*****@*****.**")

                        sent = 1
                        print('send email for ' + prefered_email)
                    except:
                        frappe.msgprint("could not send")

                print(content_msg_emp)
                print(
                    '----------------------------------------------------------------'
                )
예제 #49
0
def get_payroll_period_days(start_date, end_date, employee, company=None):
	if not company:
		company = frappe.db.get_value("Employee", employee, "company")
	payroll_period = frappe.db.sql("""
		select name, start_date, end_date
		from `tabPayroll Period`
		where
			company=%(company)s
			and %(start_date)s between start_date and end_date
			and %(end_date)s between start_date and end_date
	""", {
		'company': company,
		'start_date': start_date,
		'end_date': end_date
	})

	if len(payroll_period) > 0:
		actual_no_of_days = date_diff(getdate(payroll_period[0][2]), getdate(payroll_period[0][1])) + 1
		working_days = actual_no_of_days
		if not cint(frappe.db.get_value("HR Settings", None, "include_holidays_in_total_working_days")):
			holidays = get_holidays_for_employee(employee, getdate(payroll_period[0][1]), getdate(payroll_period[0][2]))
			working_days -= len(holidays)
		return payroll_period[0][0], working_days, actual_no_of_days
	return False, False, False
예제 #50
0
    def get_leave_details(self,
                          joining_date=None,
                          relieving_date=None,
                          lwp=None):
        if not self.fiscal_year:
            # if default fiscal year is not set, get from nowdate
            self.fiscal_year = get_fiscal_year(nowdate())[0]

        if not self.month:
            self.month = "%02d" % getdate(nowdate()).month
            self.set_month_dates()

        if not joining_date:
            joining_date, relieving_date = frappe.db.get_value(
                "Employee", self.employee,
                ["date_of_joining", "relieving_date"])

        holidays = self.get_holidays_for_employee(self.start_date,
                                                  self.end_date)

        working_days = date_diff(self.end_date, self.start_date) + 1
        if not cint(
                frappe.db.get_value("HR Settings", None,
                                    "include_holidays_in_total_working_days")):
            working_days -= len(holidays)
            if working_days < 0:
                frappe.throw(
                    _("There are more holidays than working days this month."))

        if not lwp:
            lwp = self.calculate_lwp(holidays, working_days)
        self.total_days_in_month = working_days
        self.leave_without_pay = lwp
        payment_days = flt(self.get_payment_days(joining_date,
                                                 relieving_date)) - flt(lwp)
        self.payment_days = payment_days > 0 and payment_days or 0
예제 #51
0
 def on_submit(self):
     if self.approver != frappe.session.user:
         frappe.throw(_("Only Leave Approver can submit this document"))
     if self.status == "Open":
         frappe.throw(
             _("Only Applications with status 'Approved' and 'Rejected' can be submitted"))
     elif self.status == "Approved":
         request_days = date_diff(self.to_date, self.from_date) + 1
         for number in range(request_days):
             attendance_date = add_days(self.from_date, number)
             skip_attendance = validate_if_attendance_not_applicable(
                 self.employee, attendance_date)
             if not skip_attendance:
                 att = frappe.db.exists(
                     "Attendance", {"employee": self.employee, "attendance_date": attendance_date})
                 if att:
                     attendance = frappe.get_doc("Attendance", att)
                     attendance.update({
                         "status": "Present",
                         "onduty_status": "On Duty"
                         # "on_duty_application": doc.name
                     })
                     attendance.db_update()
                     frappe.db.commit()
                 else:
                     attendance = frappe.new_doc("Attendance")
                     attendance.employee = self.employee
                     attendance.employee_name = self.employee_name
                     attendance.status = "Present"
                     attendance.attendance_date = attendance_date
                     attendance.in_time = ""
                     attendance.out_time = ""
                     attendance.onduty_status = "On Duty"
                     attendance.company = self.company
                     attendance.save(ignore_permissions=True)
                     attendance.submit()
    def on_cancel(self):
        if self.leave_allocation:
            date_difference = date_diff(self.work_end_date,
                                        self.work_from_date) + 1
            if self.half_day:
                date_difference -= 0.5
            leave_allocation = frappe.get_doc("Leave Allocation",
                                              self.leave_allocation)
            if leave_allocation:
                leave_allocation.new_leaves_allocated -= date_difference
                if leave_allocation.new_leaves_allocated - date_difference <= 0:
                    leave_allocation.new_leaves_allocated = 0
                leave_allocation.validate()
                leave_allocation.db_set(
                    "new_leaves_allocated",
                    leave_allocation.total_leaves_allocated)
                leave_allocation.db_set(
                    "total_leaves_allocated",
                    leave_allocation.total_leaves_allocated)

                # create reverse entry on cancelation
                create_additional_leave_ledger_entry(
                    leave_allocation, date_difference * -1,
                    add_days(self.work_end_date, 1))
예제 #53
0
파일: event.py 프로젝트: saurabh6790/phr
def create_event(data):
	response = ''
	request_type="POST"
	url = "%s/createEvent"%get_base_url()

	event_data={
			"event_title": data.get('event_title'),
			"profile_id": data.get('profile_id'),
			"str_event_date": data.get('event_date'),
			"received_from": "Desktop",
			"event_symptoms" : data.get('complaints'),
			"event_descripton": data.get('event_descripton')
		}

	event_date = datetime.datetime.strptime(event_data.get('str_event_date'), "%d/%m/%Y").strftime('%Y-%m-%d')
	
	if date_diff(event_date, nowdate()) > 0:
		frappe.msgprint("Event Date should be past or current",raise_exception=1)

	else:
		response=get_response(url, json.dumps(event_data), request_type)
		make_log(json.loads(response.text).get('entityid'),"Event","Create","Event Created")

	return json.loads(response.text)
def get_max_benefits_remaining(employee, on_date, payroll_period):
	max_benefits = get_max_benefits(employee, on_date)
	if max_benefits and max_benefits > 0:
		have_depends_on_payment_days = False
		per_day_amount_total = 0
		payroll_period_days = get_payroll_period_days(on_date, on_date, employee)[0]
		payroll_period_obj = frappe.get_doc("Payroll Period", payroll_period)

		# Get all salary slip flexi amount in the payroll period
		prev_sal_slip_flexi_total = get_sal_slip_total_benefit_given(employee, payroll_period_obj)

		if prev_sal_slip_flexi_total > 0:
			# Check salary structure hold depends_on_payment_days component
			# If yes then find the amount per day of each component and find the sum
			sal_struct_name = get_assigned_salary_structure(employee, on_date)
			if sal_struct_name:
				sal_struct = frappe.get_doc("Salary Structure", sal_struct_name)
				for sal_struct_row in sal_struct.get("earnings"):
					salary_component = frappe.get_doc("Salary Component", sal_struct_row.salary_component)
					if salary_component.depends_on_payment_days == 1 and salary_component.pay_against_benefit_claim != 1:
						have_depends_on_payment_days = True
						benefit_amount = get_benefit_amount_based_on_pro_rata(sal_struct, salary_component.max_benefit_amount)
						amount_per_day = benefit_amount / payroll_period_days
						per_day_amount_total += amount_per_day

			# Then the sum multiply with the no of lwp in that period
			# Include that amount to the prev_sal_slip_flexi_total to get the actual
			if have_depends_on_payment_days and per_day_amount_total > 0:
				holidays = get_holidays_for_employee(employee, payroll_period_obj.start_date, on_date)
				working_days = date_diff(on_date, payroll_period_obj.start_date) + 1
				leave_days = calculate_lwp(employee, payroll_period_obj.start_date, holidays, working_days)
				leave_days_amount = leave_days * per_day_amount_total
				prev_sal_slip_flexi_total += leave_days_amount

			return max_benefits - prev_sal_slip_flexi_total
	return max_benefits
예제 #55
0
def pretty_date(iso_datetime, ref_date=None):
    """
        Extends frappe.utils.data.pretty_date
    """
    days = date_diff(iso_datetime, ref_date or datetime.date.today())
    if days < 0:
        return frappe.utils.pretty_date(iso_datetime)
    if days < 1:
        return _('today')
    if days == 1:
        return _('tomorrow')
    if days < 7:
        return _('in {} days'.format(cint(days)))
    if days < 12:
        return _('in a week')
    if days < 31:
        return _('in {} weeks'.format(cint(days / 7.0)))
    if days < 46:
        return _('in a month')
    if days < 365:
        return _('in {} months'.format(cint(days / 30.0)))
    if days < 550:
        return _('in a year')
    return _('in {} years'.format(cint(days / 365.0)))
예제 #56
0
    def get_depreciation_amount_prorata_temporis(self,
                                                 depreciable_value,
                                                 row,
                                                 start_date=None,
                                                 end_date=None):
        if start_date and end_date:
            prorata_temporis = min(
                abs(flt(date_diff(str(end_date), str(start_date)))) / flt(
                    frappe.db.get_value("Asset Settings", None,
                                        "number_of_days_in_fiscal_year")), 1)
        else:
            prorata_temporis = 1

        if row.depreciation_method in ("Straight Line", "Manual"):
            depreciation_amount = (
                flt(row.value_after_depreciation) -
                flt(row.expected_value_after_useful_life)
            ) / (cint(row.total_number_of_depreciations) -
                 cint(self.number_of_depreciations_booked)) * prorata_temporis
        else:
            depreciation_amount = self.get_depreciation_amount(
                depreciable_value, row)

        return depreciation_amount
예제 #57
0
def set_follow_up(appointment_doc, method):
    filters = {
        "name": ["!=", appointment_doc.name],
        "insurance_subscription": appointment_doc.insurance_subscription,
        "department": appointment_doc.department,
        "status": "Closed",
    }
    appointment = get_previous_appointment(appointment_doc.patient, filters)
    if appointment and appointment_doc.appointment_date:
        diff = date_diff(appointment_doc.appointment_date,
                         appointment.appointment_date)
        valid_days = int(
            frappe.get_value("Healthcare Settings", "Healthcare Settings",
                             "valid_days"))
        if diff <= valid_days:
            appointment_doc.follow_up = 1
            if (appointment_doc.follow_up
                    and appointment_doc.insurance_subscription
                    and not appointment_doc.authorization_number):
                return
            appointment_doc.invoiced = 1
            # frappe.msgprint(_("Previous appointment found valid for free follow-up.<br>Skipping invoice for this appointment!"), alert=True)
        else:
            appointment_doc.follow_up = 0
	def test_loan_interest_accural(self):
		pledge = [{
			"loan_security": "Test Security 1",
			"qty": 4000.00
		}]

		loan_application = create_loan_application('_Test Company', self.applicant, 'Demand Loan', pledge)
		create_pledge(loan_application)
		loan = create_demand_loan(self.applicant, "Demand Loan", loan_application,
			posting_date=get_first_day(nowdate()))
		loan.submit()

		first_date = '2019-10-01'
		last_date = '2019-10-30'

		no_of_days = date_diff(last_date, first_date) + 1

		accrued_interest_amount = (loan.loan_amount * loan.rate_of_interest * no_of_days) \
			/ (days_in_year(get_datetime(first_date).year) * 100)
		make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=first_date)
		process_loan_interest_accrual_for_demand_loans(posting_date=last_date)
		loan_interest_accural = frappe.get_doc("Loan Interest Accrual", {'loan': loan.name})

		self.assertEquals(flt(loan_interest_accural.interest_amount, 0), flt(accrued_interest_amount, 0))
예제 #59
0
def get_events(start, end, user=None, for_reminder=False):
	if not user:
		user = frappe.session.user
	roles = frappe.get_roles(user)
	events = frappe.db.sql("""select name, subject, description,
		starts_on, ends_on, owner, all_day, event_type, repeat_this_event, repeat_on,repeat_till,
		monday, tuesday, wednesday, thursday, friday, saturday, sunday
		from tabEvent where ((
			(date(starts_on) between date(%(start)s) and date(%(end)s))
			or (date(ends_on) between date(%(start)s) and date(%(end)s))
			or (date(starts_on) <= date(%(start)s) and date(ends_on) >= date(%(end)s))
		) or (
			date(starts_on) <= date(%(start)s) and repeat_this_event=1 and
			ifnull(repeat_till, "3000-01-01") > date(%(start)s)
		))
		{reminder_condition}
		and (event_type='Public' or owner=%(user)s
		or exists(select name from `tabDocShare` where
			tabDocShare.share_doctype="Event" and `tabDocShare`.share_name=tabEvent.name
			and tabDocShare.user=%(user)s)
		or exists(select * from `tabEvent Role` where
			`tabEvent Role`.parent=tabEvent.name
			and `tabEvent Role`.role in ({roles})))
		order by starts_on""".format(
			reminder_condition="and ifnull(send_reminder,0)=1" if for_reminder else "",
			roles=", ".join('"{}"'.format(frappe.db.escape(r)) for r in roles)
		), {
			"start": start,
			"end": end,
			"user": user,
		}, as_dict=1)

	# process recurring events
	start = start.split(" ")[0]
	end = end.split(" ")[0]
	add_events = []
	remove_events = []

	def add_event(e, date):
		new_event = e.copy()

		enddate = add_days(date,int(date_diff(e.ends_on.split(" ")[0], e.starts_on.split(" ")[0]))) \
			if (e.starts_on and e.ends_on) else date
		new_event.starts_on = date + " " + e.starts_on.split(" ")[1]
		if e.ends_on:
			new_event.ends_on = enddate + " " + e.ends_on.split(" ")[1]
		add_events.append(new_event)

	for e in events:
		if e.repeat_this_event:
			e.starts_on = get_datetime_str(e.starts_on)
			if e.ends_on:
				e.ends_on = get_datetime_str(e.ends_on)

			event_start, time_str = get_datetime_str(e.starts_on).split(" ")
			if cstr(e.repeat_till) == "":
				repeat = "3000-01-01"
			else:
				repeat = e.repeat_till
			if e.repeat_on=="Every Year":
				start_year = cint(start.split("-")[0])
				end_year = cint(end.split("-")[0])
				event_start = "-".join(event_start.split("-")[1:])

				# repeat for all years in period
				for year in range(start_year, end_year+1):
					date = str(year) + "-" + event_start
					if getdate(date) >= getdate(start) and getdate(date) <= getdate(end) and getdate(date) <= getdate(repeat):
						add_event(e, date)

				remove_events.append(e)

			if e.repeat_on=="Every Month":
				date = start.split("-")[0] + "-" + start.split("-")[1] + "-" + event_start.split("-")[2]

				# last day of month issue, start from prev month!
				try:
					getdate(date)
				except ValueError:
					date = date.split("-")
					date = date[0] + "-" + str(cint(date[1]) - 1) + "-" + date[2]

				start_from = date
				for i in xrange(int(date_diff(end, start) / 30) + 3):
					if getdate(date) >= getdate(start) and getdate(date) <= getdate(end) \
						and getdate(date) <= getdate(repeat) and getdate(date) >= getdate(event_start):
						add_event(e, date)
					date = add_months(start_from, i+1)

				remove_events.append(e)

			if e.repeat_on=="Every Week":
				weekday = getdate(event_start).weekday()
				# monday is 0
				start_weekday = getdate(start).weekday()

				# start from nearest weeday after last monday
				date = add_days(start, weekday - start_weekday)

				for cnt in xrange(int(date_diff(end, start) / 7) + 3):
					if getdate(date) >= getdate(start) and getdate(date) <= getdate(end) \
						and getdate(date) <= getdate(repeat) and getdate(date) >= getdate(event_start):
						add_event(e, date)

					date = add_days(date, 7)

				remove_events.append(e)

			if e.repeat_on=="Every Day":
				for cnt in xrange(date_diff(end, start) + 1):
					date = add_days(start, cnt)
					if getdate(date) >= getdate(event_start) and getdate(date) <= getdate(end) \
						and getdate(date) <= getdate(repeat) and e[weekdays[getdate(date).weekday()]]:
						add_event(e, date)
				remove_events.append(e)

	for e in remove_events:
		events.remove(e)

	events = events + add_events

	for e in events:
		# remove weekday properties (to reduce message size)
		for w in weekdays:
			del e[w]

	return events
예제 #60
0
    def make_time_logs(self):
        """Capacity Planning. Plan time logs based on earliest availablity of workstation after
			Planned Start Date. Time logs will be created and remain in Draft mode and must be submitted
			before manufacturing entry can be made."""

        if not self.operations:
            return

        time_logs = []
        plan_days = frappe.db.get_single_value(
            "Manufacturing Settings", "capacity_planning_for_days") or 30

        for i, d in enumerate(self.operations):
            self.set_operation_start_end_time(i, d)

            time_log = make_time_log(self.name,
                                     d.operation,
                                     d.planned_start_time,
                                     d.planned_end_time,
                                     flt(self.qty) - flt(d.completed_qty),
                                     self.project_name,
                                     d.workstation,
                                     operation_id=d.name)

            if d.workstation:
                # validate operating hours if workstation [not mandatory] is specified
                self.check_operation_fits_in_working_hours(d)

            original_start_time = time_log.from_time
            while True:
                _from_time = time_log.from_time
                try:
                    time_log.save()
                    break
                except WorkstationHolidayError:
                    time_log.move_to_next_day()
                except NotInWorkingHoursError:
                    time_log.move_to_next_working_slot()
                except OverlapError:
                    time_log.move_to_next_non_overlapping_slot()

                # reset end time
                time_log.to_time = get_datetime(
                    time_log.from_time) + relativedelta(minutes=d.time_in_mins)

                if date_diff(time_log.from_time,
                             original_start_time) > plan_days:
                    frappe.msgprint(
                        _("Unable to find Time Slot in the next {0} days for Operation {1}"
                          ).format(plan_days, d.operation))
                    break

                if _from_time == time_log.from_time:
                    frappe.throw("Capacity Planning Error")

            d.planned_start_time = time_log.from_time
            d.planned_end_time = time_log.to_time
            d.db_update()

            if time_log.name:
                time_logs.append(time_log.name)

        self.planned_end_date = self.operations[-1].planned_end_time

        if time_logs:
            frappe.local.message_log = []
            frappe.msgprint(
                _("Time Logs created:") + "\n" + "\n".join(time_logs))