Ejemplo n.º 1
0
    def test_purchase_order_creation(self):
        bo = make_blanket_order(blanket_order_type="Purchasing")

        frappe.flags.args.doctype = 'Purchase Order'
        po = make_order(bo.name)
        po.currency = get_company_currency(po.company)
        po.schedule_date = today()
        po.items[0].qty = 10
        po.submit()

        self.assertEqual(po.doctype, "Purchase Order")
        self.assertEqual(len(po.get("items")), len(bo.get("items")))

        # check the rate, quantity and updation for the ordered quantity
        self.assertEqual(po.items[0].rate, po.items[0].rate)

        bo = frappe.get_doc("Blanket Order", bo.name)
        self.assertEqual(po.items[0].qty, bo.items[0].ordered_qty)

        # test the quantity
        frappe.flags.args.doctype = 'Purchase Order'
        po1 = make_order(bo.name)
        po1.currency = get_company_currency(po1.company)
        self.assertEqual(po1.items[0].qty,
                         (bo.items[0].qty - bo.items[0].ordered_qty))
Ejemplo n.º 2
0
    def test_sales_order_creation(self):
        bo = make_blanket_order(blanket_order_type="Selling")

        frappe.flags.args.doctype = 'Sales Order'
        so = make_order(bo.name)
        so.currency = get_company_currency(so.company)
        so.delivery_date = today()
        so.items[0].qty = 10
        so.submit()

        self.assertEqual(so.doctype, "Sales Order")
        self.assertEqual(len(so.get("items")), len(bo.get("items")))

        # check the rate, quantity and updation for the ordered quantity
        self.assertEqual(so.items[0].rate, bo.items[0].rate)

        bo = frappe.get_doc("Blanket Order", bo.name)
        self.assertEqual(so.items[0].qty, bo.items[0].ordered_qty)

        # test the quantity
        frappe.flags.args.doctype = 'Sales Order'
        so1 = make_order(bo.name)
        so1.currency = get_company_currency(so1.company)
        self.assertEqual(so1.items[0].qty,
                         (bo.items[0].qty - bo.items[0].ordered_qty))
Ejemplo n.º 3
0
def get_incoming_rate(args, raise_error_if_no_rate=True):
    """Get Incoming Rate based on valuation method"""
    from erpbee.stock.stock_ledger import get_previous_sle, get_valuation_rate
    if isinstance(args, string_types):
        args = json.loads(args)

    in_rate = 0
    if (args.get("serial_no") or "").strip():
        in_rate = get_avg_purchase_rate(args.get("serial_no"))
    else:
        valuation_method = get_valuation_method(args.get("item_code"))
        previous_sle = get_previous_sle(args)
        if valuation_method == 'FIFO':
            if previous_sle:
                previous_stock_queue = json.loads(
                    previous_sle.get('stock_queue', '[]') or '[]')
                in_rate = get_fifo_rate(previous_stock_queue,
                                        args.get("qty")
                                        or 0) if previous_stock_queue else 0
        elif valuation_method == 'Moving Average':
            in_rate = previous_sle.get('valuation_rate') or 0

    if not in_rate:
        voucher_no = args.get('voucher_no') or args.get('name')
        in_rate = get_valuation_rate(
            args.get('item_code'),
            args.get('warehouse'),
            args.get('voucher_type'),
            voucher_no,
            args.get('allow_zero_valuation'),
            currency=erpbee.get_company_currency(args.get('company')),
            company=args.get('company'),
            raise_error_if_no_rate=raise_error_if_no_rate)

    return flt(in_rate)
Ejemplo n.º 4
0
def get_currency(filters):
    """
	Returns a dictionary containing currency information. The keys of the dict are
	- company: The company for which we are fetching currency information. if no
	company is specified, it will fallback to the default company.
	- company currency: The functional currency of the said company.
	- presentation currency: The presentation currency to use. Only currencies that
	have been used for transactions will be allowed.
	- report date: The report date.
	:param filters: Report filters
	:type filters: dict

	:return: str - Currency
	"""
    company = get_appropriate_company(filters)
    company_currency = get_company_currency(company)
    presentation_currency = filters['presentation_currency'] if filters.get(
        'presentation_currency') else company_currency

    report_date = filters.get('to_date')

    if not report_date:
        fiscal_year_to_date = get_from_and_to_date(
            filters.get('to_fiscal_year'))["to_date"]
        report_date = formatdate(get_datetime_str(fiscal_year_to_date),
                                 "dd-MM-yyyy")

    currency_map = dict(company=company,
                        company_currency=company_currency,
                        presentation_currency=presentation_currency,
                        report_date=report_date)

    return currency_map
Ejemplo n.º 5
0
    def get_accounts_from_gle(self):
        company_currency = erpbee.get_company_currency(self.company)
        accounts = frappe.db.sql_list(
            """
			select name
			from tabAccount
			where is_group = 0
				and report_type = 'Balance Sheet'
				and root_type in ('Asset', 'Liability', 'Equity')
				and account_type != 'Stock'
				and company=%s
				and account_currency != %s
			order by name""", (self.company, company_currency))

        account_details = []
        if accounts:
            account_details = frappe.db.sql("""
				select
					account, party_type, party, account_currency,
					sum(debit_in_account_currency) - sum(credit_in_account_currency) as balance_in_account_currency,
					sum(debit) - sum(credit) as balance
				from `tabGL Entry`
				where account in (%s)
				group by account, party_type, party
				having sum(debit) != sum(credit)
				order by account
			""" % ', '.join(['%s'] * len(accounts)),
                                            tuple(accounts),
                                            as_dict=1)

        return account_details
Ejemplo n.º 6
0
def _execute(filters=None):
	if not filters: filters = {}
	columns = get_columns()

	company_currency = erpbee.get_company_currency(filters.company)
	item_list = get_items(filters)
	if item_list:
		itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency)

	data = []
	added_item = []
	for d in item_list:
		if (d.parent, d.item_code) not in added_item:
			row = [d.gst_hsn_code, d.description, d.stock_uom, d.stock_qty]
			total_tax = 0
			for tax in tax_columns:
				item_tax = itemised_tax.get((d.parent, d.item_code), {}).get(tax, {})
				total_tax += flt(item_tax.get("tax_amount", 0))

			row += [d.base_net_amount + total_tax]
			row += [d.base_net_amount]

			for tax in tax_columns:
				item_tax = itemised_tax.get((d.parent, d.item_code), {}).get(tax, {})
				row += [item_tax.get("tax_amount", 0)]

			data.append(row)
			added_item.append((d.parent, d.item_code))
	if data:
		data = get_merged_data(columns, data) # merge same hsn code data
	return columns, data
Ejemplo n.º 7
0
def update_against_account(voucher_type, voucher_no):
    entries = frappe.db.get_all("GL Entry",
                                filters={
                                    "voucher_type": voucher_type,
                                    "voucher_no": voucher_no
                                },
                                fields=[
                                    "name", "party", "against", "debit",
                                    "credit", "account", "company"
                                ])

    if not entries:
        return
    company_currency = erpbee.get_company_currency(entries[0].company)
    precision = get_field_precision(
        frappe.get_meta("GL Entry").get_field("debit"), company_currency)

    accounts_debited, accounts_credited = [], []
    for d in entries:
        if flt(d.debit, precision) > 0:
            accounts_debited.append(d.party or d.account)
        if flt(d.credit, precision) > 0:
            accounts_credited.append(d.party or d.account)

    for d in entries:
        if flt(d.debit, precision) > 0:
            new_against = ", ".join(list(set(accounts_credited)))
        if flt(d.credit, precision) > 0:
            new_against = ", ".join(list(set(accounts_debited)))

        if d.against != new_against:
            frappe.db.set_value("GL Entry", d.name, "against", new_against)
def execute(filters=None):
    if not filters: filters = {}

    columns = get_columns(filters)
    entries = get_entries(filters)
    item_details = get_item_details()
    data = []

    company_currency = get_company_currency(filters.get("company"))

    for d in entries:
        if d.stock_qty > 0 or filters.get('show_return_entries', 0):
            data.append([
                d.name, d.customer, d.territory, d.warehouse, d.posting_date,
                d.item_code,
                item_details.get(d.item_code, {}).get("item_group"),
                item_details.get(d.item_code, {}).get("brand"), d.stock_qty,
                d.base_net_amount, d.sales_person, d.allocated_percentage,
                d.contribution_amt, company_currency
            ])

    if data:
        total_row = [""] * len(data[0])
        data.append(total_row)

    return columns, data
Ejemplo n.º 9
0
def merge_similar_entries(gl_map):
    merged_gl_map = []
    accounting_dimensions = get_accounting_dimensions()
    for entry in gl_map:
        # if there is already an entry in this account then just add it
        # to that entry
        same_head = check_if_in_list(entry, merged_gl_map,
                                     accounting_dimensions)
        if same_head:
            same_head.debit = flt(same_head.debit) + flt(entry.debit)
            same_head.debit_in_account_currency = \
             flt(same_head.debit_in_account_currency) + flt(entry.debit_in_account_currency)
            same_head.credit = flt(same_head.credit) + flt(entry.credit)
            same_head.credit_in_account_currency = \
             flt(same_head.credit_in_account_currency) + flt(entry.credit_in_account_currency)
        else:
            merged_gl_map.append(entry)

    company = gl_map[0].company if gl_map else erpbee.get_default_company()
    company_currency = erpbee.get_company_currency(company)
    precision = get_field_precision(
        frappe.get_meta("GL Entry").get_field("debit"), company_currency)

    # filter zero debit and credit entries
    merged_gl_map = filter(
        lambda x: flt(x.debit, precision) != 0 or flt(x.credit, precision) !=
        0, merged_gl_map)
    merged_gl_map = list(merged_gl_map)

    return merged_gl_map
def get_data(filters, mode_of_payments):
	data = []

	conditions = get_conditions(filters)

	entry = frappe.db.sql("""
		select branch, mode_of_payment, sum(net_pay) as net_pay, sum(gross_pay) as gross_pay
		from `tabSalary Slip` sal
		where docstatus = 1 %s
		group by branch, mode_of_payment
		""" % (conditions), as_dict=1)

	branch_wise_entries, gross_pay = prepare_data(entry)

	branches = frappe.db.sql_list("""
		select distinct branch from `tabSalary Slip` sal
		where docstatus = 1 %s
	""" % (conditions))

	total_row = {"total": 0, "branch": "Total"}

	for branch in branches:
		total = 0
		row = {
			"branch": branch
		}
		for mode in mode_of_payments:
			if branch_wise_entries.get(branch).get(mode):
				row[mode] = branch_wise_entries.get(branch).get(mode)
				total +=  branch_wise_entries.get(branch).get(mode)

		row["total"] = total
		data.append(row)

	total_row = get_total_based_on_mode_of_payment(data, mode_of_payments)
	total_deductions = gross_pay - total_row.get("total")

	report_summary = []

	if data:
		data.append(total_row)
		data.append({})
		data.append({
			"branch": "<b>Total Gross Pay</b>",
			mode_of_payments[0]:gross_pay
		})
		data.append({
			"branch": "<b>Total Deductions</b>",
			mode_of_payments[0]:total_deductions
		})
		data.append({
			"branch": "<b>Total Net Pay</b>",
			mode_of_payments[0]:total_row.get("total")
		})

		currency = erpbee.get_company_currency(filters.company)
		report_summary = get_report_summary(gross_pay, total_deductions, total_row.get("total"), currency)

	return data, total_row, report_summary
Ejemplo n.º 11
0
def execute(filters=None):
    if not filters: filters = {}
    currency = None
    if filters.get('currency'):
        currency = filters.get('currency')
    company_currency = erpbee.get_company_currency(filters.get("company"))
    salary_slips = get_salary_slips(filters, company_currency)
    if not salary_slips: return [], []

    columns, earning_types, ded_types = get_columns(salary_slips)
    ss_earning_map = get_ss_earning_map(salary_slips, currency,
                                        company_currency)
    ss_ded_map = get_ss_ded_map(salary_slips, currency, company_currency)
    doj_map = get_employee_doj_map()

    data = []
    for ss in salary_slips:
        row = [
            ss.name, ss.employee, ss.employee_name,
            doj_map.get(ss.employee), ss.branch, ss.department, ss.designation,
            ss.company, ss.start_date, ss.end_date, ss.leave_without_pay,
            ss.payment_days
        ]

        if ss.branch is not None: columns[3] = columns[3].replace('-1', '120')
        if ss.department is not None:
            columns[4] = columns[4].replace('-1', '120')
        if ss.designation is not None:
            columns[5] = columns[5].replace('-1', '120')
        if ss.leave_without_pay is not None:
            columns[9] = columns[9].replace('-1', '130')

        for e in earning_types:
            row.append(ss_earning_map.get(ss.name, {}).get(e))

        if currency == company_currency:
            row += [flt(ss.gross_pay) * flt(ss.exchange_rate)]
        else:
            row += [ss.gross_pay]

        for d in ded_types:
            row.append(ss_ded_map.get(ss.name, {}).get(d))

        row.append(ss.total_loan_repayment)

        if currency == company_currency:
            row += [
                flt(ss.total_deduction) * flt(ss.exchange_rate),
                flt(ss.net_pay) * flt(ss.exchange_rate)
            ]
        else:
            row += [ss.total_deduction, ss.net_pay]
        row.append(currency or company_currency)
        data.append(row)

    return columns, data
Ejemplo n.º 12
0
def create_tax_slab(payroll_period,
                    effective_date=None,
                    allow_tax_exemption=False,
                    dont_submit=False,
                    currency=None,
                    company=None):
    if not currency:
        currency = erpbee.get_default_currency()

    if company:
        currency = erpbee.get_company_currency(company)

    slabs = [{
        "from_amount": 250000,
        "to_amount": 500000,
        "percent_deduction": 5,
        "condition": "annual_taxable_earning > 500000"
    }, {
        "from_amount": 500001,
        "to_amount": 1000000,
        "percent_deduction": 20
    }, {
        "from_amount": 1000001,
        "percent_deduction": 30
    }]

    income_tax_slab_name = frappe.db.get_value("Income Tax Slab",
                                               {"currency": currency})
    if not income_tax_slab_name:
        income_tax_slab = frappe.new_doc("Income Tax Slab")
        income_tax_slab.name = "Tax Slab: " + payroll_period.name + " " + cstr(
            currency)
        income_tax_slab.effective_from = effective_date or add_days(
            payroll_period.start_date, -2)
        income_tax_slab.company = company or ''
        income_tax_slab.currency = currency

        if allow_tax_exemption:
            income_tax_slab.allow_tax_exemption = 1
            income_tax_slab.standard_tax_exemption_amount = 50000

        for item in slabs:
            income_tax_slab.append("slabs", item)

        income_tax_slab.append("other_taxes_and_charges", {
            "description": "cess",
            "percent": 4
        })

        income_tax_slab.save()
        if not dont_submit:
            income_tax_slab.submit()

        return income_tax_slab.name
    else:
        return income_tax_slab_name
 def __init__(self, filters=None):
     self.filters = frappe._dict(filters or {})
     self.data = []
     self.doctype = self.filters.based_on_document
     self.child_doctype = self.doctype + " Item"
     self.based_on_field = ("qty" if self.filters.based_on_field == "Qty"
                            else "amount")
     self.fieldtype = "Float" if self.based_on_field == "qty" else "Currency"
     self.company_currency = erpbee.get_company_currency(
         self.filters.company)
Ejemplo n.º 14
0
def create_purchase_invoice(supplier_name, file_name, args, name):
    args = frappe._dict(args)
    pi = frappe.get_doc({
        "doctype": "Purchase Invoice",
        "company": args.company,
        "currency": erpbee.get_company_currency(args.company),
        "naming_series": args.naming_series,
        "supplier": supplier_name,
        "is_return": args.is_return,
        "posting_date": today(),
        "bill_no": args.bill_no,
        "buying_price_list": args.buying_price_list,
        "bill_date": args.bill_date,
        "destination_code": args.destination_code,
        "document_type": args.document_type,
        "disable_rounded_total": 1,
        "items": args["items"],
        "taxes": args["taxes"]
    })

    try:
        pi.set_missing_values()
        pi.insert(ignore_mandatory=True)

        #if discount exists in file, apply any discount on grand total
        if args.total_discount > 0:
            pi.apply_discount_on = "Grand Total"
            pi.discount_amount = args.total_discount
            pi.save()
        #adjust payment amount to match with grand total calculated
        calc_total = 0
        adj = 0
        for term in args.terms:
            calc_total += flt(term["payment_amount"])
        if flt(calc_total - flt(pi.grand_total)) != 0:
            adj = calc_total - flt(pi.grand_total)
        pi.payment_schedule = []
        for term in args.terms:
            pi.append(
                'payment_schedule', {
                    "mode_of_payment_code": term["mode_of_payment_code"],
                    "bank_account_iban": term["bank_account_iban"],
                    "due_date": term["due_date"],
                    "payment_amount": flt(term["payment_amount"]) - adj
                })
            adj = 0
        pi.imported_grand_total = calc_total
        pi.save()
        return pi.name
    except Exception as e:
        frappe.db.set_value("Import Supplier Invoice", name, "status", "Error")
        frappe.log_error(message=e,
                         title="Create Purchase Invoice: " +
                         args.get("bill_no") + "File Name: " + file_name)
        return None
Ejemplo n.º 15
0
 def validate_expense_accounts(self):
     company_currency = erpbee.get_company_currency(self.company)
     for account in self.taxes:
         if get_account_currency(
                 account.expense_account) != company_currency:
             frappe.throw(_(
                 "Row {}: Expense account currency should be same as company's default currency."
             ).format(account.idx) + _(
                 "Please select expense account with account currency as {}."
             ).format(frappe.bold(company_currency)),
                          title=_("Invalid Account Currency"))
Ejemplo n.º 16
0
def validate_employee_currency_with_company_currency(applicant, company):
    from erpbee.payroll.doctype.salary_structure_assignment.salary_structure_assignment import get_employee_currency
    if not applicant:
        frappe.throw(_("Please select Applicant"))
    if not company:
        frappe.throw(_("Please select Company"))
    employee_currency = get_employee_currency(applicant)
    company_currency = erpbee.get_company_currency(company)
    if employee_currency != company_currency:
        frappe.throw(
            _("Loan cannot be repayed from salary for Employee {0} because salary is processed in currency {1}"
              ).format(applicant, employee_currency))
Ejemplo n.º 17
0
    def validate_conversion_rate(self):
        # validate conversion rate
        company_currency = erpbee.get_company_currency(self.doc.company)
        if not self.doc.currency or self.doc.currency == company_currency:
            self.doc.currency = company_currency
            self.doc.conversion_rate = 1.0
        else:
            validate_conversion_rate(
                self.doc.currency, self.doc.conversion_rate,
                self.doc.meta.get_label("conversion_rate"), self.doc.company)

        self.doc.conversion_rate = flt(self.doc.conversion_rate)
Ejemplo n.º 18
0
def make_employee_advance(employee_name):
	doc = frappe.new_doc("Employee Advance")
	doc.employee = employee_name
	doc.company  = "_Test company"
	doc.purpose = "For site visit"
	doc.currency = erpbee.get_company_currency("_Test company")
	doc.exchange_rate = 1
	doc.advance_amount = 1000
	doc.posting_date = nowdate()
	doc.advance_account = "_Test Employee Advance - _TC"
	doc.insert()
	doc.submit()

	return doc
Ejemplo n.º 19
0
    def validate_currency(self):
        company_currency = erpbee.get_company_currency(self.company)
        account_currency = get_account_currency(self.account)

        if not self.account_currency:
            self.account_currency = company_currency

        if account_currency != self.account_currency:
            frappe.throw(
                _("{0} {1}: Accounting Entry for {2} can only be made in currency: {3}"
                  ).format(self.voucher_type, self.voucher_no, self.account,
                           (account_currency or company_currency)),
                InvalidAccountCurrency)

        if self.party_type and self.party:
            validate_party_gle_currency(self.party_type, self.party,
                                        self.company, self.account_currency)
Ejemplo n.º 20
0
    def get_dashboard_info(self):
        info = {
            "total_paid": 0,
            "total_unpaid": 0,
            "currency": erpbee.get_company_currency(self.company)
        }

        fees_amount = frappe.db.sql(
            """select sum(grand_total), sum(outstanding_amount) from tabFees
			where fee_schedule=%s and docstatus=1""", (self.name))

        if fees_amount:
            info["total_paid"] = flt(fees_amount[0][0]) - flt(
                fees_amount[0][1])
            info["total_unpaid"] = flt(fees_amount[0][1])

        return info
Ejemplo n.º 21
0
    def get_accounts_data(self, account=None):
        accounts = []
        self.validate_mandatory()
        company_currency = erpbee.get_company_currency(self.company)
        precision = get_field_precision(
            frappe.get_meta("Exchange Rate Revaluation Account").get_field(
                "new_balance_in_base_currency"), company_currency)

        account_details = self.get_accounts_from_gle()
        for d in account_details:
            current_exchange_rate = d.balance / d.balance_in_account_currency \
             if d.balance_in_account_currency else 0
            new_exchange_rate = get_exchange_rate(d.account_currency,
                                                  company_currency,
                                                  self.posting_date)
            new_balance_in_base_currency = flt(d.balance_in_account_currency *
                                               new_exchange_rate)
            gain_loss = flt(new_balance_in_base_currency, precision) - flt(
                d.balance, precision)
            if gain_loss:
                accounts.append({
                    "account":
                    d.account,
                    "party_type":
                    d.party_type,
                    "party":
                    d.party,
                    "account_currency":
                    d.account_currency,
                    "balance_in_base_currency":
                    d.balance,
                    "balance_in_account_currency":
                    d.balance_in_account_currency,
                    "current_exchange_rate":
                    current_exchange_rate,
                    "new_exchange_rate":
                    new_exchange_rate,
                    "new_balance_in_base_currency":
                    new_balance_in_base_currency
                })

        if not accounts:
            self.throw_invalid_response_message(account_details)

        return accounts
Ejemplo n.º 22
0
    def get_serialized_values(self, sle):
        incoming_rate = flt(sle.incoming_rate)
        actual_qty = flt(sle.actual_qty)
        serial_nos = cstr(sle.serial_no).split("\n")

        if incoming_rate < 0:
            # wrong incoming rate
            incoming_rate = self.wh_data.valuation_rate

        stock_value_change = 0
        if incoming_rate:
            stock_value_change = actual_qty * incoming_rate
        elif actual_qty < 0:
            # In case of delivery/stock issue, get average purchase rate
            # of serial nos of current entry
            if not sle.is_cancelled:
                outgoing_value = self.get_incoming_value_for_serial_nos(
                    sle, serial_nos)
                stock_value_change = -1 * outgoing_value
            else:
                stock_value_change = actual_qty * sle.outgoing_rate

        new_stock_qty = self.wh_data.qty_after_transaction + actual_qty

        if new_stock_qty > 0:
            new_stock_value = (
                self.wh_data.qty_after_transaction *
                self.wh_data.valuation_rate) + stock_value_change
            if new_stock_value >= 0:
                # calculate new valuation rate only if stock value is positive
                # else it remains the same as that of previous entry
                self.wh_data.valuation_rate = new_stock_value / new_stock_qty

        if not self.wh_data.valuation_rate and sle.voucher_detail_no:
            allow_zero_rate = self.check_if_allow_zero_valuation_rate(
                sle.voucher_type, sle.voucher_detail_no)
            if not allow_zero_rate:
                self.wh_data.valuation_rate = get_valuation_rate(
                    sle.item_code,
                    sle.warehouse,
                    sle.voucher_type,
                    sle.voucher_no,
                    self.allow_zero_rate,
                    currency=erpbee.get_company_currency(sle.company))
Ejemplo n.º 23
0
    def create_journal_entry(self, je_payment_amount, user_remark):
        payroll_payable_account = self.payroll_payable_account
        precision = frappe.get_precision("Journal Entry Account",
                                         "debit_in_account_currency")

        accounts = []
        currencies = []
        multi_currency = 0
        company_currency = erpbee.get_company_currency(self.company)

        exchange_rate, amount = self.get_amount_and_exchange_rate_for_journal_entry(
            self.payment_account, je_payment_amount, company_currency,
            currencies)
        accounts.append({
            "account": self.payment_account,
            "bank_account": self.bank_account,
            "credit_in_account_currency": flt(amount, precision),
            "exchange_rate": flt(exchange_rate),
        })

        exchange_rate, amount = self.get_amount_and_exchange_rate_for_journal_entry(
            payroll_payable_account, je_payment_amount, company_currency,
            currencies)
        accounts.append({
            "account": payroll_payable_account,
            "debit_in_account_currency": flt(amount, precision),
            "exchange_rate": flt(exchange_rate),
            "reference_type": self.doctype,
            "reference_name": self.name
        })

        if len(currencies) > 1:
            multi_currency = 1

        journal_entry = frappe.new_doc('Journal Entry')
        journal_entry.voucher_type = 'Bank Entry'
        journal_entry.user_remark = _('Payment of {0} from {1} to {2}')\
         .format(user_remark, self.start_date, self.end_date)
        journal_entry.company = self.company
        journal_entry.posting_date = self.posting_date
        journal_entry.multi_currency = multi_currency

        journal_entry.set("accounts", accounts)
        journal_entry.save(ignore_permissions=True)
Ejemplo n.º 24
0
    def get_moving_average_values(self, sle):
        actual_qty = flt(sle.actual_qty)
        new_stock_qty = flt(self.wh_data.qty_after_transaction) + actual_qty
        if new_stock_qty >= 0:
            if actual_qty > 0:
                if flt(self.wh_data.qty_after_transaction) <= 0:
                    self.wh_data.valuation_rate = sle.incoming_rate
                else:
                    new_stock_value = (self.wh_data.qty_after_transaction * self.wh_data.valuation_rate) + \
                     (actual_qty * sle.incoming_rate)

                    self.wh_data.valuation_rate = new_stock_value / new_stock_qty

            elif sle.outgoing_rate:
                if new_stock_qty:
                    new_stock_value = (self.wh_data.qty_after_transaction * self.wh_data.valuation_rate) + \
                     (actual_qty * sle.outgoing_rate)

                    self.wh_data.valuation_rate = new_stock_value / new_stock_qty
                else:
                    self.wh_data.valuation_rate = sle.outgoing_rate

        else:
            if flt(self.wh_data.qty_after_transaction
                   ) >= 0 and sle.outgoing_rate:
                self.wh_data.valuation_rate = sle.outgoing_rate

            if not self.wh_data.valuation_rate and actual_qty > 0:
                self.wh_data.valuation_rate = sle.incoming_rate

            # Get valuation rate from previous SLE or Item master, if item does not have the
            # allow zero valuration rate flag set
            if not self.wh_data.valuation_rate and sle.voucher_detail_no:
                allow_zero_valuation_rate = self.check_if_allow_zero_valuation_rate(
                    sle.voucher_type, sle.voucher_detail_no)
                if not allow_zero_valuation_rate:
                    self.wh_data.valuation_rate = get_valuation_rate(
                        sle.item_code,
                        sle.warehouse,
                        sle.voucher_type,
                        sle.voucher_no,
                        self.allow_zero_rate,
                        currency=erpbee.get_company_currency(sle.company))
Ejemplo n.º 25
0
def update_totals(gst_tax, base_gst_tax, doc):
	doc.base_grand_total -= base_gst_tax
	doc.grand_total -= gst_tax

	if doc.meta.get_field("rounded_total"):
		if doc.is_rounded_total_disabled():
			doc.outstanding_amount = doc.grand_total
		else:
			doc.rounded_total = round_based_on_smallest_currency_fraction(doc.grand_total,
				doc.currency, doc.precision("rounded_total"))

			doc.rounding_adjustment += flt(doc.rounded_total - doc.grand_total,
				doc.precision("rounding_adjustment"))

			doc.outstanding_amount = doc.rounded_total or doc.grand_total

	doc.in_words = money_in_words(doc.grand_total, doc.currency)
	doc.base_in_words = money_in_words(doc.base_grand_total, erpbee.get_company_currency(doc.company))
	doc.set_payment_schedule()
Ejemplo n.º 26
0
def validate_quantity(doc, args, ref, valid_items, already_returned_items):
    fields = ['stock_qty']
    if doc.doctype in ['Purchase Receipt', 'Purchase Invoice']:
        fields.extend(['received_qty', 'rejected_qty'])

    already_returned_data = already_returned_items.get(args.item_code) or {}

    company_currency = erpbee.get_company_currency(doc.company)
    stock_qty_precision = get_field_precision(
        frappe.get_meta(doc.doctype + " Item").get_field("stock_qty"),
        company_currency)

    for column in fields:
        returned_qty = flt(already_returned_data.get(
            column, 0)) if len(already_returned_data) > 0 else 0

        if column == 'stock_qty':
            reference_qty = ref.get(column)
            current_stock_qty = args.get(column)
        else:
            reference_qty = ref.get(column) * ref.get("conversion_factor", 1.0)
            current_stock_qty = args.get(column) * args.get(
                "conversion_factor", 1.0)

        max_returnable_qty = flt(reference_qty,
                                 stock_qty_precision) - returned_qty
        label = column.replace('_', ' ').title()

        if reference_qty:
            if flt(args.get(column)) > 0:
                frappe.throw(
                    _("{0} must be negative in return document").format(label))
            elif returned_qty >= reference_qty and args.get(column):
                frappe.throw(
                    _("Item {0} has already been returned").format(
                        args.item_code), StockOverReturnError)
            elif abs(flt(current_stock_qty,
                         stock_qty_precision)) > max_returnable_qty:
                frappe.throw(
                    _("Row # {0}: Cannot return more than {1} for Item {2}"
                      ).format(args.idx, max_returnable_qty, args.item_code),
                    StockOverReturnError)
Ejemplo n.º 27
0
    def validate_overlapping_shipping_rule_conditions(self):
        def overlap_exists_between(num_range1, num_range2):
            """
				num_range1 and num_range2 are two ranges
				ranges are represented as a tuple e.g. range 100 to 300 is represented as (100, 300)
				if condition num_range1 = 100 to 300
				then condition num_range2 can only be like 50 to 99 or 301 to 400
				hence, non-overlapping condition = (x1 <= x2 < y1 <= y2) or (y1 <= y2 < x1 <= x2)
			"""
            (x1, x2), (y1, y2) = num_range1, num_range2
            separate = (x1 <= x2 <= y1 <= y2) or (y1 <= y2 <= x1 <= x2)
            return (not separate)

        overlaps = []
        for i in range(0, len(self.conditions)):
            for j in range(i + 1, len(self.conditions)):
                d1, d2 = self.conditions[i], self.conditions[j]
                if d1.as_dict() != d2.as_dict():
                    # in our case, to_value can be zero, hence pass the from_value if so
                    range_a = (d1.from_value, d1.to_value or d1.from_value)
                    range_b = (d2.from_value, d2.to_value or d2.from_value)
                    if overlap_exists_between(range_a, range_b):
                        overlaps.append([d1, d2])

        if overlaps:
            company_currency = erpbee.get_company_currency(self.company)
            msgprint(_("Overlapping conditions found between:"))
            messages = []
            for d1, d2 in overlaps:
                messages.append(
                    "%s-%s = %s " %
                    (d1.from_value, d1.to_value,
                     fmt_money(d1.shipping_amount, currency=company_currency))
                    + _("and") + " %s-%s = %s" %
                    (d2.from_value, d2.to_value,
                     fmt_money(d2.shipping_amount, currency=company_currency)))

            msgprint("\n".join(messages),
                     raise_exception=OverlappingConditionError)
Ejemplo n.º 28
0
def tax_account_query(doctype, txt, searchfield, start, page_len, filters):
    company_currency = erpbee.get_company_currency(filters.get('company'))

    def get_accounts(with_account_type_filter):
        account_type_condition = ''
        if with_account_type_filter:
            account_type_condition = "AND account_type in %(account_types)s"

        accounts = frappe.db.sql(
            """
			SELECT name, parent_account
			FROM `tabAccount`
			WHERE `tabAccount`.docstatus!=2
				{account_type_condition}
				AND is_group = 0
				AND company = %(company)s
				AND account_currency = %(currency)s
				AND `{searchfield}` LIKE %(txt)s
				{mcond}
			ORDER BY idx DESC, name
			LIMIT %(offset)s, %(limit)s
		""".format(account_type_condition=account_type_condition,
             searchfield=searchfield,
             mcond=get_match_cond(doctype)),
            dict(account_types=filters.get("account_type"),
                 company=filters.get("company"),
                 currency=company_currency,
                 txt="%{}%".format(txt),
                 offset=start,
                 limit=page_len))

        return accounts

    tax_accounts = get_accounts(True)

    if not tax_accounts:
        tax_accounts = get_accounts(False)

    return tax_accounts
Ejemplo n.º 29
0
 def set_missing_accounts_and_fields(self):
     if not self.company:
         self.company = frappe.defaults.get_defaults().company
     if not self.currency:
         self.currency = erpbee.get_company_currency(self.company)
     if not (self.receivable_account and self.income_account
             and self.cost_center):
         accounts_details = frappe.get_all("Company",
                                           fields=[
                                               "default_receivable_account",
                                               "default_income_account",
                                               "cost_center"
                                           ],
                                           filters={"name":
                                                    self.company})[0]
     if not self.receivable_account:
         self.receivable_account = accounts_details.default_receivable_account
     if not self.income_account:
         self.income_account = accounts_details.default_income_account
     if not self.cost_center:
         self.cost_center = accounts_details.cost_center
     if not self.student_email:
         self.student_email = self.get_student_emails()
Ejemplo n.º 30
0
def get_account_details(account,
                        company,
                        posting_date,
                        party_type=None,
                        party=None):
    account_currency, account_type = frappe.db.get_value(
        "Account", account, ["account_currency", "account_type"])
    if account_type in ["Receivable", "Payable"
                        ] and not (party_type and party):
        frappe.throw(
            _("Party Type and Party is mandatory for {0} account").format(
                account_type))

    account_details = {}
    company_currency = erpbee.get_company_currency(company)
    balance = get_balance_on(account,
                             party_type=party_type,
                             party=party,
                             in_account_currency=False)
    if balance:
        balance_in_account_currency = get_balance_on(account,
                                                     party_type=party_type,
                                                     party=party)
        current_exchange_rate = balance / balance_in_account_currency if balance_in_account_currency else 0
        new_exchange_rate = get_exchange_rate(account_currency,
                                              company_currency, posting_date)
        new_balance_in_base_currency = balance_in_account_currency * new_exchange_rate
        account_details = {
            "account_currency": account_currency,
            "balance_in_base_currency": balance,
            "balance_in_account_currency": balance_in_account_currency,
            "current_exchange_rate": current_exchange_rate,
            "new_exchange_rate": new_exchange_rate,
            "new_balance_in_base_currency": new_balance_in_base_currency
        }

    return account_details