示例#1
0
def set_auto_repeat_period(args, mcount, new_document):
    if mcount and new_document.meta.get_field(
            'from_date') and new_document.meta.get_field('to_date'):
        last_ref_doc = frappe.db.sql("""
			select name, from_date, to_date
			from `tab{0}`
			where auto_repeat=%s and docstatus < 2
			order by creation desc
			limit 1
		""".format(args.reference_doctype),
                                     args.name,
                                     as_dict=1)

        if not last_ref_doc:
            return

        from_date = get_next_date(last_ref_doc[0].from_date, mcount)

        if (cstr(get_first_day(last_ref_doc[0].from_date)) == cstr(last_ref_doc[0].from_date)) and \
          (cstr(get_last_day(last_ref_doc[0].to_date)) == cstr(last_ref_doc[0].to_date)):
            to_date = get_last_day(
                get_next_date(last_ref_doc[0].to_date, mcount))
        else:
            to_date = get_next_date(last_ref_doc[0].to_date, mcount)

        new_document.set('from_date', from_date)
        new_document.set('to_date', to_date)
    def calculate_amount(self, start_date, end_date):
        """
		start_date, end_date - datetime.datetime.date
		return - estimated amount to post for given period
		Calculated based on already booked amount and item service period
		"""
        total_months = (
            (self.service_end_date.year - self.service_start_date.year) * 12 +
            (self.service_end_date.month - self.service_start_date.month) + 1)

        prorate = date_diff(self.service_end_date,
                            self.service_start_date) / date_diff(
                                get_last_day(self.service_end_date),
                                get_first_day(self.service_start_date))

        actual_months = rounded(total_months * prorate, 1)

        already_booked_amount = self.get_item_total()
        base_amount = self.base_net_amount / actual_months

        if base_amount + already_booked_amount > self.base_net_amount:
            base_amount = self.base_net_amount - already_booked_amount

        if not (get_first_day(start_date) == start_date
                and get_last_day(end_date) == end_date):
            partial_month = flt(date_diff(end_date, start_date)) / flt(
                date_diff(get_last_day(end_date), get_first_day(start_date)))
            base_amount *= rounded(partial_month, 1)

        return base_amount
def make_new_document(ref_wrapper, date_field, posting_date):
    from erpnext.accounts.utils import get_fiscal_year
    new_document = frappe.copy_doc(ref_wrapper)
    mcount = month_map[ref_wrapper.recurring_type]

    from_date = get_next_date(ref_wrapper.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.from_date)) == \
      cstr(ref_wrapper.from_date)) and \
     (cstr(get_last_day(ref_wrapper.to_date)) == \
      cstr(ref_wrapper.to_date)):
        to_date = get_last_day(get_next_date(ref_wrapper.to_date, mcount))
    else:
        to_date = get_next_date(ref_wrapper.to_date, mcount)

    new_document.update({
        date_field: posting_date,
        "from_date": from_date,
        "to_date": to_date,
        "fiscal_year": get_fiscal_year(posting_date)[0],
        "owner": ref_wrapper.owner,
    })

    if ref_wrapper.doctype == "Sales Order":
        new_document.update({
            "delivery_date":
            get_next_date(ref_wrapper.delivery_date, mcount,
                          cint(ref_wrapper.repeat_on_day_of_month))
        })

    new_document.submit()

    return new_document
示例#4
0
	def test_empty_dashboard_chart(self):
		if frappe.db.exists('Dashboard Chart', 'Test Empty Dashboard Chart'):
			frappe.delete_doc('Dashboard Chart', 'Test Empty Dashboard Chart')

		frappe.db.sql('delete from `tabError Log`')

		frappe.get_doc(dict(
			doctype = 'Dashboard Chart',
			chart_name = 'Test Empty Dashboard Chart',
			chart_type = 'Count',
			document_type = 'Error Log',
			based_on = 'creation',
			timespan = 'Last Year',
			time_interval = 'Monthly',
			filters_json = '[]',
			timeseries = 1
		)).insert()

		cur_date = datetime.now() - relativedelta(years=1)

		result = get(chart_name ='Test Empty Dashboard Chart', refresh=1)
		self.assertEqual(result.get('labels')[0], formatdate(cur_date.strftime('%Y-%m-%d')))

		if formatdate(cur_date.strftime('%Y-%m-%d')) == formatdate(get_last_day(cur_date).strftime('%Y-%m-%d')):
			cur_date += relativedelta(months=1)

		for idx in range(1, 13):
			month = get_last_day(cur_date)
			month = formatdate(month.strftime('%Y-%m-%d'))
			self.assertEqual(result.get('labels')[idx], month)
			cur_date += relativedelta(months=1)

		frappe.db.rollback()
示例#5
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
示例#6
0
def get_next_dep_date(doc, dep_freq, tot_dep):
    #Next depreciation date shoud be last date of the purchase date if monthly or last date
    #of period of depreciation
    #if monthly depreciation then last day or month, if bi-monthly then last day of month+1
    #if 3 monthly then last day of quarter and not 3 months
    #if 4 monthly then last day of third and not 4 months and so on and so forth
    fy_doc = get_fy_doc(doc)
    r = relativedelta.relativedelta(add_days(fy_doc.year_end_date, 1),
                                    fy_doc.year_start_date)
    fy_months = r.years * 12 + r.months
    dep_in_fy = cint(fy_months) / flt(dep_freq)
    booked_deps_months = (cint(doc.number_of_depreciations_booked) *
                          cint(dep_freq))
    last_day = add_months(get_last_day(doc.purchase_date), booked_deps_months)
    base_last_day = get_last_day(doc.purchase_date)
    base_dep_date = None
    if dep_in_fy >= 1 and dep_in_fy % 1 == 0:
        for i in range(0, cint(tot_dep)):
            dep_date = get_last_day(
                add_months(fy_doc.year_start_date, (i * dep_freq - 1)))
            if base_last_day <= dep_date and base_dep_date is None:
                base_dep_date = dep_date

            if last_day <= dep_date:
                doc.next_depreciation_date = dep_date
                break
            else:
                doc.next_depreciation_date = fy_doc.year_end_date
    elif dep_in_fy % 1 != 0:
        frappe.throw(
            'Frequency Causing Depreciations not to be posted equally in FY, \
			please change the frequency of depreciation')
    else:
        frappe.throw('Months between depreciation cannot be less than 1')
    return base_dep_date
示例#7
0
def update_doc(new_document, reference_doc, args, schedule_date):
    new_document.docstatus = 0
    if new_document.meta.get_field('set_posting_time'):
        new_document.set('set_posting_time', 1)

    mcount = month_map.get(args.frequency)

    if new_document.meta.get_field('subscription'):
        new_document.set('subscription', args.name)

    if args.from_date and args.to_date:
        from_date = get_next_date(args.from_date, mcount)

        if (cstr(get_first_day(args.from_date)) == cstr(args.from_date)) and \
         (cstr(get_last_day(args.to_date)) == cstr(args.to_date)):
            to_date = get_last_day(get_next_date(args.to_date, mcount))
        else:
            to_date = get_next_date(args.to_date, mcount)

        if new_document.meta.get_field('from_date'):
            new_document.set('from_date', from_date)
            new_document.set('to_date', to_date)

    new_document.run_method("on_recurring",
                            reference_doc=reference_doc,
                            subscription_doc=args)
    for data in new_document.meta.fields:
        if data.fieldtype == 'Date' and data.reqd:
            new_document.set(data.fieldname, schedule_date)
示例#8
0
 def create_interests(self):
     get_start_date = compose(
         frappe.utils.get_first_day,
         partial(frappe.utils.add_months, self.billing_start_date),
     )
     for i in range(0, self.emi_duration):
         start_date = self.billing_start_date if i == 0 else get_start_date(
             i)
         end_date = get_last_day(start_date)
         period = start_date.strftime("%b %Y")
         frappe.get_doc({
             "doctype":
             "Microfinance Loan Interest",
             "loan":
             self.name,
             "posting_date":
             add_days(end_date, 1),
             "period":
             period,
             "start_date":
             start_date,
             "end_date":
             end_date,
             "billed_amount":
             self.monthly_interest,
             "principal_amount":
             self.loan_principal / self.emi_duration,
         }).insert(ignore_permissions=True)
     self.billing_end_date = get_last_day(
         frappe.utils.add_months(self.billing_start_date,
                                 self.emi_duration))
示例#9
0
def make_new_document(ref_wrapper, date_field, posting_date):
	from erpnext.accounts.utils import get_fiscal_year
	new_document = frappe.copy_doc(ref_wrapper)
	mcount = month_map[ref_wrapper.recurring_type]

	from_date = get_next_date(ref_wrapper.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.from_date)) == cstr(ref_wrapper.from_date)) and \
		(cstr(get_last_day(ref_wrapper.to_date)) == cstr(ref_wrapper.to_date)):
			to_date = get_last_day(get_next_date(ref_wrapper.to_date, mcount))
	else:
		to_date = get_next_date(ref_wrapper.to_date, mcount)

	new_document.update({
		date_field: posting_date,
		"from_date": from_date,
		"to_date": to_date,
		"fiscal_year": get_fiscal_year(posting_date)[0],
		"owner": ref_wrapper.owner,
	})

	if ref_wrapper.doctype == "Sales Order":
		new_document.update({
			"delivery_date": get_next_date(ref_wrapper.delivery_date, mcount,
				cint(ref_wrapper.repeat_on_day_of_month))
	})

	new_document.submit()

	return new_document
示例#10
0
	def set_auto_repeat_period(self, new_doc):
		mcount = month_map.get(self.frequency)
		if mcount and new_doc.meta.get_field("from_date") and new_doc.meta.get_field("to_date"):
			last_ref_doc = frappe.db.get_all(
				doctype=self.reference_doctype,
				fields=["name", "from_date", "to_date"],
				filters=[
					["auto_repeat", "=", self.name],
					["docstatus", "<", 2],
				],
				order_by="creation desc",
				limit=1,
			)

			if not last_ref_doc:
				return

			from_date = get_next_date(last_ref_doc[0].from_date, mcount)

			if (cstr(get_first_day(last_ref_doc[0].from_date)) == cstr(last_ref_doc[0].from_date)) and (
				cstr(get_last_day(last_ref_doc[0].to_date)) == cstr(last_ref_doc[0].to_date)
			):
				to_date = get_last_day(get_next_date(last_ref_doc[0].to_date, mcount))
			else:
				to_date = get_next_date(last_ref_doc[0].to_date, mcount)

			new_doc.set("from_date", from_date)
			new_doc.set("to_date", to_date)
示例#11
0
def validate_employee_advance(employee,date):
	policies = frappe.get_doc("Advance Salary Policies","Advance Salary Policies")
	employee_type = frappe.db.get_value("Employee",employee,"employment_type")
	if employee_type == "Probation":
		frappe.msgprint(_("Advance Salary Request Apply After Probation Period"))
		return False
	start_date = frappe.db.get_value("Employee",employee,"final_confirmation_date")
	if getdate(start_date) > getdate(date):
		frappe.msgprint(_("Advance Salary Request Apply After Probation Period"))
		return False
	if get_salary_advance_total(employee,date,policies) == True:
		frappe.msgprint(_("Already Applied Employee Advance In Last 6 Months"))
		return False
	sal_st = get_sal_structure(employee)
	salary_slip = make_salary_slip_custom(sal_st, employee=employee,start_date=get_first_day(date),end_date=add_days(get_first_day(date),19), ignore_permissions=True)
	if salary_slip.gross_pay > flt(policies.salary_should_be_below_or_equal_to):
		frappe.msgprint(_("Gross Pay Must Be Less Than or Equal {0}").format(policies.salary_should_be_below_or_equal_to))
		return False		
	holiday_list = get_holiday_list_for_employee(employee, False)
	attendance = get_filtered_date_list(employee, get_first_day(date), add_days(get_first_day(date),19),holiday_list)
	working_days = date_diff(get_last_day(date),get_first_day(date)) + 1
	gross_pay_day = salary_slip.gross_pay / working_days
	final_working_days = 20 - ((flt(salary_slip.total_working_days)-len(get_holidays_for_employee(employee,get_first_day(date), add_days(get_first_day(date),19)))) - flt(attendance))
	gross_pay_eligible_for_advance = (flt(gross_pay_day) * flt(final_working_days))
	loan = get_loan_amount(employee,get_first_day(date),get_last_day(date))
	return gross_pay_eligible_for_advance,loan
示例#12
0
    def set_auto_repeat_period(self, new_doc):
        mcount = month_map.get(self.frequency)
        if mcount and new_doc.meta.get_field(
                'from_date') and new_doc.meta.get_field('to_date'):
            last_ref_doc = frappe.db.get_all(
                doctype=self.reference_doctype,
                fields=['name', 'from_date', 'to_date'],
                filters=[
                    ['auto_repeat', '=', self.name],
                    ['docstatus', '<', 2],
                ],
                order_by='creation desc',
                limit=1)

            if not last_ref_doc:
                return

            from_date = get_next_date(last_ref_doc[0].from_date, mcount)

            if (cstr(get_first_day(last_ref_doc[0].from_date)) == cstr(last_ref_doc[0].from_date)) and \
              (cstr(get_last_day(last_ref_doc[0].to_date)) == cstr(last_ref_doc[0].to_date)):
                to_date = get_last_day(
                    get_next_date(last_ref_doc[0].to_date, mcount))
            else:
                to_date = get_next_date(last_ref_doc[0].to_date, mcount)

            new_doc.set('from_date', from_date)
            new_doc.set('to_date', to_date)
示例#13
0
def get_next_dep_date(doc, dep_freq, tot_dep):
	#Next depreciation date shoud be last date of the purchase date if monthly or last date
	#of period of depreciation
	#if monthly depreciation then last day or month, if bi-monthly then last day of month+1
	#if 3 monthly then last day of quarter and not 3 months
	#if 4 monthly then last day of third and not 4 months and so on and so forth
	fy_doc = get_fy_doc(doc)
	r = relativedelta.relativedelta(add_days(fy_doc.year_end_date,1), fy_doc.year_start_date)
	fy_months = r.years*12 + r.months
	dep_in_fy = cint(fy_months)/flt(dep_freq)
	booked_deps_months = (cint(doc.number_of_depreciations_booked)*cint(dep_freq))
	last_day = add_months(get_last_day(doc.purchase_date), booked_deps_months)
	base_last_day = get_last_day(doc.purchase_date)
	base_dep_date = None
	if dep_in_fy >= 1 and dep_in_fy % 1  == 0:
		for i in range(0, cint(tot_dep)):
			dep_date = get_last_day(add_months(fy_doc.year_start_date, (i*dep_freq -1)))
			if base_last_day <= dep_date and base_dep_date is None:
				base_dep_date = dep_date

			if last_day <= dep_date:
				doc.next_depreciation_date = dep_date
				break
			else:
				doc.next_depreciation_date = fy_doc.year_end_date
	elif dep_in_fy % 1  != 0:
		frappe.throw('Frequency Causing Depreciations not to be posted equally in FY, \
			please change the frequency of depreciation')
	else:
		frappe.throw('Months between depreciation cannot be less than 1')
	return base_dep_date
示例#14
0
def make_new_document(ref_wrapper, date_field, posting_date):
    from erpnext.accounts.utils import get_fiscal_year
    new_document = frappe.copy_doc(ref_wrapper)
    mcount = month_map[ref_wrapper.recurring_type]

    from_date = get_next_date(ref_wrapper.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.from_date)) == \
      cstr(ref_wrapper.from_date)) and \
     (cstr(get_last_day(ref_wrapper.to_date)) == \
      cstr(ref_wrapper.to_date)):
        to_date = get_last_day(get_next_date(ref_wrapper.to_date, mcount))
    else:
        to_date = get_next_date(ref_wrapper.to_date, mcount)

    new_document.update({
        date_field: posting_date,
        "from_date": from_date,
        "to_date": to_date,
        "fiscal_year": get_fiscal_year(posting_date)[0],
        "owner": ref_wrapper.owner,
        "docstatus": 0,
        "per_billed": 0,
        "per_delivered": 0,
        "billed_amt": 0,
        "delivery_status": "Not Delivered"
    })

    new_document.set("sales_order_details", [])

    for item in ref_wrapper.sales_order_details:
        new_item = new_document.append('sales_order_details', {})
        new_item.item_code = item.item_code
        new_item.qty = item.qty

        item_price = frappe.db.get_value(
            'Item Price', {
                'item_code': item.item_code,
                'price_list': new_document.selling_price_list
            },
            'price_list_rate',
            as_dict=True)
        if item_price:
            new_item.rate = item_price.get('price_list_rate', 0)

    if ref_wrapper.doctype == "Sales Order":
        new_document.update({
            "delivery_date":
            get_next_date(ref_wrapper.delivery_date, mcount,
                          cint(ref_wrapper.repeat_on_day_of_month))
        })

    new_document.save()

    return new_document
示例#15
0
def get_due_date(posting_date, term):
	due_date = None
	if term.due_date_based_on == "Day(s) after invoice date":
		due_date = add_days(posting_date, term.credit_days)
	elif term.due_date_based_on == "Day(s) after the end of the invoice month":
		due_date = add_days(get_last_day(posting_date), term.credit_days)
	elif term.due_date_based_on == "Month(s) after the end of the invoice month":
		due_date = add_months(get_last_day(posting_date), term.credit_months)

	return due_date
示例#16
0
def get_due_date(term, posting_date=None, bill_date=None):
    due_date = None
    date = bill_date or posting_date
    if term.due_date_based_on == "Day(s) after invoice date":
        due_date = add_days(date, term.credit_days)
    elif term.due_date_based_on == "Day(s) after the end of the invoice month":
        due_date = add_days(get_last_day(date), term.credit_days)
    elif term.due_date_based_on == "Month(s) after the end of the invoice month":
        due_date = add_months(get_last_day(date), term.credit_months)
    return due_date
示例#17
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),
            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))

        # check for disbursement accrual
        loan_interest_accrual = frappe.db.get_value(
            "Loan Interest Accrual", {
                "loan": loan.name,
                "accrual_type": "Disbursement"
            })

        self.assertTrue(loan_interest_accrual)
示例#18
0
def calculate_monthly_amount(
	doc, item, last_gl_entry, start_date, end_date, total_days, total_booking_days, account_currency
):
	amount, base_amount = 0, 0

	if not last_gl_entry:
		total_months = (
			(item.service_end_date.year - item.service_start_date.year) * 12
			+ (item.service_end_date.month - item.service_start_date.month)
			+ 1
		)

		prorate_factor = flt(date_diff(item.service_end_date, item.service_start_date)) / flt(
			date_diff(get_last_day(item.service_end_date), get_first_day(item.service_start_date))
		)

		actual_months = rounded(total_months * prorate_factor, 1)

		already_booked_amount, already_booked_amount_in_account_currency = get_already_booked_amount(
			doc, item
		)
		base_amount = flt(item.base_net_amount / actual_months, item.precision("base_net_amount"))

		if base_amount + already_booked_amount > item.base_net_amount:
			base_amount = item.base_net_amount - already_booked_amount

		if account_currency == doc.company_currency:
			amount = base_amount
		else:
			amount = flt(item.net_amount / actual_months, item.precision("net_amount"))
			if amount + already_booked_amount_in_account_currency > item.net_amount:
				amount = item.net_amount - already_booked_amount_in_account_currency

		if not (get_first_day(start_date) == start_date and get_last_day(end_date) == end_date):
			partial_month = flt(date_diff(end_date, start_date)) / flt(
				date_diff(get_last_day(end_date), get_first_day(start_date))
			)

			base_amount = rounded(partial_month, 1) * base_amount
			amount = rounded(partial_month, 1) * amount
	else:
		already_booked_amount, already_booked_amount_in_account_currency = get_already_booked_amount(
			doc, item
		)
		base_amount = flt(
			item.base_net_amount - already_booked_amount, item.precision("base_net_amount")
		)
		if account_currency == doc.company_currency:
			amount = base_amount
		else:
			amount = flt(
				item.net_amount - already_booked_amount_in_account_currency, item.precision("net_amount")
			)

	return amount, base_amount
示例#19
0
def get_pro_rata_amt(row, depreciation_amount, from_date, to_date):
	months = month_diff(to_date, from_date)
	if row.depreciation_method == "Prorated Straight Line (360 Days)":
		todate = get_last_day(from_date) if getdate(to_date).month == 12 else to_date
		fromdate = get_last_day(to_date) if getdate(from_date).month == 12 else from_date
		days = date_diff(todate, fromdate) + (cint(months) - 1) * 30
		total_days = min(get_total_days(to_date, row.frequency_of_depreciation), 360)
	else:
		total_days = get_total_days(to_date, row.frequency_of_depreciation)
		days = date_diff(to_date, from_date)

	return (depreciation_amount * flt(days)) / flt(total_days), days, months
示例#20
0
def make_new_document(reference_doc, date_field, posting_date):
    from erpnext.accounts.utils import get_fiscal_year
    new_document = frappe.copy_doc(reference_doc, ignore_no_copy=True)
    mcount = month_map[reference_doc.recurring_type]

    from_date = get_next_date(reference_doc.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(reference_doc.from_date)) == cstr(reference_doc.from_date)) and \
     (cstr(get_last_day(reference_doc.to_date)) == cstr(reference_doc.to_date)):
        to_date = get_last_day(get_next_date(reference_doc.to_date, mcount))
    else:
        to_date = get_next_date(reference_doc.to_date, mcount)

    new_document.update({
        date_field:
        posting_date,
        "from_date":
        from_date,
        "to_date":
        to_date,
        "fiscal_year":
        get_fiscal_year(posting_date)[0],
        "next_date":
        get_next_date(from_date, mcount,
                      cint(reference_doc.repeat_on_day_of_month))
    })

    # copy document fields
    for fieldname in ("owner", "recurring_type", "repeat_on_day_of_month",
                      "recurring_id", "notification_email_address",
                      "is_recurring", "end_date", "title", "naming_series",
                      "select_print_heading", "ignore_pricing_rule",
                      "posting_time", "remarks", 'submit_on_creation'):
        if new_document.meta.get_field(fieldname):
            new_document.set(fieldname, reference_doc.get(fieldname))

    # copy item fields
    for i, item in enumerate(new_document.items):
        for fieldname in ("page_break", ):
            item.set(fieldname, reference_doc.items[i].get(fieldname))

    new_document.run_method("on_recurring", reference_doc=reference_doc)

    if reference_doc.submit_on_creation:
        new_document.submit()
    else:
        new_document.docstatus = 0
        new_document.insert()

    return new_document
示例#21
0
def get_plan_rate(plan,
                  quantity=1,
                  customer=None,
                  start_date=None,
                  end_date=None,
                  prorate_factor=1):
    plan = frappe.get_doc("Subscription Plan", plan)
    if plan.price_determination == "Fixed Rate":
        return plan.cost * prorate_factor

    elif plan.price_determination == "Based On Price List":
        if customer:
            customer_group = frappe.db.get_value("Customer", customer,
                                                 "customer_group")
        else:
            customer_group = None

        price = get_price(item_code=plan.item,
                          price_list=plan.price_list,
                          customer_group=customer_group,
                          company=None,
                          qty=quantity)
        if not price:
            return 0
        else:
            return price.price_list_rate * prorate_factor

    elif plan.price_determination == 'Monthly Rate':
        start_date = getdate(start_date)
        end_date = getdate(end_date)

        no_of_months = (end_date.year - start_date.year) * 12 + (
            end_date.month - start_date.month) + 1
        cost = plan.cost * no_of_months

        # Adjust cost if start or end date is not month start or end
        prorate = frappe.db.get_single_value('Subscription Settings',
                                             'prorate')

        if prorate:
            prorate_factor = flt(
                date_diff(start_date, get_first_day(start_date)) /
                date_diff(get_last_day(start_date), get_first_day(start_date)),
                1)

            prorate_factor += flt(
                date_diff(get_last_day(end_date), end_date) /
                date_diff(get_last_day(end_date), get_first_day(end_date)), 1)

            cost -= (plan.cost * prorate_factor)

        return cost
    def test_loan_topup(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 = 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(posting_date=add_days(last_date, 1))

        # Paid 511095.89 amount includes 5,00,000 principal amount and 11095.89 interest amount
        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()

        make_loan_disbursement_entry(loan.name,
                                     500000,
                                     disbursement_date=add_days(last_date, 16))

        total_principal_paid = loan.total_principal_paid

        loan.reload()

        # Loan Topup will result in decreasing the Total Principal Paid
        self.assertEqual(flt(loan.total_principal_paid, 2),
                         flt(total_principal_paid - 500000, 2))
def make_new_document(ref_wrapper, date_field, posting_date):
	from erpnext.accounts.utils import get_fiscal_year
	new_document = frappe.copy_doc(ref_wrapper)
	mcount = month_map[ref_wrapper.recurring_type]

	from_date = get_next_date(ref_wrapper.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.from_date)) == cstr(ref_wrapper.from_date)) and \
		(cstr(get_last_day(ref_wrapper.to_date)) == cstr(ref_wrapper.to_date)):
			to_date = get_last_day(get_next_date(ref_wrapper.to_date, mcount))
	else:
		to_date = get_next_date(ref_wrapper.to_date, mcount)
def make_new_document(ref_wrapper, date_field, posting_date):
    from erpnext.accounts.utils import get_fiscal_year
    new_document = frappe.copy_doc(ref_wrapper)
    mcount = month_map[ref_wrapper.recurring_type]

    from_date = get_next_date(ref_wrapper.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.from_date)) == cstr(ref_wrapper.from_date)) and \
     (cstr(get_last_day(ref_wrapper.to_date)) == cstr(ref_wrapper.to_date)):
        to_date = get_last_day(get_next_date(ref_wrapper.to_date, mcount))
    else:
        to_date = get_next_date(ref_wrapper.to_date, mcount)
示例#25
0
	def validate_asset_finance_books(self, row):
		if flt(row.expected_value_after_useful_life) >= flt(self.gross_purchase_amount):
			frappe.throw(_("Row {0}: Expected Value After Useful Life must be less than Gross Purchase Amount")
				.format(row.idx))

		if not row.depreciation_start_date:
			if not self.available_for_use_date:
				frappe.throw(_("Row {0}: Depreciation Start Date is required").format(row.idx))
			row.depreciation_start_date = get_last_day(self.available_for_use_date)

		if not self.is_existing_asset:
			self.opening_accumulated_depreciation = 0
			self.number_of_depreciations_booked = 0
		else:
			depreciable_amount = flt(self.gross_purchase_amount) - flt(row.expected_value_after_useful_life)
			if flt(self.opening_accumulated_depreciation) > depreciable_amount:
					frappe.throw(_("Opening Accumulated Depreciation must be less than equal to {0}")
						.format(depreciable_amount))

			if self.opening_accumulated_depreciation:
				if not self.number_of_depreciations_booked:
					frappe.throw(_("Please set Number of Depreciations Booked"))
			else:
				self.number_of_depreciations_booked = 0

			if cint(self.number_of_depreciations_booked) > cint(row.total_number_of_depreciations):
				frappe.throw(_("Number of Depreciations Booked cannot be greater than Total Number of Depreciations"))

		if row.depreciation_start_date and getdate(row.depreciation_start_date) < getdate(self.purchase_date):
			frappe.throw(_("Depreciation Row {0}: Next Depreciation Date cannot be before Purchase Date")
				.format(row.idx))

		if row.depreciation_start_date and getdate(row.depreciation_start_date) < getdate(self.available_for_use_date):
			frappe.throw(_("Depreciation Row {0}: Next Depreciation Date cannot be before Available-for-use Date")
				.format(row.idx))
示例#26
0
	def test_create_asset_maintenance(self):
		pr = make_purchase_receipt(item_code="Photocopier",
			qty=1, rate=100000.0, location="Test Location")

		asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name')
		asset_doc = frappe.get_doc('Asset', asset_name)
		month_end_date = get_last_day(nowdate())

		purchase_date = nowdate() if nowdate() != month_end_date else add_days(nowdate(), -15)

		asset_doc.available_for_use_date = purchase_date
		asset_doc.purchase_date = purchase_date

		asset_doc.calculate_depreciation = 1
		asset_doc.append("finance_books", {
			"expected_value_after_useful_life": 200,
			"depreciation_method": "Straight Line",
			"total_number_of_depreciations": 3,
			"frequency_of_depreciation": 10,
			"depreciation_start_date": month_end_date
		})

		asset_doc.save()

		if not frappe.db.exists("Asset Maintenance", "Photocopier"):
			asset_maintenance =	frappe.get_doc({
					"doctype": "Asset Maintenance",
					"asset_name": "Photocopier",
					"maintenance_team": "Team Awesome",
					"company": "_Test Company",
					"asset_maintenance_tasks": get_maintenance_tasks()
				}).insert()

			next_due_date = calculate_next_due_date(nowdate(), "Monthly")
			self.assertEqual(asset_maintenance.asset_maintenance_tasks[0].next_due_date, next_due_date)
示例#27
0
def get_booking_dates(doc, item, posting_date=None):
	if not posting_date:
		posting_date = add_days(today(), -1)

	last_gl_entry = False

	deferred_account = "deferred_revenue_account" if doc.doctype=="Sales Invoice" else "deferred_expense_account"

	prev_gl_entry = frappe.db.sql('''
		select name, posting_date from `tabGL Entry` where company=%s and account=%s and
		voucher_type=%s and voucher_no=%s and voucher_detail_no=%s
		order by posting_date desc limit 1
	''', (doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name), as_dict=True)

	if prev_gl_entry:
		start_date = getdate(add_days(prev_gl_entry[0].posting_date, 1))
	else:
		start_date = item.service_start_date

	end_date = get_last_day(start_date)
	if end_date >= item.service_end_date:
		end_date = item.service_end_date
		last_gl_entry = True
	elif item.service_stop_date and end_date >= item.service_stop_date:
		end_date = item.service_stop_date
		last_gl_entry = True

	if end_date > getdate(posting_date):
		end_date = posting_date

	if getdate(start_date) <= getdate(end_date):
		return start_date, end_date, last_gl_entry
	else:
		return None, None, None
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
	def _test(i):
		obj.assertEquals(i+1, frappe.db.sql("""select count(*) from `tab%s`
			where recurring_id=%s and (docstatus=1 or docstatus=0)""" % (base_doc.doctype, '%s'),
			(base_doc.recurring_id))[0][0])

		next_date = get_next_date(base_doc.get(date_field), no_of_months,
			base_doc.repeat_on_day_of_month)

		manage_recurring_documents(base_doc.doctype, next_date=next_date, commit=False)

		recurred_documents = frappe.db.sql("""select name from `tab%s`
			where recurring_id=%s and (docstatus=1 or docstatus=0) order by name desc"""
			% (base_doc.doctype, '%s'), (base_doc.recurring_id))

		obj.assertEquals(i+2, len(recurred_documents))

		new_doc = frappe.get_doc(base_doc.doctype, recurred_documents[0][0])

		for fieldname in ["is_recurring", "recurring_type",
			"repeat_on_day_of_month", "notification_email_address"]:
				obj.assertEquals(base_doc.get(fieldname),
					new_doc.get(fieldname))

		obj.assertEquals(new_doc.get(date_field), getdate(next_date))

		obj.assertEquals(new_doc.from_date,	getdate(add_months(base_doc.from_date, no_of_months)))

		if first_and_last_day:
			obj.assertEquals(new_doc.to_date, getdate(get_last_day(add_months(base_doc.to_date, no_of_months))))
		else:
			obj.assertEquals(new_doc.to_date, getdate(add_months(base_doc.to_date, no_of_months)))

		return new_doc
示例#30
0
def validate_expense_against_budget(args):
	args = frappe._dict(args)
	if not args.cost_center:
		return
		
	if frappe.db.get_value("Account", {"name": args.account, "root_type": "Expense"}):
		cc_lft, cc_rgt = frappe.db.get_value("Cost Center", args.cost_center, ["lft", "rgt"])

		budget_records = frappe.db.sql("""
			select ba.budget_amount, b.monthly_distribution, b.cost_center,
				b.action_if_annual_budget_exceeded, b.action_if_accumulated_monthly_budget_exceeded
			from `tabBudget` b, `tabBudget Account` ba
			where
				b.name=ba.parent and b.fiscal_year=%s and ba.account=%s and b.docstatus=1
				and exists(select name from `tabCost Center` where lft<=%s and rgt>=%s and name=b.cost_center)
		""", (args.fiscal_year, args.account, cc_lft, cc_rgt), as_dict=True)

		for budget in budget_records:
			if budget.budget_amount:
				yearly_action = budget.action_if_annual_budget_exceeded
				monthly_action = budget.action_if_accumulated_monthly_budget_exceeded

				if monthly_action in ["Stop", "Warn"]:
					budget_amount = get_accumulated_monthly_budget(budget.monthly_distribution,
						args.posting_date, args.fiscal_year, budget.budget_amount)

					args["month_end_date"] = get_last_day(args.posting_date)
						
					compare_expense_with_budget(args, budget.cost_center,
						budget_amount, _("Accumulated Monthly"), monthly_action)

				if yearly_action in ("Stop", "Warn") and monthly_action != "Stop" \
					and yearly_action != monthly_action:
						compare_expense_with_budget(args, budget.cost_center,
							flt(budget.budget_amount), _("Annual"), yearly_action)
    def test_current_asset_value(self):
        pr = make_purchase_receipt(item_code="Macbook Pro",
                                   qty=1,
                                   rate=100000.0,
                                   location="Test Location")

        asset_name = frappe.db.get_value("Asset",
                                         {"purchase_receipt": pr.name}, 'name')
        asset_doc = frappe.get_doc('Asset', asset_name)

        month_end_date = get_last_day(nowdate())
        purchase_date = nowdate() if nowdate() != month_end_date else add_days(
            nowdate(), -15)

        asset_doc.available_for_use_date = purchase_date
        asset_doc.purchase_date = purchase_date
        asset_doc.calculate_depreciation = 1
        asset_doc.append(
            "finance_books", {
                "expected_value_after_useful_life": 200,
                "depreciation_method": "Straight Line",
                "total_number_of_depreciations": 3,
                "frequency_of_depreciation": 10,
                "depreciation_start_date": month_end_date
            })
        asset_doc.submit()

        current_value = get_current_asset_value(asset_doc.name)
        self.assertEqual(current_value, 100000.0)
示例#32
0
def copy_timesheet_for_rest_day(name):
    time_sheet_doc = frappe.get_doc("Timesheet", name)
    last_day = get_last_day(time_sheet_doc.start_date)
    cur_date = add_days(time_sheet_doc.start_date, 1)
    count = 1
    while getdate(last_day) >= getdate(cur_date):
        time_dict = []
        for row in time_sheet_doc.time_logs:
            time_json = {}
            time_json["activity_type"] = row.activity_type
            time_json["from_time"] = add_days(row.from_time, count)
            time_json["to_time"] = add_days(row.to_time, count)
            time_dict.append(time_json)

        doc = frappe.get_doc(
            dict(doctype="Timesheet",
                 employee=time_sheet_doc.employee,
                 company=time_sheet_doc.company,
                 time_logs=time_dict)).insert()
        timesheet_submit_on_duplicate = frappe.db.get_value(
            "Global FM Setting", "Global FM Setting",
            "timesheet_submit_on_duplicate")
        if int(timesheet_submit_on_duplicate) == 1:
            doc.submit()
        cur_date = add_days(cur_date, 1)
        count += 1
    frappe.msgprint(str(count) + " Timesheet Added")
示例#33
0
def create_salary_slips_for_payroll_period(employee,
                                           salary_structure,
                                           payroll_period,
                                           deduct_random=True):
    deducted_dates = []
    i = 0
    while i < 12:
        slip = frappe.get_doc({
            "doctype": "Salary Slip",
            "employee": employee,
            "salary_structure": salary_structure,
            "frequency": "Monthly"
        })
        if i == 0:
            posting_date = add_days(payroll_period.start_date, 25)
        else:
            posting_date = add_months(posting_date, 1)
        if i == 11:
            slip.deduct_tax_for_unsubmitted_tax_exemption_proof = 1
            slip.deduct_tax_for_unclaimed_employee_benefits = 1
        if deduct_random and not random.randint(0, 2):
            slip.deduct_tax_for_unsubmitted_tax_exemption_proof = 1
            deducted_dates.append(posting_date)
        slip.posting_date = posting_date
        slip.start_date = get_first_day(posting_date)
        slip.end_date = get_last_day(posting_date)
        doc = make_salary_slip(salary_structure, slip, employee)
        doc.submit()
        i += 1
    return deducted_dates
示例#34
0
    def test_empty_dashboard_chart(self):
        if frappe.db.exists("Dashboard Chart", "Test Empty Dashboard Chart"):
            frappe.delete_doc("Dashboard Chart", "Test Empty Dashboard Chart")

        frappe.db.sql("delete from `tabError Log`")

        frappe.get_doc(
            dict(
                doctype="Dashboard Chart",
                chart_name="Test Empty Dashboard Chart",
                chart_type="Count",
                document_type="Error Log",
                based_on="creation",
                timespan="Last Year",
                time_interval="Monthly",
                filters_json="[]",
                timeseries=1,
            )).insert()

        cur_date = datetime.now() - relativedelta(years=1)

        result = get(chart_name="Test Empty Dashboard Chart", refresh=1)

        for idx in range(13):
            month = get_last_day(cur_date)
            month = formatdate(month.strftime("%Y-%m-%d"))
            self.assertEqual(result.get("labels")[idx], get_period(month))
            cur_date += relativedelta(months=1)

        frappe.db.rollback()
示例#35
0
    def test_earned_leave_allocation(self):
        leave_period = create_leave_period("Test Earned Leave Period")
        leave_type = create_earned_leave_type("Test Earned Leave")

        leave_policy = frappe.get_doc({
            "doctype":
            "Leave Policy",
            "title":
            "Test Leave Policy",
            "leave_policy_details": [{
                "leave_type": leave_type.name,
                "annual_allocation": 6
            }],
        }).submit()

        data = {
            "assignment_based_on": "Leave Period",
            "leave_policy": leave_policy.name,
            "leave_period": leave_period.name,
        }

        # second last day of the month
        # leaves allocated should be 0 since it is an earned leave and allocation happens via scheduler based on set frequency
        frappe.flags.current_date = add_days(get_last_day(getdate()), -1)
        leave_policy_assignments = create_assignment_for_multiple_employees(
            [self.employee.name], frappe._dict(data))

        leaves_allocated = frappe.db.get_value(
            "Leave Allocation",
            {"leave_policy_assignment": leave_policy_assignments[0]},
            "total_leaves_allocated",
        )
        self.assertEqual(leaves_allocated, 0)
示例#36
0
	def test_create_asset_maintenance(self):
		pr = make_purchase_receipt(item_code="Photocopier",
			qty=1, rate=100000.0, location="Test Location")

		asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name')
		asset_doc = frappe.get_doc('Asset', asset_name)
		month_end_date = get_last_day(nowdate())

		purchase_date = nowdate() if nowdate() != month_end_date else add_days(nowdate(), -15)

		asset_doc.available_for_use_date = purchase_date
		asset_doc.purchase_date = purchase_date

		asset_doc.calculate_depreciation = 1
		asset_doc.append("finance_books", {
			"expected_value_after_useful_life": 200,
			"depreciation_method": "Straight Line",
			"total_number_of_depreciations": 3,
			"frequency_of_depreciation": 10,
			"depreciation_start_date": month_end_date
		})

		asset_doc.save()

		if not frappe.db.exists("Asset Maintenance", "Photocopier"):
			asset_maintenance =	frappe.get_doc({
					"doctype": "Asset Maintenance",
					"asset_name": "Photocopier",
					"maintenance_team": "Team Awesome",
					"company": "_Test Company",
					"asset_maintenance_tasks": get_maintenance_tasks()
				}).insert()

			next_due_date = calculate_next_due_date(nowdate(), "Monthly")
			self.assertEqual(asset_maintenance.asset_maintenance_tasks[0].next_due_date, next_due_date)
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
示例#38
0
    def test_dashboard_chart(self):
        if frappe.db.exists('Dashboard Chart', 'Test Dashboard Chart'):
            frappe.delete_doc('Dashboard Chart', 'Test Dashboard Chart')

        frappe.get_doc(
            dict(doctype='Dashboard Chart',
                 chart_name='Test Dashboard Chart',
                 chart_type='Count',
                 document_type='DocType',
                 based_on='creation',
                 timespan='Last Year',
                 time_interval='Monthly',
                 filters_json='{}',
                 timeseries=1)).insert()

        cur_date = datetime.now() - relativedelta(years=1)

        result = get(chart_name='Test Dashboard Chart', refresh=1)

        for idx in range(13):
            month = get_last_day(cur_date)
            month = formatdate(month.strftime('%Y-%m-%d'))
            self.assertEqual(result.get('labels')[idx], get_period(month))
            cur_date += relativedelta(months=1)

        frappe.db.rollback()
def sms_limit(doc, method=None):
    limitations = frappe.get_single("Site Limitations")
    if not limitations.enable or not limitations.sms_restrictions:
        return

    allowed_sms = limitations.sms_allowed
    today = getdate()
    end_day = get_last_day(today)
    start_day = get_first_day(today)
    if limitations.enable_sms_dates:
        end_day = limitations.sms_to_date
        start_day = limitations.sms_from_date
    query = """ 
            SELECT
               COUNT(name)
            FROM
                `tabSMS Log`
            WHERE
                DATE(sent_on) BETWEEN '{start_day}' AND '{end_day}'
            """.format(start_day=start_day, end_day=end_day)
    sms_list = frappe.db.sql(query, as_dict=True)
    sms_count = sms_list[0]['COUNT(name)']
    contact = frappe.get_value("ISupport Settings", None,
                               "support_email") or "System Administrator"

    if sms_count > allowed_sms:
        frappe.throw(
            'Only {} SMS allowed and you have sent {} SMS. To increase the limit please contact {}'
            .format(allowed_sms, sms_count, contact))
示例#40
0
def update_late_fees(customer):
	now_date = datetime.now().date()
	firstDay_of_month = date(now_date.year, now_date.month, 1)
	last_day_of_month = get_last_day(now_date)
	
	# Get All Open Agreement of Customer
	customer_agreements = frappe.db.sql("""select name from `tabCustomer Agreement`
										where agreement_status = "Open" and late_fees_updated="No" and customer = '{0}'""".format(customer),as_list=1)
	firstDay_this_month = date(now_date.year, now_date.month, 1)
	
	for agreement in customer_agreements:
		total_late_fees = 0
		agreement_doc =frappe.get_doc("Customer Agreement",agreement[0])
		for row in agreement_doc.payments_record:
			
			if row.check_box_of_submit == 0 and getdate(row.due_date) >= firstDay_of_month and getdate(row.due_date) <= now_date:
				if date_diff(now_date,row.due_date) > 3:
					no_of_late_days = date_diff(now_date,row.due_date) - 3
					row.late_fee_for_payment = "{0:.2f}".format(float(no_of_late_days * agreement_doc.monthly_rental_payment * (agreement_doc.late_fees_rate/100)))
					total_late_fees = float(total_late_fees) + float(row.late_fee_for_payment)
			
			if (row.pre_select_uncheck == 0 and row.check_box_of_submit == 0 and getdate(row.due_date) < firstDay_this_month):
				if date_diff(now_date,row.due_date) > 3:
					no_of_late_days = date_diff(now_date,row.due_date) - 3
					row.late_fee_for_payment = "{0:.2f}".format(float(no_of_late_days * agreement_doc.monthly_rental_payment * (agreement_doc.late_fees_rate/100)))
					total_late_fees = float(total_late_fees) + float(row.late_fee_for_payment)

		agreement_doc.late_fees = total_late_fees
		agreement_doc.save(ignore_permissions = True)
def make_new_document(reference_doc, date_field, posting_date):
	from erpnext.accounts.utils import get_fiscal_year
	new_document = frappe.copy_doc(reference_doc, ignore_no_copy=True)
	mcount = month_map[reference_doc.recurring_type]

	from_date = get_next_date(reference_doc.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(reference_doc.from_date)) == cstr(reference_doc.from_date)) and \
		(cstr(get_last_day(reference_doc.to_date)) == cstr(reference_doc.to_date)):
			to_date = get_last_day(get_next_date(reference_doc.to_date, mcount))
	else:
		to_date = get_next_date(reference_doc.to_date, mcount)

	new_document.update({
		date_field: posting_date,
		"from_date": from_date,
		"to_date": to_date,
		"fiscal_year": get_fiscal_year(posting_date)[0],
        	"next_date": get_next_date(from_date, mcount,cint(reference_doc.repeat_on_day_of_month))
	})

	# copy document fields
	for fieldname in ("owner", "recurring_type", "repeat_on_day_of_month",
		"recurring_id", "notification_email_address", "is_recurring", "end_date",
		"title", "naming_series", "select_print_heading", "ignore_pricing_rule",
		"posting_time", "remarks", 'submit_on_creation'):
		if new_document.meta.get_field(fieldname):
			new_document.set(fieldname, reference_doc.get(fieldname))

	# copy item fields
	for i, item in enumerate(new_document.items):
		for fieldname in ("page_break",):
			item.set(fieldname, reference_doc.items[i].get(fieldname))

	new_document.run_method("on_recurring", reference_doc=reference_doc)

	if reference_doc.submit_on_creation:
		new_document.submit()
	else:
		new_document.docstatus=0
		new_document.insert()

	return new_document
示例#42
0
	def get_employee_holidays(self):
		first_day = get_first_day(self.att_date)
		last_day = get_last_day(self.att_date)
		
		holidays = frappe.db.sql("""select t1.holiday_date from `tabHoliday` t1, tabEmployee t2 where 
			t1.parent = t2.holiday_list and t2.name = %s and t1.holiday_date between %s and %s""",(self.employee, first_day, last_day))
		holidays = [cstr(i[0]) for i in holidays]

		if self.status in ('Weekly Off', 'Public Holiday') and self.att_date not in holidays:
			frappe.throw(_("This date not present in Holiday list.Please select correct date.."))
示例#43
0
文件: party.py 项目: ci2014/erpnext
def get_due_date_from_template(template_name, posting_date, bill_date):
	"""
	Inspects all `Payment Term`s from the a `Payment Terms Template` and returns the due
	date after considering all the `Payment Term`s requirements.
	:param template_name: Name of the `Payment Terms Template`
	:return: String representing the calculated due date
	"""
	due_date = getdate(bill_date or posting_date)

	template = frappe.get_doc('Payment Terms Template', template_name)

	for term in template.terms:
		if term.due_date_based_on == 'Day(s) after invoice date':
			due_date = max(due_date, add_days(due_date, term.credit_days))
		elif term.due_date_based_on == 'Day(s) after the end of the invoice month':
			due_date = max(due_date, add_days(get_last_day(due_date), term.credit_days))
		else:
			due_date = max(due_date, add_months(get_last_day(due_date), term.credit_months))
	return due_date
示例#44
0
def set_subscription_period(args, mcount, new_document):
	if mcount and new_document.meta.get_field('from_date') and new_document.meta.get_field('to_date'):
		last_ref_doc = frappe.db.sql("""
			select name, from_date, to_date
			from `tab{0}`
			where subscription=%s and docstatus < 2
			order by creation desc
			limit 1
		""".format(args.reference_doctype), args.name, as_dict=1)

		if not last_ref_doc:
			return

		from_date = get_next_date(last_ref_doc[0].from_date, mcount)

		if (cstr(get_first_day(last_ref_doc[0].from_date)) == cstr(last_ref_doc[0].from_date)) and \
			(cstr(get_last_day(last_ref_doc[0].to_date)) == cstr(last_ref_doc[0].to_date)):
				to_date = get_last_day(get_next_date(last_ref_doc[0].to_date, mcount))
		else:
			to_date = get_next_date(last_ref_doc[0].to_date, mcount)

		new_document.set('from_date', from_date)
		new_document.set('to_date', to_date)
示例#45
0
	def test_purchase_asset(self):
		pr = make_purchase_receipt(item_code="Macbook Pro",
			qty=1, rate=100000.0, location="Test Location")

		asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name')
		asset = frappe.get_doc('Asset', asset_name)
		asset.calculate_depreciation = 1

		month_end_date = get_last_day(nowdate())
		purchase_date = nowdate() if nowdate() != month_end_date else add_days(nowdate(), -15)

		asset.available_for_use_date = purchase_date
		asset.purchase_date = purchase_date
		asset.append("finance_books", {
			"expected_value_after_useful_life": 10000,
			"depreciation_method": "Straight Line",
			"total_number_of_depreciations": 3,
			"frequency_of_depreciation": 10,
			"depreciation_start_date": month_end_date
		})
		asset.submit()

		pi = make_purchase_invoice(asset.name, asset.item_code, asset.gross_purchase_amount,
			asset.company, asset.purchase_date)
		pi.supplier = "_Test Supplier"
		pi.insert()
		pi.submit()
		asset.load_from_db()
		self.assertEqual(asset.supplier, "_Test Supplier")
		self.assertEqual(asset.purchase_date, getdate(purchase_date))
		self.assertEqual(asset.purchase_invoice, pi.name)

		expected_gle = (
			("Asset Received But Not Billed - _TC", 100000.0, 0.0),
			("Creditors - _TC", 0.0, 100000.0)
		)

		gle = frappe.db.sql("""select account, debit, credit from `tabGL Entry`
			where voucher_type='Purchase Invoice' and voucher_no = %s
			order by account""", pi.name)
		self.assertEqual(gle, expected_gle)

		pi.cancel()

		asset.load_from_db()
		self.assertEqual(asset.supplier, None)
		self.assertEqual(asset.purchase_invoice, None)

		self.assertFalse(frappe.db.get_value("GL Entry",
			{"voucher_type": "Purchase Invoice", "voucher_no": pi.name}))
示例#46
0
文件: asset.py 项目: drukhil/erpnext
	def make_depreciation_schedule(self):
		self.schedules = []
		done = ""
		if not self.get("schedules") and self.next_depreciation_date:
			accumulated_depreciation = flt(self.opening_accumulated_depreciation)
			income_accumulated_depreciation = flt(self.income_tax_opening_depreciation_amount)
			value_after_depreciation = flt(self.value_after_depreciation)
			current_value_income_tax = flt(self.value_after_depreciation) - flt(self.expected_value_after_useful_life)

			number_of_pending_depreciations = cint(self.total_number_of_depreciations) - \
				cint(self.number_of_depreciations_booked)
			if number_of_pending_depreciations:
				for n in xrange(number_of_pending_depreciations):
					schedule_date = get_last_day(add_months(self.next_depreciation_date,
						n * cint(self.frequency_of_depreciation)))

					last_schedule_date = add_months(self.next_depreciation_date,
						(n - 1) * cint(self.frequency_of_depreciation))

					if n == 0:
						num_of_days = get_number_of_days(self.purchase_date, schedule_date) + 1
					else:
						num_of_days = get_number_of_days(last_schedule_date, schedule_date)

					depreciation_amount = self.get_depreciation_amount(value_after_depreciation, num_of_days)
					income_tax_amount = self.get_income_tax_depreciation_amount(current_value_income_tax, flt(self.asset_depreciation_percent), num_of_days)

					accumulated_depreciation += flt(depreciation_amount)
					value_after_depreciation -= flt(depreciation_amount)
					income_accumulated_depreciation += income_tax_amount
					
					if accumulated_depreciation < self.gross_purchase_amount:
						self.append("schedules", {
							"schedule_date": schedule_date,
							"depreciation_amount": depreciation_amount,
							"depreciation_income_tax": income_tax_amount,
							"accumulated_depreciation_amount": accumulated_depreciation,
							"accumulated_depreciation_income_tax": income_accumulated_depreciation
						})
					else:
						self.append("schedules", {
							"schedule_date": schedule_date,
							"depreciation_amount": flt(self.gross_purchase_amount) - flt(accumulated_depreciation) + flt(self.expected_value_after_useful_life) + flt(depreciation_amount),
							"depreciation_income_tax": income_tax_amount,
							"accumulated_depreciation_amount": flt(self.gross_purchase_amount) - flt(self.expected_value_after_useful_life),
							"accumulated_depreciation_income_tax": income_accumulated_depreciation
						})
						break
示例#47
0
def validate_budget_records(args, budget_records):
	for budget in budget_records:
		if flt(budget.budget_amount):
			yearly_action = budget.action_if_annual_budget_exceeded
			monthly_action = budget.action_if_accumulated_monthly_budget_exceeded

			if monthly_action in ["Stop", "Warn"]:
				budget_amount = get_accumulated_monthly_budget(budget.monthly_distribution,
					args.posting_date, args.fiscal_year, budget.budget_amount)
				args["month_end_date"] = get_last_day(args.posting_date)

				compare_expense_with_budget(args, budget_amount, 
					_("Accumulated Monthly"), monthly_action, budget.budget_against)

			if yearly_action in ("Stop", "Warn") and monthly_action != "Stop" \
				and yearly_action != monthly_action:
				compare_expense_with_budget(args, flt(budget.budget_amount), 
						_("Annual"), yearly_action, budget.budget_against)
示例#48
0
	def test_movement_for_serialized_asset(self):
		asset_item = "Test Serialized Asset Item"
		pr = make_purchase_receipt(item_code=asset_item, rate = 1000, qty=3, location = "Mumbai")
		asset_name = frappe.db.get_value('Asset', {'purchase_receipt': pr.name}, 'name')

		asset = frappe.get_doc('Asset', asset_name)
		month_end_date = get_last_day(nowdate())
		asset.available_for_use_date = nowdate() if nowdate() != month_end_date else add_days(nowdate(), -15)

		asset.calculate_depreciation = 1
		asset.append("finance_books", {
			"expected_value_after_useful_life": 200,
			"depreciation_method": "Straight Line",
			"total_number_of_depreciations": 3,
			"frequency_of_depreciation": 10,
			"depreciation_start_date": month_end_date
		})
		asset.submit()
		serial_nos = frappe.db.get_value('Asset Movement', {'reference_name': pr.name}, 'serial_no')

		mov1 = create_asset_movement(asset=asset_name, purpose = 'Transfer',
			company=asset.company, source_location = "Mumbai", target_location="Pune", serial_no=serial_nos)
		self.assertEqual(mov1.target_location, "Pune")

		serial_no = frappe.db.get_value('Serial No', {'asset': asset_name}, 'name')

		employee = make_employee("*****@*****.**")
		create_asset_movement(asset=asset_name, purpose = 'Transfer',
			company=asset.company, serial_no=serial_no, to_employee=employee)

		self.assertEqual(frappe.db.get_value('Serial No', serial_no, 'employee'), employee)

		create_asset_movement(asset=asset_name, purpose = 'Transfer', company=asset.company,
			serial_no=serial_no, from_employee=employee, to_employee="_T-Employee-00001")

		self.assertEqual(frappe.db.get_value('Serial No', serial_no, 'location'), "Pune")

		mov4 = create_asset_movement(asset=asset_name, purpose = 'Transfer',
			company=asset.company, source_location = "Pune", target_location="Nagpur", serial_no=serial_nos)
		self.assertEqual(mov4.target_location, "Nagpur")
		self.assertEqual(frappe.db.get_value('Serial No', serial_no, 'location'), "Nagpur")
		self.assertEqual(frappe.db.get_value('Serial No', serial_no, 'employee'), "_T-Employee-00001")
示例#49
0
文件: budget.py 项目: drukhil/erpnext
def validate_expense_against_budget(args):
	args = frappe._dict(args)
	if args.against_voucher_type == 'Asset':
		pass
	elif frappe.db.get_value("Account", {"name": args.account, "root_type": "Expense"}) or frappe.db.get_value("Account", {"name": args.account, "root_type": "Asset", "account_type": "Fixed Asset"}):
		cc_lft, cc_rgt = frappe.db.get_value("Cost Center", args.cost_center, ["lft", "rgt"])

		budget_records = frappe.db.sql("""
			select ba.budget_amount, b.monthly_distribution, b.cost_center,
				b.action_if_annual_budget_exceeded, b.action_if_accumulated_monthly_budget_exceeded
			from `tabBudget` b, `tabBudget Account` ba
			where
				b.name=ba.parent and b.fiscal_year=%s and ba.account=%s and b.docstatus=1
				and exists(select name from `tabCost Center` where lft<=%s and rgt>=%s and name=b.cost_center)
		""", (args.fiscal_year, args.account, cc_lft, cc_rgt), as_dict=True)

		if budget_records:
			for budget in budget_records:
				if budget.budget_amount:
					yearly_action = budget.action_if_annual_budget_exceeded
					monthly_action = budget.action_if_accumulated_monthly_budget_exceeded

					if monthly_action in ["Stop", "Warn"]:
						budget_amount = get_accumulated_monthly_budget(budget.monthly_distribution,
							args.posting_date, args.fiscal_year, budget.budget_amount)

						args["month_end_date"] = get_last_day(args.posting_date)
							
						compare_expense_with_budget(args, budget.cost_center,
							budget_amount, _("Accumulated Monthly"), monthly_action)

					if yearly_action in ("Stop", "Warn") and monthly_action != "Stop" \
						and yearly_action != monthly_action:
							compare_expense_with_budget(args, budget.cost_center,
								flt(budget.budget_amount), _("Annual"), yearly_action)
		elif args.account in ['Normal Loss - SMCL', 'Abnormal Loss - SMCL', 'Cost of Good Manufacture - SMCL', 'Stripping Cost Amortization - SMCL']:
			pass
		elif str(frappe.db.get_value("Account", args.account, "parent_account")) == "Depreciation & Amortisation - SMCL":
			pass
		else:
			#Budget Check if there is no budget booking under the budget head
			frappe.throw("There is no budget in " + args.account + " under " + args.cost_center + " for " + str(args.fiscal_year))
	def test_asset_depreciation_value_adjustment(self):
		pr = make_purchase_receipt(item_code="Macbook Pro",
			qty=1, rate=100000.0, location="Test Location")

		asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name')
		asset_doc = frappe.get_doc('Asset', asset_name)
		asset_doc.calculate_depreciation = 1

		month_end_date = get_last_day(nowdate())
		purchase_date = nowdate() if nowdate() != month_end_date else add_days(nowdate(), -15)

		asset_doc.available_for_use_date = purchase_date
		asset_doc.purchase_date = purchase_date
		asset_doc.calculate_depreciation = 1
		asset_doc.append("finance_books", {
			"expected_value_after_useful_life": 200,
			"depreciation_method": "Straight Line",
			"total_number_of_depreciations": 3,
			"frequency_of_depreciation": 10,
			"depreciation_start_date": month_end_date
		})
		asset_doc.submit()

		current_value = get_current_asset_value(asset_doc.name)
		adj_doc = make_asset_value_adjustment(asset = asset_doc.name,
			current_asset_value = current_value, new_asset_value = 50000.0)
		adj_doc.submit()

		expected_gle = (
			("_Test Accumulated Depreciations - _TC", 0.0, 50000.0),
			("_Test Depreciations - _TC", 50000.0, 0.0)
		)

		gle = frappe.db.sql("""select account, debit, credit from `tabGL Entry`
			where voucher_type='Journal Entry' and voucher_no = %s
			order by account""", adj_doc.journal_entry)

		self.assertEqual(gle, expected_gle)
示例#51
0
def create_salary_slips_for_payroll_period(employee, salary_structure, payroll_period, deduct_random=True):
	deducted_dates = []
	i = 0
	while i < 12:
		slip = frappe.get_doc({"doctype": "Salary Slip", "employee": employee,
				"salary_structure": salary_structure, "frequency": "Monthly"})
		if i == 0:
			posting_date = add_days(payroll_period.start_date, 25)
		else:
			posting_date = add_months(posting_date, 1)
		if i == 11:
			slip.deduct_tax_for_unsubmitted_tax_exemption_proof = 1
			slip.deduct_tax_for_unclaimed_employee_benefits = 1
		if deduct_random and not random.randint(0, 2):
			slip.deduct_tax_for_unsubmitted_tax_exemption_proof = 1
			deducted_dates.append(posting_date)
		slip.posting_date = posting_date
		slip.start_date = get_first_day(posting_date)
		slip.end_date = get_last_day(posting_date)
		doc = make_salary_slip(salary_structure, slip, employee)
		doc.submit()
		i += 1
	return deducted_dates
		def _test(i):
			self.assertEquals(i+1, frappe.db.sql("""select count(*) from `tabSales Invoice`
				where recurring_id=%s and docstatus=1""", base_si.recurring_id)[0][0])

			next_date = get_next_date(base_si.posting_date, no_of_months,
				base_si.repeat_on_day_of_month)

			manage_recurring_invoices(next_date=next_date, commit=False)

			recurred_invoices = frappe.db.sql("""select name from `tabSales Invoice`
				where recurring_id=%s and docstatus=1 order by name desc""",
				base_si.recurring_id)

			self.assertEquals(i+2, len(recurred_invoices))

			new_si = frappe.get_doc("Sales Invoice", recurred_invoices[0][0])

			for fieldname in ["convert_into_recurring_invoice", "recurring_type",
				"repeat_on_day_of_month", "notification_email_address"]:
					self.assertEquals(base_si.get(fieldname),
						new_si.get(fieldname))

			self.assertEquals(new_si.posting_date, unicode(next_date))

			self.assertEquals(new_si.invoice_period_from_date,
				unicode(add_months(base_si.invoice_period_from_date, no_of_months)))

			if first_and_last_day:
				self.assertEquals(new_si.invoice_period_to_date,
					unicode(get_last_day(add_months(base_si.invoice_period_to_date,
						no_of_months))))
			else:
				self.assertEquals(new_si.invoice_period_to_date,
					unicode(add_months(base_si.invoice_period_to_date, no_of_months)))


			return new_si
	def test_current_asset_value(self):
		pr = make_purchase_receipt(item_code="Macbook Pro",
			qty=1, rate=100000.0, location="Test Location")

		asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name')
		asset_doc = frappe.get_doc('Asset', asset_name)

		month_end_date = get_last_day(nowdate())
		purchase_date = nowdate() if nowdate() != month_end_date else add_days(nowdate(), -15)

		asset_doc.available_for_use_date = purchase_date
		asset_doc.purchase_date = purchase_date
		asset_doc.calculate_depreciation = 1
		asset_doc.append("finance_books", {
			"expected_value_after_useful_life": 200,
			"depreciation_method": "Straight Line",
			"total_number_of_depreciations": 3,
			"frequency_of_depreciation": 10,
			"depreciation_start_date": month_end_date
		})
		asset_doc.submit()

		current_value = get_current_asset_value(asset_doc.name)
		self.assertEqual(current_value, 100000.0)
示例#54
0
def make_dep_schedule(doc, base_dep_date, exp_val_aft_life, dep_freq, tot_dep):
	dont_make_sch = 0
	fy_doc = get_fy_doc(doc)
	diff_pd_npd = relativedelta.relativedelta(add_days(base_dep_date,1), getdate(doc.purchase_date))
	diff_months = diff_pd_npd.years*12 + diff_pd_npd.months
	diff_days = date_diff(add_days(doc.next_depreciation_date,1), doc.purchase_date)
	fy_days = date_diff(fy_doc.year_end_date, fy_doc.year_start_date)
	middle_purchase_factor = flt(diff_days)/flt(fy_days)

	if tot_dep == cint(doc.number_of_depreciations_booked):
		doc.opening_accumulated_depreciation = (doc.gross_purchase_amount - exp_val_aft_life)
		doc.schedules = []
		dont_make_sch = 1
	else:
		if doc.opening_accumulated_depreciation == (doc.gross_purchase_amount - exp_val_aft_life):
			doc.number_of_depreciations_booked = tot_dep
			doc.schedules = []
			dont_make_sch = 1

	if doc.depreciation_method != 'Manual':
		doc.schedules = []

	if dont_make_sch != 1:
		if not doc.get("schedules") and doc.next_depreciation_date:
			value_after_depreciation = doc.gross_purchase_amount - doc.opening_accumulated_depreciation

			if diff_months < dep_freq:
				number_of_pending_depreciations = cint(tot_dep) - \
					cint(doc.number_of_depreciations_booked) + 1
			else:
				number_of_pending_depreciations = cint(tot_dep) - \
						cint(doc.number_of_depreciations_booked)

			if number_of_pending_depreciations:
				for n in range(number_of_pending_depreciations):
					schedule_date = get_last_day(add_months(doc.next_depreciation_date, 
						n * cint(dep_freq)))

					if diff_months < dep_freq and n==0 and \
					cint(doc.number_of_depreciations_booked) == 0:
						depreciation_amount = get_depreciation_amount(doc, \
							value_after_depreciation, middle_purchase_factor)
					else:
						depreciation_amount = get_depreciation_amount(doc, \
							value_after_depreciation, 1)
					value_after_depreciation = value_after_depreciation - flt(depreciation_amount)

					doc.append("schedules", {
						"schedule_date": schedule_date,
						"depreciation_amount": depreciation_amount
					})
			#frappe.throw(str(number_of_pending_depreciations))
		accumulated_depreciation = flt(doc.opening_accumulated_depreciation)
		value_after_depreciation = flt(doc.value_after_depreciation)
		for i, d in enumerate(doc.get("schedules")):
			depreciation_amount = flt(d.depreciation_amount, d.precision("depreciation_amount"))

			if i==len(doc.get("schedules"))-1 and doc.depreciation_method == "Straight Line":
				depreciation_amount = flt((doc.gross_purchase_amount) - flt(accumulated_depreciation) - flt(exp_val_aft_life),
					d.precision("depreciation_amount"))

			d.depreciation_amount = depreciation_amount
			accumulated_depreciation += d.depreciation_amount
			d.accumulated_depreciation_amount = flt(accumulated_depreciation, \
				d.precision("accumulated_depreciation_amount"))
示例#55
0
def work():
	frappe.set_user(frappe.db.get_global('demo_hr_user'))
	year, month = frappe.flags.current_date.strftime("%Y-%m").split("-")
	mark_attendance()
	make_leave_application()

	# process payroll
	if not frappe.db.sql('select name from `tabSalary Slip` where month(adddate(start_date, interval 1 month))=month(curdate())'):
		# process payroll for previous month
		process_payroll = frappe.get_doc("Process Payroll", "Process Payroll")
		process_payroll.company = frappe.flags.company
		process_payroll.payroll_frequency = 'Monthly'

		# select a posting date from the previous month
		process_payroll.posting_date = get_last_day(getdate(frappe.flags.current_date) - datetime.timedelta(days=10))
		process_payroll.payment_account = frappe.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")

		process_payroll.set_start_end_dates()

		# based on frequency
		process_payroll.salary_slip_based_on_timesheet = 0
		process_payroll.create_salary_slips()
		process_payroll.submit_salary_slips()
		process_payroll.make_journal_entry(reference_date=frappe.flags.current_date,
			reference_number=random_string(10))

		process_payroll.salary_slip_based_on_timesheet = 1
		process_payroll.create_salary_slips()
		process_payroll.submit_salary_slips()
		process_payroll.make_journal_entry(reference_date=frappe.flags.current_date,
			reference_number=random_string(10))

	if frappe.db.get_global('demo_hr_user'):
		make_timesheet_records()

		#expense claim
		expense_claim = frappe.new_doc("Expense Claim")
		expense_claim.extend('expenses', get_expenses())
		expense_claim.employee = get_random("Employee")
		expense_claim.company = frappe.flags.company
		expense_claim.posting_date = frappe.flags.current_date
		expense_claim.exp_approver = filter((lambda x: x[0] != 'Administrator'), get_expense_approver(None, '', None, 0, 20, None))[0][0]
		expense_claim.insert()

		rand = random.random()

		if rand < 0.4:
			expense_claim.approval_status = "Approved"
			update_sanctioned_amount(expense_claim)
			expense_claim.submit()

			if random.randint(0, 1):
				#make journal entry against expense claim
				je = frappe.get_doc(make_bank_entry(expense_claim.name))
				je.posting_date = frappe.flags.current_date
				je.cheque_no = random_string(10)
				je.cheque_date = frappe.flags.current_date
				je.flags.ignore_permissions = 1
				je.submit()

		elif rand < 0.2:
			expense_claim.approval_status = "Rejected"
			expense_claim.submit()
def get_period_list(fiscal_year, periodicity):
	"""Get a list of dict {"from_date": from_date, "to_date": to_date, "key": key, "label": label}
		Periodicity can be (Yearly, Quarterly, Monthly)"""

	fy_start_end_date = frappe.db.get_value("Fiscal Year", fiscal_year, ["year_start_date", "year_end_date"])
	if not fy_start_end_date:
		frappe.throw(_("Fiscal Year {0} not found.").format(fiscal_year))

	# start with first day, so as to avoid year to_dates like 2-April if ever they occur]
	year_start_date = get_first_day(getdate(fy_start_end_date[0]))
	year_end_date = getdate(fy_start_end_date[1])
	
	if periodicity == "Yearly":
		period_list = [frappe._dict({"from_date": year_start_date, "to_date": year_end_date, 
			"key": fiscal_year, "label": fiscal_year})]
	else:
		months_to_add = {
			"Half-Yearly": 6,
			"Quarterly": 3,
			"Monthly": 1
		}[periodicity]

		period_list = []

		start_date = year_start_date
		for i in xrange(12 / months_to_add):
			period = frappe._dict({
				"from_date": start_date
			})
			to_date = add_months(start_date, months_to_add)
			start_date = to_date
			
			if to_date == get_first_day(to_date):
				# if to_date is the first day, get the last day of previous month
				to_date = add_days(to_date, -1)
			else:
				# to_date should be the last day of the new to_date's month
				to_date = get_last_day(to_date)

			if to_date <= year_end_date:
				# the normal case
				period.to_date = to_date
			else:
				# if a fiscal year ends before a 12 month period
				period.to_date = year_end_date
			
			period_list.append(period)
			
			if period.to_date == year_end_date:
				break
				
	# common processing
	for opts in period_list:
		key = opts["to_date"].strftime("%b_%Y").lower()
		if periodicity == "Monthly":
			label = formatdate(opts["to_date"], "MMM YYYY")
		else:
			label = get_label(periodicity, opts["from_date"], opts["to_date"])
			
		opts.update({
			"key": key.replace(" ", "_").replace("-", "_"),
			"label": label,
			"year_start_date": year_start_date,
			"year_end_date": year_end_date
		})

	return period_list
	def test_recurring_invoice(self):
		from frappe.utils import get_first_day, get_last_day, add_to_date, nowdate, getdate
		from erpnext.accounts.utils import get_fiscal_year
		today = nowdate()
		base_si = frappe.copy_doc(test_records[0])
		base_si.update({
			"convert_into_recurring_invoice": 1,
			"recurring_type": "Monthly",
			"notification_email_address": "[email protected], [email protected], [email protected]",
			"repeat_on_day_of_month": getdate(today).day,
			"posting_date": today,
			"fiscal_year": get_fiscal_year(today)[0],
			"invoice_period_from_date": get_first_day(today),
			"invoice_period_to_date": get_last_day(today)
		})

		# monthly
		si1 = frappe.copy_doc(base_si)
		si1.insert()
		si1.submit()
		self._test_recurring_invoice(si1, True)

		# monthly without a first and last day period
		si2 = frappe.copy_doc(base_si)
		si2.update({
			"invoice_period_from_date": today,
			"invoice_period_to_date": add_to_date(today, days=30)
		})
		si2.insert()
		si2.submit()
		self._test_recurring_invoice(si2, False)

		# quarterly
		si3 = frappe.copy_doc(base_si)
		si3.update({
			"recurring_type": "Quarterly",
			"invoice_period_from_date": get_first_day(today),
			"invoice_period_to_date": get_last_day(add_to_date(today, months=3))
		})
		si3.insert()
		si3.submit()
		self._test_recurring_invoice(si3, True)

		# quarterly without a first and last day period
		si4 = frappe.copy_doc(base_si)
		si4.update({
			"recurring_type": "Quarterly",
			"invoice_period_from_date": today,
			"invoice_period_to_date": add_to_date(today, months=3)
		})
		si4.insert()
		si4.submit()
		self._test_recurring_invoice(si4, False)

		# yearly
		si5 = frappe.copy_doc(base_si)
		si5.update({
			"recurring_type": "Yearly",
			"invoice_period_from_date": get_first_day(today),
			"invoice_period_to_date": get_last_day(add_to_date(today, years=1))
		})
		si5.insert()
		si5.submit()
		self._test_recurring_invoice(si5, True)

		# yearly without a first and last day period
		si6 = frappe.copy_doc(base_si)
		si6.update({
			"recurring_type": "Yearly",
			"invoice_period_from_date": today,
			"invoice_period_to_date": add_to_date(today, years=1)
		})
		si6.insert()
		si6.submit()
		self._test_recurring_invoice(si6, False)

		# change posting date but keep recuring day to be today
		si7 = frappe.copy_doc(base_si)
		si7.update({
			"posting_date": add_to_date(today, days=-1)
		})
		si7.insert()
		si7.submit()

		# setting so that _test function works
		si7.posting_date = today
		self._test_recurring_invoice(si7, True)
示例#58
0
def test_recurring_document(obj, test_records):
	from frappe.utils import get_first_day, get_last_day, add_to_date, nowdate, getdate, add_days
	from erpnext.accounts.utils import get_fiscal_year
	frappe.db.set_value("Print Settings", "Print Settings", "send_print_as_pdf", 1)
	today = nowdate()
	base_doc = frappe.copy_doc(test_records[0])

	base_doc.update({
		"is_recurring": 1,
		"recurring_type": "Monthly",
		"notification_email_address": "[email protected], [email protected], [email protected]",
		"repeat_on_day_of_month": getdate(today).day,
		"due_date": None,
		"fiscal_year": get_fiscal_year(today)[0],
		"from_date": get_first_day(today),
		"to_date": get_last_day(today)
	})

	if base_doc.doctype == "Sales Order":
		base_doc.update({
			"transaction_date": today,
			"delivery_date": add_days(today, 15)
		})
	elif base_doc.doctype == "Sales Invoice":
		base_doc.update({
			"posting_date": today
		})

	if base_doc.doctype == "Sales Order":
		date_field = "transaction_date"
	elif base_doc.doctype == "Sales Invoice":
		date_field = "posting_date"

	# monthly
	doc1 = frappe.copy_doc(base_doc)
	doc1.insert()
	doc1.submit()
	_test_recurring_document(obj, doc1, date_field, True)

	# monthly without a first and last day period
	doc2 = frappe.copy_doc(base_doc)
	doc2.update({
		"from_date": today,
		"to_date": add_to_date(today, days=30)
	})
	doc2.insert()
	doc2.submit()
	_test_recurring_document(obj, doc2, date_field, False)

	# quarterly
	doc3 = frappe.copy_doc(base_doc)
	doc3.update({
		"recurring_type": "Quarterly",
		"from_date": get_first_day(today),
		"to_date": get_last_day(add_to_date(today, months=3))
	})
	doc3.insert()
	doc3.submit()
	_test_recurring_document(obj, doc3, date_field, True)

	# quarterly without a first and last day period
	doc4 = frappe.copy_doc(base_doc)
	doc4.update({
		"recurring_type": "Quarterly",
		"from_date": today,
		"to_date": add_to_date(today, months=3)
	})
	doc4.insert()
	doc4.submit()
	_test_recurring_document(obj, doc4, date_field, False)

	# yearly
	doc5 = frappe.copy_doc(base_doc)
	doc5.update({
		"recurring_type": "Yearly",
		"from_date": get_first_day(today),
		"to_date": get_last_day(add_to_date(today, years=1))
	})
	doc5.insert()
	doc5.submit()
	_test_recurring_document(obj, doc5, date_field, True)

	# yearly without a first and last day period
	doc6 = frappe.copy_doc(base_doc)
	doc6.update({
		"recurring_type": "Yearly",
		"from_date": today,
		"to_date": add_to_date(today, years=1)
	})
	doc6.insert()
	doc6.submit()
	_test_recurring_document(obj, doc6, date_field, False)

	# change date field but keep recurring day to be today
	doc7 = frappe.copy_doc(base_doc)
	doc7.update({
		date_field: today,
	})
	doc7.insert()
	doc7.submit()

	# setting so that _test function works
	# doc7.set(date_field, today)
	_test_recurring_document(obj, doc7, date_field, True)
def get_period_list(fiscal_year, periodicity, from_beginning=False):
	"""Get a list of dict {"to_date": to_date, "key": key, "label": label}
		Periodicity can be (Yearly, Quarterly, Monthly)"""

	fy_start_end_date = frappe.db.get_value("Fiscal Year", fiscal_year, ["year_start_date", "year_end_date"])
	if not fy_start_end_date:
		frappe.throw(_("Fiscal Year {0} not found.").format(fiscal_year))

	start_date = getdate(fy_start_end_date[0])
	end_date = getdate(fy_start_end_date[1])

	if periodicity == "Yearly":
		period_list = [_dict({"to_date": end_date, "key": fiscal_year, "label": fiscal_year})]
	else:
		months_to_add = {
			"Half-yearly": 6,
			"Quarterly": 3,
			"Monthly": 1
		}[periodicity]

		period_list = []

		# start with first day, so as to avoid year to_dates like 2-April if ever they occur
		to_date = get_first_day(start_date)

		for i in xrange(12 / months_to_add):
			to_date = add_months(to_date, months_to_add)

			if to_date == get_first_day(to_date):
				# if to_date is the first day, get the last day of previous month
				to_date = add_days(to_date, -1)
			else:
				# to_date should be the last day of the new to_date's month
				to_date = get_last_day(to_date)

			if to_date <= end_date:
				# the normal case
				period_list.append(_dict({ "to_date": to_date }))

				# if it ends before a full year
				if to_date == end_date:
					break

			else:
				# if a fiscal year ends before a 12 month period
				period_list.append(_dict({ "to_date": end_date }))
				break

	# common processing
	for opts in period_list:
		key = opts["to_date"].strftime("%b_%Y").lower()
		label = formatdate(opts["to_date"], "MMM YYYY")
		opts.update({
			"key": key.replace(" ", "_").replace("-", "_"),
			"label": label,
			"year_start_date": start_date,
			"year_end_date": end_date
		})

		if from_beginning:
			# set start date as None for all fiscal periods, used in case of Balance Sheet
			opts["from_date"] = None
		else:
			opts["from_date"] = start_date

	return period_list
def calculate_depreciation_date():
    return get_last_day(nowdate());