예제 #1
0
def calculate_next_due_date(periodicity,
                            start_date=None,
                            end_date=None,
                            last_completion_date=None,
                            next_due_date=None):
    if not start_date and not last_completion_date:
        start_date = dataent.utils.now()

    if last_completion_date and (last_completion_date > start_date
                                 or not start_date):
        start_date = last_completion_date
    if periodicity == 'Daily':
        next_due_date = add_days(start_date, 1)
    if periodicity == 'Weekly':
        next_due_date = add_days(start_date, 7)
    if periodicity == 'Monthly':
        next_due_date = add_months(start_date, 1)
    if periodicity == 'Yearly':
        next_due_date = add_years(start_date, 1)
    if periodicity == '2 Yearly':
        next_due_date = add_years(start_date, 2)
    if periodicity == 'Quarterly':
        next_due_date = add_months(start_date, 3)
    if end_date and (start_date >= end_date or last_completion_date >= end_date
                     or next_due_date):
        next_due_date = ""
    return next_due_date
예제 #2
0
    def test_leave_grant(self):
        leave_type = "_Test Leave Type"

        # create the leave policy
        leave_policy = dataent.get_doc({
            "doctype":
            "Leave Policy",
            "leave_policy_details": [{
                "leave_type": leave_type,
                "annual_allocation": 20
            }]
        }).insert()
        leave_policy.submit()

        # create employee and assign the leave period
        employee = "*****@*****.**"
        employee_doc_name = make_employee(employee)
        dataent.db.set_value("Employee", employee_doc_name, "leave_policy",
                             leave_policy.name)

        # clear the already allocated leave
        dataent.db.sql(
            '''delete from `tabLeave Allocation` where employee=%s''',
            "*****@*****.**")

        # create the leave period
        leave_period = create_leave_period(add_months(today(), -3),
                                           add_months(today(), 3))

        # test leave_allocation
        leave_period.grant_leave_allocation(employee=employee_doc_name)
        self.assertEqual(
            get_leave_balance_on(employee_doc_name, leave_type, today()), 20)
예제 #3
0
def create_salary_slips_for_payroll_period(employee,
                                           salary_structure,
                                           payroll_period,
                                           deduct_random=True):
    deducted_dates = []
    i = 0
    while i < 12:
        slip = dataent.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
예제 #4
0
def calculate_service_end_date(args, item=None):
	args = process_args(args)
	if not item:
		item = dataent.get_cached_doc("Item", args.item_code)

	doctype = args.get("parenttype") or args.get("doctype")
	if doctype == "Sales Invoice":
		enable_deferred = "enable_deferred_revenue"
		no_of_months = "no_of_months"
		account = "deferred_revenue_account"
	else:
		enable_deferred = "enable_deferred_expense"
		no_of_months = "no_of_months_exp"
		account = "deferred_expense_account"

	service_start_date = args.service_start_date if args.service_start_date else args.transaction_date
	service_end_date = add_months(service_start_date, item.get(no_of_months))
	deferred_detail = {
		"service_start_date": service_start_date,
		"service_end_date": service_end_date
	}
	deferred_detail[enable_deferred] = item.get(enable_deferred)
	deferred_detail[account] = get_default_deferred_account(args, item, fieldname=account)

	return deferred_detail
예제 #5
0
파일: loan.py 프로젝트: dataent/epaas
    def make_repayment_schedule(self):
        self.repayment_schedule = []
        payment_date = self.repayment_start_date
        balance_amount = self.loan_amount
        while (balance_amount > 0):
            interest_amount = rounded(balance_amount *
                                      flt(self.rate_of_interest) / (12 * 100))
            principal_amount = self.monthly_repayment_amount - interest_amount
            balance_amount = rounded(balance_amount + interest_amount -
                                     self.monthly_repayment_amount)

            if balance_amount < 0:
                principal_amount += balance_amount
                balance_amount = 0.0

            total_payment = principal_amount + interest_amount
            self.append(
                "repayment_schedule", {
                    "payment_date": payment_date,
                    "principal_amount": principal_amount,
                    "interest_amount": interest_amount,
                    "total_payment": total_payment,
                    "balance_loan_amount": balance_amount
                })
            next_payment_date = add_months(payment_date, 1)
            payment_date = next_payment_date
예제 #6
0
    def test_make_sales_order(self):
        from epaas.selling.doctype.quotation.quotation import make_sales_order

        quotation = dataent.copy_doc(test_records[0])
        quotation.transaction_date = nowdate()
        quotation.valid_till = add_months(quotation.transaction_date, 1)
        quotation.insert()

        self.assertRaises(dataent.ValidationError, make_sales_order,
                          quotation.name)
        quotation.submit()

        sales_order = make_sales_order(quotation.name)

        self.assertEqual(sales_order.doctype, "Sales Order")
        self.assertEqual(len(sales_order.get("items")), 1)
        self.assertEqual(
            sales_order.get("items")[0].doctype, "Sales Order Item")
        self.assertEqual(
            sales_order.get("items")[0].prevdoc_docname, quotation.name)
        self.assertEqual(sales_order.customer, "_Test Customer")

        sales_order.delivery_date = "2014-01-01"
        sales_order.naming_series = "_T-Quotation-"
        sales_order.transaction_date = nowdate()
        sales_order.insert()
예제 #7
0
	def create_quotation(self):
		quotation = dataent.new_doc("Quotation")

		values = {
			"doctype": "Quotation",
			"quotation_to": "Customer",
			"order_type": "Shopping Cart",
			"party_name": get_party(dataent.session.user).name,
			"docstatus": 0,
			"contact_email": dataent.session.user,
			"selling_price_list": "_Test Price List Rest of the World",
			"currency": "USD",
			"taxes_and_charges" : "_Test Tax 1 - _TC",
			"conversion_rate":1,
			"transaction_date" : nowdate(),
			"valid_till" : add_months(nowdate(), 1),
			"items": [{
				"item_code": "_Test Item",
				"qty": 1
			}],
			"taxes": dataent.get_doc("Sales Taxes and Charges Template", "_Test Tax 1 - _TC").taxes,
			"company": "_Test Company"
		}

		quotation.update(values)

		quotation.insert(ignore_permissions=True)

		return quotation
예제 #8
0
def sync_transactions(bank, bank_account):

    last_sync_date = dataent.db.get_value("Bank Account", bank_account,
                                          "last_integration_date")
    if last_sync_date:
        start_date = formatdate(last_sync_date, "YYYY-MM-dd")
    else:
        start_date = formatdate(add_months(today(), -12), "YYYY-MM-dd")
    end_date = formatdate(today(), "YYYY-MM-dd")

    try:
        transactions = get_transactions(bank=bank,
                                        bank_account=bank_account,
                                        start_date=start_date,
                                        end_date=end_date)
        result = []
        if transactions:
            for transaction in transactions:
                result.append(new_bank_transaction(transaction))

        dataent.db.set_value("Bank Account", bank_account,
                             "last_integration_date", getdate(end_date))

        return result
    except Exception:
        dataent.log_error(dataent.get_traceback(),
                          _("Plaid transactions sync error"))
 def test_result_for_partial_material_request(self):
     so = make_sales_order()
     mr=make_material_request(so.name)
     mr.items[0].qty = 4
     mr.schedule_date = add_months(nowdate(),1)
     mr.submit()
     report = execute()
     l = len(report[1])
     self.assertEqual((so.items[0].qty - mr.items[0].qty), report[1][l-1]['pending_qty'])
예제 #10
0
def create_benefit_claim(employee, payroll_period, amount, component):
    claim_date = add_months(payroll_period.start_date, random.randint(0, 11))
    dataent.get_doc({
        "doctype": "Employee Benefit Claim",
        "employee": employee,
        "claimed_amount": amount,
        "claim_date": claim_date,
        "earning_component": component
    }).submit()
    return claim_date
예제 #11
0
    def test_monthly_auto_repeat(self):
        start_date = today()
        end_date = add_months(start_date, 12)

        todo = dataent.get_doc(
            dict(doctype='ToDo',
                 description='test recurring todo',
                 assigned_by='Administrator')).insert()

        self.monthly_auto_repeat('ToDo', todo.name, start_date, end_date)
예제 #12
0
def create_additional_salary(employee, payroll_period, amount):
    salary_date = add_months(payroll_period.start_date, random.randint(0, 11))
    dataent.get_doc({
        "doctype": "Additional Salary",
        "employee": employee,
        "company": epaas.get_default_company(),
        "salary_component": "Performance Bonus",
        "payroll_date": salary_date,
        "amount": amount,
        "type": "Earning"
    }).submit()
    return salary_date
예제 #13
0
    def test_make_sales_order_terms_copied(self):
        from epaas.selling.doctype.quotation.quotation import make_sales_order

        quotation = dataent.copy_doc(test_records[0])
        quotation.transaction_date = nowdate()
        quotation.valid_till = add_months(quotation.transaction_date, 1)
        quotation.insert()
        quotation.submit()

        sales_order = make_sales_order(quotation.name)

        self.assertTrue(sales_order.get('payment_schedule'))
예제 #14
0
def create_salary_structure_assignment(employee, salary_structure, from_date=None):
	if dataent.db.exists("Salary Structure Assignment", {"employee": employee}):
		dataent.db.sql("""delete from `tabSalary Structure Assignment` where employee=%s""",(employee))
	salary_structure_assignment = dataent.new_doc("Salary Structure Assignment")
	salary_structure_assignment.employee = employee
	salary_structure_assignment.base = 50000
	salary_structure_assignment.variable = 5000
	salary_structure_assignment.from_date = from_date or add_months(nowdate(), -1)
	salary_structure_assignment.salary_structure = salary_structure
	salary_structure_assignment.company = epaas.get_default_company()
	salary_structure_assignment.save(ignore_permissions=True)
	salary_structure_assignment.submit()
	return salary_structure_assignment
예제 #15
0
	def test_leave_balance_value_and_amount(self):
		employee = "*****@*****.**"
		leave_type = "_Test Leave Type Encashment"

		# create the leave policy
		leave_policy = dataent.get_doc({
			"doctype": "Leave Policy",
			"leave_policy_details": [{
				"leave_type": leave_type,
				"annual_allocation": 10
			}]
		}).insert()
		leave_policy.submit()

		# create employee, salary structure and assignment
		employee = make_employee(employee)
		dataent.db.set_value("Employee", employee, "leave_policy", leave_policy.name) 
		salary_structure = make_salary_structure("Salary Structure for Encashment", "Monthly", employee,
			other_details={"leave_encashment_amount_per_day": 50})

		# create the leave period and assign the leaves
		leave_period = create_leave_period(add_months(today(), -3), add_months(today(), 3))
		leave_period.grant_leave_allocation(employee=employee)

		leave_encashment = dataent.get_doc(dict(
			doctype = 'Leave Encashment',
			employee = employee,
			leave_type = leave_type,
			leave_period = leave_period.name,
			payroll_date = today()
		)).insert()

		self.assertEqual(leave_encashment.leave_balance, 10)
		self.assertEqual(leave_encashment.encashable_days, 5)
		self.assertEqual(leave_encashment.encashment_amount, 250)

		leave_encashment.submit()
		self.assertTrue(dataent.db.get_value("Leave Encashment", leave_encashment.name, "additional_salary"))
예제 #16
0
def convert_deferred_revenue_to_income(start_date=None, end_date=None):
	# book the expense/income on the last day, but it will be trigger on the 1st of month at 12:00 AM
	if not start_date:
		start_date = add_months(today(), -1)
	if not end_date:
		end_date = add_days(today(), -1)

	# check for the sales invoice for which GL entries has to be done
	invoices = dataent.db.sql_list('''
		select distinct parent from `tabSales Invoice Item`
		where service_start_date<=%s and service_end_date>=%s
		and enable_deferred_revenue = 1 and docstatus = 1 and ifnull(amount, 0) > 0
	''', (end_date, start_date))

	for invoice in invoices:
		doc = dataent.get_doc("Sales Invoice", invoice)
		book_deferred_income_or_expense(doc, end_date)
예제 #17
0
    def test_make_sales_order_with_terms(self):
        from epaas.selling.doctype.quotation.quotation import make_sales_order

        quotation = dataent.copy_doc(test_records[0])
        quotation.transaction_date = nowdate()
        quotation.valid_till = add_months(quotation.transaction_date, 1)
        quotation.update(
            {"payment_terms_template": "_Test Payment Term Template"})
        quotation.insert()

        self.assertRaises(dataent.ValidationError, make_sales_order,
                          quotation.name)
        quotation.save()
        quotation.submit()

        self.assertEqual(quotation.payment_schedule[0].payment_amount, 8906.00)
        self.assertEqual(quotation.payment_schedule[0].due_date,
                         quotation.transaction_date)
        self.assertEqual(quotation.payment_schedule[1].payment_amount, 8906.00)
        self.assertEqual(quotation.payment_schedule[1].due_date,
                         add_days(quotation.transaction_date, 30))

        sales_order = make_sales_order(quotation.name)

        self.assertEqual(sales_order.doctype, "Sales Order")
        self.assertEqual(len(sales_order.get("items")), 1)
        self.assertEqual(
            sales_order.get("items")[0].doctype, "Sales Order Item")
        self.assertEqual(
            sales_order.get("items")[0].prevdoc_docname, quotation.name)
        self.assertEqual(sales_order.customer, "_Test Customer")

        sales_order.delivery_date = "2014-01-01"
        sales_order.naming_series = "_T-Quotation-"
        sales_order.transaction_date = nowdate()
        sales_order.insert()

        self.assertEqual(sales_order.payment_schedule[0].payment_amount,
                         8906.00)
        self.assertEqual(sales_order.payment_schedule[0].due_date,
                         getdate(quotation.transaction_date))
        self.assertEqual(sales_order.payment_schedule[1].payment_amount,
                         8906.00)
        self.assertEqual(sales_order.payment_schedule[1].due_date,
                         getdate(add_days(quotation.transaction_date, 30)))
예제 #18
0
def create_proof_submission(employee, payroll_period, amount):
    submission_date = add_months(payroll_period.start_date,
                                 random.randint(0, 11))
    proof_submission = dataent.get_doc({
        "doctype": "Employee Tax Exemption Proof Submission",
        "employee": employee,
        "payroll_period": payroll_period.name,
        "submission_date": submission_date
    })
    proof_submission.append(
        "tax_exemption_proofs", {
            "exemption_sub_category": "_Test Sub Category",
            "exemption_category": "_Test Category",
            "type_of_proof": "Test",
            "amount": amount
        })
    proof_submission.submit()
    return submission_date
예제 #19
0
    def test_make_sales_order_with_different_currency(self):
        from epaas.selling.doctype.quotation.quotation import make_sales_order

        quotation = dataent.copy_doc(test_records[0])
        quotation.transaction_date = nowdate()
        quotation.valid_till = add_months(quotation.transaction_date, 1)
        quotation.insert()
        quotation.submit()

        sales_order = make_sales_order(quotation.name)
        sales_order.currency = "USD"
        sales_order.conversion_rate = 20.0
        sales_order.delivery_date = "2019-01-01"
        sales_order.naming_series = "_T-Quotation-"
        sales_order.transaction_date = nowdate()
        sales_order.insert()

        self.assertEquals(sales_order.currency, "USD")
        self.assertNotEqual(sales_order.currency, quotation.currency)
예제 #20
0
def make_salary_structure_for_timesheet(employee):
    salary_structure_name = "Timesheet Salary Structure Test"
    frequency = "Monthly"

    salary_structure = make_salary_structure(salary_structure_name,
                                             frequency,
                                             dont_submit=True)
    salary_structure.salary_component = "Timesheet Component"
    salary_structure.salary_slip_based_on_timesheet = 1
    salary_structure.hour_rate = 50.0
    salary_structure.save()
    salary_structure.submit()

    if not dataent.db.get_value("Salary Structure Assignment", {
            'employee': employee,
            'docstatus': 1
    }):
        dataent.db.set_value('Employee', employee, 'date_of_joining',
                             add_months(nowdate(), -5))
        create_salary_structure_assignment(employee, salary_structure.name)

    return salary_structure
예제 #21
0
파일: party.py 프로젝트: dataent/epaas
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 = dataent.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
예제 #22
0
    def test_create_quotation_with_margin(self):
        from epaas.selling.doctype.quotation.quotation import make_sales_order
        from epaas.selling.doctype.sales_order.sales_order \
         import make_delivery_note, make_sales_invoice

        rate_with_margin = flt((1500 * 18.75) / 100 + 1500)

        test_records[0]['items'][0]['price_list_rate'] = 1500
        test_records[0]['items'][0]['margin_type'] = 'Percentage'
        test_records[0]['items'][0]['margin_rate_or_amount'] = 18.75

        quotation = dataent.copy_doc(test_records[0])
        quotation.transaction_date = nowdate()
        quotation.valid_till = add_months(quotation.transaction_date, 1)
        quotation.insert()

        self.assertEqual(quotation.get("items")[0].rate, rate_with_margin)
        self.assertRaises(dataent.ValidationError, make_sales_order,
                          quotation.name)
        quotation.submit()

        sales_order = make_sales_order(quotation.name)
        sales_order.naming_series = "_T-Quotation-"
        sales_order.transaction_date = "2016-01-01"
        sales_order.delivery_date = "2016-01-02"

        sales_order.insert()

        self.assertEqual(quotation.get("items")[0].rate, rate_with_margin)

        sales_order.submit()

        dn = make_delivery_note(sales_order.name)
        self.assertEqual(quotation.get("items")[0].rate, rate_with_margin)
        dn.save()

        si = make_sales_invoice(sales_order.name)
        self.assertEqual(quotation.get("items")[0].rate, rate_with_margin)
        si.save()
예제 #23
0
파일: budget.py 프로젝트: dataent/epaas
def get_accumulated_monthly_budget(monthly_distribution, posting_date,
                                   fiscal_year, annual_budget):
    distribution = {}
    if monthly_distribution:
        for d in dataent.db.sql("""select mdp.month, mdp.percentage_allocation
			from `tabMonthly Distribution Percentage` mdp, `tabMonthly Distribution` md
			where mdp.parent=md.name and md.fiscal_year=%s""",
                                fiscal_year,
                                as_dict=1):
            distribution.setdefault(d.month, d.percentage_allocation)

    dt = dataent.db.get_value("Fiscal Year", fiscal_year, "year_start_date")
    accumulated_percentage = 0.0

    while (dt <= getdate(posting_date)):
        if monthly_distribution:
            accumulated_percentage += distribution.get(
                getdate(dt).strftime("%B"), 0)
        else:
            accumulated_percentage += 100.0 / 12

        dt = add_months(dt, 1)

    return annual_budget * accumulated_percentage / 100
예제 #24
0
def make_blanket_order(**args):
    args = dataent._dict(args)
    bo = dataent.new_doc("Blanket Order")
    bo.blanket_order_type = args.blanket_order_type
    bo.company = args.company or "_Test Company"

    if args.blanket_order_type == "Selling":
        bo.customer = args.customer or "_Test Customer"
    else:
        bo.supplier = args.supplier or "_Test Supplier"

    bo.from_date = today()
    bo.to_date = add_months(bo.from_date, months=12)

    bo.append(
        "items", {
            "item_code": args.item_code or "_Test Item",
            "qty": args.quantity or 1000,
            "rate": args.rate or 100
        })

    bo.insert()
    bo.submit()
    return bo
예제 #25
0
def get_period_list(from_fiscal_year,
                    to_fiscal_year,
                    periodicity,
                    accumulated_values=False,
                    company=None,
                    reset_period_on_fy_change=True):
    """Get a list of dict {"from_date": from_date, "to_date": to_date, "key": key, "label": label}
		Periodicity can be (Yearly, Quarterly, Monthly)"""

    fiscal_year = get_fiscal_year_data(from_fiscal_year, to_fiscal_year)
    validate_fiscal_year(fiscal_year, from_fiscal_year, to_fiscal_year)

    # start with first day, so as to avoid year to_dates like 2-April if ever they occur]
    year_start_date = getdate(fiscal_year.year_start_date)
    year_end_date = getdate(fiscal_year.year_end_date)

    months_to_add = {
        "Yearly": 12,
        "Half-Yearly": 6,
        "Quarterly": 3,
        "Monthly": 1
    }[periodicity]

    period_list = []

    start_date = year_start_date
    months = get_months(year_start_date, year_end_date)

    for i in range(months // months_to_add):
        period = dataent._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)

        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.to_date_fiscal_year = get_fiscal_year(period.to_date,
                                                     company=company)[0]
        period.from_date_fiscal_year_start_date = get_fiscal_year(
            period.from_date, company=company)[1]

        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" and not accumulated_values:
            label = formatdate(opts["to_date"], "MMM YYYY")
        else:
            if not accumulated_values:
                label = get_label(periodicity, opts["from_date"],
                                  opts["to_date"])
            else:
                if reset_period_on_fy_change:
                    label = get_label(periodicity,
                                      opts.from_date_fiscal_year_start_date,
                                      opts["to_date"])
                else:
                    label = get_label(periodicity, period_list[0].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
예제 #26
0
파일: asset.py 프로젝트: dataent/epaas
    def make_depreciation_schedule(self):
        depreciation_method = [
            d.depreciation_method for d in self.finance_books
        ]

        if 'Manual' not in depreciation_method:
            self.schedules = []

        if not self.get("schedules") and self.available_for_use_date:
            total_depreciations = sum([
                d.total_number_of_depreciations
                for d in self.get('finance_books')
            ])

            for d in self.get('finance_books'):
                self.validate_asset_finance_books(d)

                value_after_depreciation = (
                    flt(self.gross_purchase_amount) -
                    flt(self.opening_accumulated_depreciation))

                d.value_after_depreciation = value_after_depreciation

                no_of_depreciations = cint(
                    d.total_number_of_depreciations - 1) - cint(
                        self.number_of_depreciations_booked)
                end_date = add_months(
                    d.depreciation_start_date,
                    no_of_depreciations * cint(d.frequency_of_depreciation))

                total_days = date_diff(end_date, self.available_for_use_date)
                rate_per_day = (
                    value_after_depreciation -
                    d.get("expected_value_after_useful_life")) / total_days

                number_of_pending_depreciations = cint(d.total_number_of_depreciations) - \
                 cint(self.number_of_depreciations_booked)

                from_date = self.available_for_use_date
                if number_of_pending_depreciations:
                    next_depr_date = getdate(
                        add_months(self.available_for_use_date,
                                   number_of_pending_depreciations * 12))
                    if (cint(
                            dataent.db.get_value(
                                "Asset Settings", None,
                                "schedule_based_on_fiscal_year")) == 1
                            and getdate(
                                d.depreciation_start_date) < next_depr_date):

                        number_of_pending_depreciations += 1
                        for n in range(number_of_pending_depreciations):
                            if n == list(range(
                                    number_of_pending_depreciations))[-1]:
                                schedule_date = add_months(
                                    self.available_for_use_date, n * 12)
                                previous_scheduled_date = add_months(
                                    d.depreciation_start_date, (n - 1) * 12)
                                depreciation_amount = \
                                 self.get_depreciation_amount_prorata_temporis(value_after_depreciation,
                                  d, previous_scheduled_date, schedule_date)

                            elif n == list(
                                    range(number_of_pending_depreciations))[0]:
                                schedule_date = d.depreciation_start_date
                                depreciation_amount = \
                                 self.get_depreciation_amount_prorata_temporis(value_after_depreciation,
                                  d, self.available_for_use_date, schedule_date)

                            else:
                                schedule_date = add_months(
                                    d.depreciation_start_date, n * 12)
                                depreciation_amount = \
                                  self.get_depreciation_amount_prorata_temporis(value_after_depreciation, d)

                            if value_after_depreciation != 0:
                                value_after_depreciation -= flt(
                                    depreciation_amount)

                                self.append(
                                    "schedules", {
                                        "schedule_date": schedule_date,
                                        "depreciation_amount":
                                        depreciation_amount,
                                        "depreciation_method":
                                        d.depreciation_method,
                                        "finance_book": d.finance_book,
                                        "finance_book_id": d.idx
                                    })
                    else:
                        for n in range(number_of_pending_depreciations):
                            schedule_date = add_months(
                                d.depreciation_start_date,
                                n * cint(d.frequency_of_depreciation))

                            if d.depreciation_method in ("Straight Line",
                                                         "Manual"):
                                days = date_diff(schedule_date, from_date)
                                if n == 0: days += 1

                                depreciation_amount = days * rate_per_day
                                from_date = schedule_date
                            else:
                                depreciation_amount = self.get_depreciation_amount(
                                    value_after_depreciation,
                                    d.total_number_of_depreciations, d)

                            if depreciation_amount:
                                value_after_depreciation -= flt(
                                    depreciation_amount)

                                self.append(
                                    "schedules", {
                                        "schedule_date": schedule_date,
                                        "depreciation_amount":
                                        depreciation_amount,
                                        "depreciation_method":
                                        d.depreciation_method,
                                        "finance_book": d.finance_book,
                                        "finance_book_id": d.idx
                                    })
예제 #27
0
def get_monthly_goal_graph_data(title, doctype, docname, goal_value_field, goal_total_field, goal_history_field,
	goal_doctype, goal_doctype_link, goal_field, date_field, filter_str, aggregation="sum"):
	'''
		Get month-wise graph data for a doctype based on aggregation values of a field in the goal doctype

		:param title: Graph title
		:param doctype: doctype of graph doc
		:param docname: of the doc to set the graph in
		:param goal_value_field: goal field of doctype
		:param goal_total_field: current month value field of doctype
		:param goal_history_field: cached history field
		:param goal_doctype: doctype the goal is based on
		:param goal_doctype_link: doctype link field in goal_doctype
		:param goal_field: field from which the goal is calculated
		:param filter_str: where clause condition
		:param aggregation: a value like 'count', 'sum', 'avg'

		:return: dict of graph data
	'''

	from dataent.utils.formatters import format_value
	import json

	meta = dataent.get_meta(doctype)
	doc = dataent.get_doc(doctype, docname)

	goal = doc.get(goal_value_field)
	formatted_goal = format_value(goal, meta.get_field(goal_value_field), doc)

	current_month_value = doc.get(goal_total_field)
	formatted_value = format_value(current_month_value, meta.get_field(goal_total_field), doc)

	from dataent.utils import today, getdate, formatdate, add_months
	current_month_year = formatdate(today(), "MM-yyyy")

	history = doc.get(goal_history_field)
	try:
		month_to_value_dict = json.loads(history) if history and '{' in history else None
	except ValueError:
		month_to_value_dict = None

	if month_to_value_dict is None:
		doc_filter = (goal_doctype_link + ' = "' + docname + '"') if doctype != goal_doctype else ''
		if filter_str:
			doc_filter += ' and ' + filter_str if doc_filter else filter_str
		month_to_value_dict = get_monthly_results(goal_doctype, goal_field, date_field, doc_filter, aggregation)
		dataent.db.set_value(doctype, docname, goal_history_field, json.dumps(month_to_value_dict))

	month_to_value_dict[current_month_year] = current_month_value

	months = []
	months_formatted = []
	values = []
	values_formatted = []
	for i in range(0, 12):
		date_value = add_months(today(), -i)
		month_value = formatdate(date_value, "MM-yyyy")
		month_word = getdate(date_value).strftime('%b')
		month_year = getdate(date_value).strftime('%B') + ', ' + getdate(date_value).strftime('%Y')
		months.insert(0, month_word)
		months_formatted.insert(0, month_year)
		if month_value in month_to_value_dict:
			val = month_to_value_dict[month_value]
		else:
			val = 0
		values.insert(0, val)
		values_formatted.insert(0, format_value(val, meta.get_field(goal_total_field), doc))

	y_markers = []
	summary_values = [
		{
			'title': _("This month"),
			'color': '#ffa00a',
			'value': formatted_value
		}
	]

	if float(goal) > 0:
		y_markers = [
			{
				'label': _("Goal"),
				'lineType': "dashed",
				'value': goal
			},
		]
		summary_values += [
			{
				'title': _("Goal"),
				'color': '#5e64ff',
				'value': formatted_goal
			},
			{
				'title': _("Completed"),
				'color': '#28a745',
				'value': str(int(round(float(current_month_value)/float(goal)*100))) + "%"
			}
		]

	data = {
		'title': title,
		# 'subtitle':

		'data': {
			'datasets': [
				{
					'values': values,
					'formatted': values_formatted
				}
			],
			'labels': months,
		},

		'summary': summary_values,
	}

	if y_markers:
		data["data"]["yMarkers"] = y_markers

	return data