def get_party_details(company, party_type, party, date, cost_center=None):
    bank_account = ''
    if not frappe.db.exists(party_type, party):
        frappe.throw(_("Invalid {0}: {1}").format(party_type, party))

    party_account = get_party_account(party_type, party, company)

    account_currency = get_account_currency(party_account)
    account_balance = get_balance_on(party_account,
                                     date,
                                     cost_center=cost_center)
    _party_name = "title" if party_type in (
        "Student", "Shareholder") else party_type.lower() + "_name"
    party_name = frappe.db.get_value(party_type, party, _party_name)
    party_balance = get_balance_on(party_type=party_type,
                                   party=party,
                                   cost_center=cost_center)
    if party_type in ["Customer", "Supplier"]:
        bank_account = get_party_bank_account(party_type, party)

    return {
        "party_account": party_account,
        "party_name": party_name,
        "party_account_currency": account_currency,
        "party_balance": party_balance,
        "account_balance": account_balance,
        "bank_account": bank_account
    }
Beispiel #2
0
def get_party_details(company, party_type, party, date, cost_center=None):
	bank_account = ''
	if not frappe.db.exists(party_type, party):
		frappe.throw(_("Invalid {0}: {1}").format(party_type, party))

	party_account = get_party_account(party_type, party, company)

	account_currency = get_account_currency(party_account)
	account_balance = get_balance_on(party_account, date, cost_center=cost_center)
	_party_name = "title" if party_type in ("Student", "Shareholder") else party_type.lower() + "_name"
	party_name = frappe.db.get_value(party_type, party, _party_name)
	party_balance = get_balance_on(party_type=party_type, party=party, cost_center=cost_center)
	if party_type in ["Customer", "Supplier"]:
		bank_account = get_party_bank_account(party_type, party)

	return {
		"party_account": party_account,
		"party_name": party_name,
		"party_account_currency": account_currency,
		"party_balance": party_balance,
		"account_balance": account_balance,
		"bank_account": bank_account
	}
def get_payment_entry(dt,
                      dn,
                      party_amount=None,
                      bank_account=None,
                      bank_amount=None):
    doc = frappe.get_doc(dt, dn)
    if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) > 0:
        frappe.throw(
            _("Can only make payment against unbilled {0}").format(dt))

    if dt in ("Sales Invoice", "Sales Order"):
        party_type = "Customer"
    elif dt in ("Purchase Invoice", "Purchase Order"):
        party_type = "Supplier"
    elif dt in ("Expense Claim", "Employee Advance"):
        party_type = "Employee"
    elif dt in ("Fees"):
        party_type = "Student"

    # party account
    if dt == "Sales Invoice":
        party_account = doc.debit_to
    elif dt == "Purchase Invoice":
        party_account = doc.credit_to
    elif dt == "Fees":
        party_account = doc.receivable_account
    elif dt == "Employee Advance":
        party_account = doc.advance_account
    elif dt == "Expense Claim":
        party_account = doc.payable_account
    else:
        party_account = get_party_account(party_type,
                                          doc.get(party_type.lower()),
                                          doc.company)

    party_account_currency = doc.get(
        "party_account_currency") or get_account_currency(party_account)

    # payment type
    if (dt == "Sales Order" or (dt in ("Sales Invoice", "Fees") and doc.outstanding_amount > 0)) \
     or (dt=="Purchase Invoice" and doc.outstanding_amount < 0):
        payment_type = "Receive"
    else:
        payment_type = "Pay"

    # amounts
    grand_total = outstanding_amount = 0
    if party_amount:
        grand_total = outstanding_amount = party_amount
    elif dt in ("Sales Invoice", "Purchase Invoice"):
        if party_account_currency == doc.company_currency:
            grand_total = doc.base_rounded_total or doc.base_grand_total
        else:
            grand_total = doc.rounded_total or doc.grand_total
        outstanding_amount = doc.outstanding_amount
    elif dt in ("Expense Claim"):
        grand_total = doc.total_sanctioned_amount
        outstanding_amount = doc.total_sanctioned_amount \
         - doc.total_amount_reimbursed - flt(doc.total_advance_amount)
    elif dt == "Employee Advance":
        grand_total = doc.advance_amount
        outstanding_amount = flt(doc.advance_amount) - flt(doc.paid_amount)
    elif dt == "Fees":
        grand_total = doc.grand_total
        outstanding_amount = doc.outstanding_amount
    else:
        if party_account_currency == doc.company_currency:
            grand_total = flt(
                doc.get("base_rounded_total") or doc.base_grand_total)
        else:
            grand_total = flt(doc.get("rounded_total") or doc.grand_total)
        outstanding_amount = grand_total - flt(doc.advance_paid)

    # bank or cash
    bank = get_default_bank_cash_account(
        doc.company,
        "Bank",
        mode_of_payment=doc.get("mode_of_payment"),
        account=bank_account)

    paid_amount = received_amount = 0
    if party_account_currency == bank.account_currency:
        paid_amount = received_amount = abs(outstanding_amount)
    elif payment_type == "Receive":
        paid_amount = abs(outstanding_amount)
        if bank_amount:
            received_amount = bank_amount
    else:
        received_amount = abs(outstanding_amount)
        if bank_amount:
            paid_amount = bank_amount

    pe = frappe.new_doc("Payment Entry")
    pe.payment_type = payment_type
    pe.company = doc.company
    pe.cost_center = doc.get("cost_center")
    pe.posting_date = nowdate()
    pe.mode_of_payment = doc.get("mode_of_payment")
    pe.party_type = party_type
    pe.party = doc.get(scrub(party_type))
    pe.contact_person = doc.get("contact_person")
    pe.contact_email = doc.get("contact_email")
    pe.ensure_supplier_is_not_blocked()

    pe.paid_from = party_account if payment_type == "Receive" else bank.account
    pe.paid_to = party_account if payment_type == "Pay" else bank.account
    pe.paid_from_account_currency = party_account_currency \
     if payment_type=="Receive" else bank.account_currency
    pe.paid_to_account_currency = party_account_currency if payment_type == "Pay" else bank.account_currency
    pe.paid_amount = paid_amount
    pe.received_amount = received_amount
    pe.allocate_payment_amount = 1
    pe.letter_head = doc.get("letter_head")

    if pe.party_type in ["Customer", "Supplier"]:
        bank_account = get_party_bank_account(pe.party_type, pe.party)
        pe.set("bank_account", bank_account)
        pe.set_bank_account_data()

    # only Purchase Invoice can be blocked individually
    if doc.doctype == "Purchase Invoice" and doc.invoice_is_blocked():
        frappe.msgprint(
            _('{0} is on hold till {1}'.format(doc.name, doc.release_date)))
    else:
        pe.append(
            "references", {
                'reference_doctype': dt,
                'reference_name': dn,
                "bill_no": doc.get("bill_no"),
                "due_date": doc.get("due_date"),
                'total_amount': grand_total,
                'outstanding_amount': outstanding_amount,
                'allocated_amount': outstanding_amount
            })

    pe.setup_party_account_field()
    pe.set_missing_values()
    if party_account and bank:
        pe.set_exchange_rate()
        pe.set_amounts()
    return pe
Beispiel #4
0
def get_payment_entry(dt,
                      dn,
                      party_amount=None,
                      bank_account=None,
                      bank_amount=None):
    from erpnext.accounts.party import get_party_account
    from erpnext.accounts.utils import get_account_currency
    from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
    from erpnext.accounts.doctype.bank_account.bank_account import get_party_bank_account
    doc = frappe.get_doc(dt, dn)
    # siwari change
    dt = "Sales Order"

    if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) > 0:
        frappe.throw(
            _("Can only make payment against unbilled {0}").format(dt))

    if dt in ("Sales Invoice", "Sales Order"):
        party_type = "Customer"
    elif dt in ("Purchase Invoice", "Purchase Order"):
        party_type = "Supplier"
    elif dt in ("Expense Claim", "Employee Advance"):
        party_type = "Employee"
    elif dt in ("Fees"):
        party_type = "Student"

    # party account
    if dt == "Sales Invoice":
        party_account = get_party_account_based_on_invoice_discounting(
            dn) or doc.debit_to
    elif dt == "Purchase Invoice":
        party_account = doc.credit_to
    elif dt == "Fees":
        party_account = doc.receivable_account
    elif dt == "Employee Advance":
        party_account = doc.advance_account
    elif dt == "Expense Claim":
        party_account = doc.payable_account
    else:
        party_account = get_party_account(party_type,
                                          doc.get(party_type.lower()),
                                          doc.company)

    if dt not in ("Sales Invoice", "Purchase Invoice"):
        party_account_currency = get_account_currency(party_account)
    else:
        party_account_currency = doc.get(
            "party_account_currency") or get_account_currency(party_account)

    # payment type
    if (dt == "Sales Order" or (dt in ("Sales Invoice", "Fees") and doc.outstanding_amount > 0)) \
     or (dt=="Purchase Invoice" and doc.outstanding_amount < 0):
        payment_type = "Receive"
    else:
        payment_type = "Pay"

    # amounts
    grand_total = outstanding_amount = 0
    if party_amount:
        grand_total = outstanding_amount = party_amount
    elif dt in ("Sales Invoice", "Purchase Invoice"):
        if party_account_currency == doc.company_currency:
            grand_total = doc.base_rounded_total or doc.base_grand_total
        else:
            grand_total = doc.rounded_total or doc.grand_total
        outstanding_amount = doc.outstanding_amount
    elif dt in ("Expense Claim"):
        grand_total = doc.total_sanctioned_amount + doc.total_taxes_and_charges
        outstanding_amount = doc.grand_total \
         - doc.total_amount_reimbursed
    elif dt == "Employee Advance":
        grand_total = doc.advance_amount
        outstanding_amount = flt(doc.advance_amount) - flt(doc.paid_amount)
    elif dt == "Fees":
        grand_total = doc.grand_total
        outstanding_amount = doc.outstanding_amount
    else:
        if party_account_currency == doc.company_currency:
            grand_total = flt(
                doc.get("base_rounded_total") or doc.base_grand_total)
        else:
            grand_total = flt(doc.get("rounded_total") or doc.grand_total)
        outstanding_amount = grand_total - flt(doc.advance_paid)

    # bank or cash
    bank = get_default_bank_cash_account(
        doc.company,
        "Bank",
        mode_of_payment=doc.get("mode_of_payment"),
        account=bank_account)

    if not bank:
        bank = get_default_bank_cash_account(
            doc.company,
            "Cash",
            mode_of_payment=doc.get("mode_of_payment"),
            account=bank_account)

    paid_amount = received_amount = 0
    if party_account_currency == bank.account_currency:
        paid_amount = received_amount = abs(outstanding_amount)
    elif payment_type == "Receive":
        paid_amount = abs(outstanding_amount)
        if bank_amount:
            received_amount = bank_amount
        else:
            received_amount = paid_amount * doc.conversion_rate
    else:
        received_amount = abs(outstanding_amount)
        if bank_amount:
            paid_amount = bank_amount
        else:
            # if party account currency and bank currency is different then populate paid amount as well
            paid_amount = received_amount * doc.conversion_rate

    pe = frappe.new_doc("Payment Entry")
    pe.payment_type = payment_type
    pe.company = doc.company
    pe.cost_center = doc.get("cost_center")
    pe.posting_date = nowdate()
    pe.mode_of_payment = doc.get("mode_of_payment")
    pe.party_type = party_type
    pe.party = doc.get(scrub(party_type))
    pe.contact_person = doc.get("contact_person")
    pe.contact_email = doc.get("contact_email")
    pe.ensure_supplier_is_not_blocked()

    pe.paid_from = party_account if payment_type == "Receive" else bank.account
    pe.paid_to = party_account if payment_type == "Pay" else bank.account
    pe.paid_from_account_currency = party_account_currency \
     if payment_type=="Receive" else bank.account_currency
    pe.paid_to_account_currency = party_account_currency if payment_type == "Pay" else bank.account_currency
    pe.paid_amount = paid_amount
    pe.received_amount = received_amount
    pe.letter_head = doc.get("letter_head")

    if pe.party_type in ["Customer", "Supplier"]:
        bank_account = get_party_bank_account(pe.party_type, pe.party)
        pe.set("bank_account", bank_account)
        pe.set_bank_account_data()

    # only Purchase Invoice can be blocked individually
    if doc.doctype == "Purchase Invoice" and doc.invoice_is_blocked():
        frappe.msgprint(
            _('{0} is on hold till {1}'.format(doc.name, doc.release_date)))
    else:
        # siwari change
        pass

    pe.setup_party_account_field()
    pe.set_missing_values()
    if party_account and bank:
        pe.set_exchange_rate()
        pe.set_amounts()
    return pe
Beispiel #5
0
def create_payment_entry(
    company,
    customer,
    amount,
    currency,
    mode_of_payment,
    reference_date=None,
    reference_no=None,
    posting_date=None,
    submit=0,
):
    # TODO : need to have a better way to handle currency
    date = nowdate() if not posting_date else posting_date
    party_type = "Customer"
    party_account = get_party_account(party_type, customer, company)
    party_account_currency = get_account_currency(party_account)
    if party_account_currency != currency:
        frappe.throw(
            _("Currency is not correct, party account currency is {party_account_currency} and transaction currency is {currency}"
              ).format(party_account_currency=party_account_currency,
                       currency=currency))
    payment_type = "Receive"

    bank = get_bank_cash_account(company, mode_of_payment)
    company_currency = frappe.get_value("Company", company, "default_currency")
    conversion_rate = get_exchange_rate(currency, company_currency, date,
                                        "for_selling")
    paid_amount, received_amount = set_paid_amount_and_received_amount(
        party_account_currency, bank, amount, payment_type, None,
        conversion_rate)

    pe = frappe.new_doc("Payment Entry")
    pe.payment_type = payment_type
    pe.company = company
    pe.cost_center = erpnext.get_default_cost_center(company)
    pe.posting_date = date
    pe.mode_of_payment = mode_of_payment
    pe.party_type = party_type
    pe.party = customer

    pe.paid_from = party_account if payment_type == "Receive" else bank.account
    pe.paid_to = party_account if payment_type == "Pay" else bank.account
    pe.paid_from_account_currency = (party_account_currency if payment_type
                                     == "Receive" else bank.account_currency)
    pe.paid_to_account_currency = (party_account_currency if payment_type
                                   == "Pay" else bank.account_currency)
    pe.paid_amount = paid_amount
    pe.received_amount = received_amount
    pe.letter_head = frappe.get_value("Company", company,
                                      "default_letter_head")
    pe.reference_date = reference_date
    pe.reference_no = reference_no
    if pe.party_type in ["Customer", "Supplier"]:
        bank_account = get_party_bank_account(pe.party_type, pe.party)
        pe.set("bank_account", bank_account)
        pe.set_bank_account_data()

    pe.setup_party_account_field()
    pe.set_missing_values()

    if party_account and bank:
        pe.set_amounts()
    if submit:
        pe.docstatus = 1
    pe.insert(ignore_permissions=True)
    return pe
Beispiel #6
0
    def get_payment_entry(self, transaction):
        company_currency = frappe.db.get_value("Company", self.company,
                                               "default_currency")
        party_account_currency = get_account_currency(self.party_account)

        # payment type
        if (self.reconciliation_doctype == "Sales Invoice" and transaction.get("amount") > 0) \
         or (self.reconciliation_doctype == "Purchase Invoice" and transaction.get("amount") > 0):
            payment_type = "Receive"
        else:
            payment_type = "Pay"

        # total outstanding
        total_outstanding_amount = 0
        if self.reconciliation_doctype in ("Sales Invoice",
                                           "Purchase Invoice"):
            total_outstanding_amount = sum(
                [x.get("outstanding_amount") for x in self.documents])
        elif self.reconciliation_doctype in ("Expense Claim"):
            total_outstanding_amount = sum([
                (flt(x.get("grand_total")) -
                 flt(x.get("total_amount_reimbursed"))) for x in self.documents
            ])
        elif self.reconciliation_doctype == "Employee Advance":
            total_outstanding_amount = sum([
                (flt(x.get("advance_amount")) - flt(x.get("paid_amount")))
                for x in self.documents
            ])

        bank_account = frappe.get_doc("Bank Account",
                                      transaction.get("bank_account"))
        account_currency = frappe.db.get_value("Account", bank_account.account,
                                               "account_currency")

        paid_amount = received_amount = 0
        outstanding_amount = sum(
            [x.get("outstanding_amount") for x in self.documents])
        amount_to_pay_or_receive = abs(transaction.get("unallocated_amount")) \
          if abs(transaction.get("unallocated_amount")) <= outstanding_amount else outstanding_amount
        if party_account_currency == account_currency:
            paid_amount = received_amount = amount_to_pay_or_receive
        elif payment_type == "Receive":
            paid_amount = amount_to_pay_or_receive
            target_exchange_rate = total_outstanding_amount / paid_amount
            received_amount = total_outstanding_amount
        else:
            received_amount = amount_to_pay_or_receive
            source_exchange_rate = received_amount / total_outstanding_amount
            paid_amount = total_outstanding_amount

        pe = frappe.new_doc("Payment Entry")
        pe.payment_type = payment_type
        pe.company = bank_account.company
        pe.cost_center = self.cost_center
        pe.posting_date = getdate(parse_date(transaction.get("date")))
        pe.mode_of_payment = self.mode_of_payment
        pe.party_type = self.party_type
        pe.party = self.party
        contacts = [x.get("contact_person") for x in self.documents]
        pe.contact_person = contacts[0] if contacts else None
        pe.contact_email = " ,".join([
            x.get("contact_email") for x in self.documents
            if x.get("contact_email")
        ])
        pe.ensure_supplier_is_not_blocked()

        pe.paid_from = self.party_account if payment_type == "Receive" else bank_account.account
        pe.paid_to = self.party_account if payment_type == "Pay" else bank_account.account
        pe.paid_from_account_currency = party_account_currency \
         if payment_type == "Receive" else account_currency
        pe.paid_to_account_currency = party_account_currency if payment_type == "Pay" else account_currency
        pe.paid_amount = paid_amount
        pe.received_amount = received_amount
        letter_heads = [x.get("letter_head") for x in self.documents]
        pe.letter_head = letter_heads[0] if letter_heads else None
        pe.reference_no = transaction.get(
            "reference_number") or transaction.get("name")
        pe.reference_date = getdate(parse_date(transaction.get("date")))
        pe.bank_account = bank_account.name

        if pe.party_type in ["Customer", "Supplier"]:
            bank_account = get_party_bank_account(pe.party_type, pe.party)
            pe.set("party_bank_account", bank_account)
        pe.set_bank_account_data()

        total_allocated_amount = 0
        for doc in self.documents:
            # only Purchase Invoice can be blocked individually
            if doc.get("doctype") == "Purchase Invoice":
                pi = frappe.get_doc("Purchase Invoice", doc.get("name"))
                if pi.invoice_is_blocked():
                    frappe.throw(
                        _('{0} is on hold till {1}'.format(
                            pi.name, pi.release_date)))

            # amounts
            grand_total = outstanding_amount = 0
            if self.reconciliation_doctype in ("Sales Invoice",
                                               "Purchase Invoice"):
                if party_account_currency == doc.get("company_currency"):
                    grand_total = doc.get("base_rounded_total") or doc.get(
                        "base_grand_total")
                else:
                    grand_total = doc.get("rounded_total") or doc.get(
                        "grand_total")
                outstanding_amount = doc.get("outstanding_amount")
            elif self.reconciliation_doctype in ("Expense Claim"):
                grand_total = doc.get("total_sanctioned_amount") + doc.get(
                    "total_taxes_and_charges")
                outstanding_amount = doc.get("grand_total") - doc.get(
                    "total_amount_reimbursed")
            elif self.reconciliation_doctype == "Employee Advance":
                grand_total = doc.get("advance_amount")
                outstanding_amount = flt(doc.get("advance_amount")) - flt(
                    doc.get("paid_amount"))
            else:
                if party_account_currency == doc.get("company_currency"):
                    grand_total = flt(
                        doc.get("base_rounded_total")
                        or doc.get("base_grand_total"))
                else:
                    grand_total = flt(
                        doc.get("rounded_total") or doc.get("grand_total"))
                outstanding_amount = grand_total - flt(doc.get("advance_paid"))

            allocated_amount = min(
                outstanding_amount,
                flt(abs(transaction.get("unallocated_amount"))) -
                flt(total_allocated_amount))

            pe.append(
                "references", {
                    'reference_doctype': doc.get("doctype"),
                    'reference_name': doc.get("name"),
                    "bill_no": doc.get("bill_no"),
                    "due_date": doc.get("due_date"),
                    'total_amount': grand_total,
                    'outstanding_amount': outstanding_amount,
                    'allocated_amount': allocated_amount
                })

            total_allocated_amount += allocated_amount

        pe.setup_party_account_field()
        pe.set_missing_values()
        if self.party_account and bank_account:
            pe.set_exchange_rate()
            pe.set_amounts()
        return pe
Beispiel #7
0
def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=None):
	doc = frappe.get_doc(dt, dn)
	if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) > 0:
		frappe.throw(_("Can only make payment against unbilled {0}").format(dt))

	if dt in ("Sales Invoice", "Sales Order"):
		party_type = "Customer"
	elif dt in ("Purchase Invoice", "Purchase Order"):
		party_type = "Supplier"
	elif dt in ("Expense Claim", "Employee Advance"):
		party_type = "Employee"
	elif dt in ("Fees"):
		party_type = "Student"

	# party account
	if dt == "Sales Invoice":
		party_account = doc.debit_to
	elif dt == "Purchase Invoice":
		party_account = doc.credit_to
	elif dt == "Fees":
		party_account = doc.receivable_account
	elif dt == "Employee Advance":
		party_account = doc.advance_account
	elif dt == "Expense Claim":
		party_account = doc.payable_account
	else:
		party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company)

	party_account_currency = doc.get("party_account_currency") or get_account_currency(party_account)

	# payment type
	if (dt == "Sales Order" or (dt in ("Sales Invoice", "Fees") and doc.outstanding_amount > 0)) \
		or (dt=="Purchase Invoice" and doc.outstanding_amount < 0):
			payment_type = "Receive"
	else:
		payment_type = "Pay"

	# amounts
	grand_total = outstanding_amount = 0
	if party_amount:
		grand_total = outstanding_amount = party_amount
	elif dt in ("Sales Invoice", "Purchase Invoice"):
		if party_account_currency == doc.company_currency:
			grand_total = doc.base_rounded_total or doc.base_grand_total
		else:
			grand_total = doc.rounded_total or doc.grand_total
		outstanding_amount = doc.outstanding_amount
	elif dt in ("Expense Claim"):
		grand_total = doc.total_sanctioned_amount
		outstanding_amount = doc.total_sanctioned_amount \
			- doc.total_amount_reimbursed - flt(doc.total_advance_amount)
	elif dt == "Employee Advance":
		grand_total = doc.advance_amount
		outstanding_amount = flt(doc.advance_amount) - flt(doc.paid_amount)
	elif dt == "Fees":
		grand_total = doc.grand_total
		outstanding_amount = doc.outstanding_amount
	else:
		if party_account_currency == doc.company_currency:
			grand_total = flt(doc.get("base_rounded_total") or doc.base_grand_total)
		else:
			grand_total = flt(doc.get("rounded_total") or doc.grand_total)
		outstanding_amount = grand_total - flt(doc.advance_paid)

	# bank or cash
	bank = get_default_bank_cash_account(doc.company, "Bank", mode_of_payment=doc.get("mode_of_payment"),
		account=bank_account)

	paid_amount = received_amount = 0
	if party_account_currency == bank.account_currency:
		paid_amount = received_amount = abs(outstanding_amount)
	elif payment_type == "Receive":
		paid_amount = abs(outstanding_amount)
		if bank_amount:
			received_amount = bank_amount
	else:
		received_amount = abs(outstanding_amount)
		if bank_amount:
			paid_amount = bank_amount

	pe = frappe.new_doc("Payment Entry")
	pe.payment_type = payment_type
	pe.company = doc.company
	pe.cost_center = doc.get("cost_center")
	pe.posting_date = nowdate()
	pe.mode_of_payment = doc.get("mode_of_payment")
	pe.party_type = party_type
	pe.party = doc.get(scrub(party_type))
	pe.contact_person = doc.get("contact_person")
	pe.contact_email = doc.get("contact_email")
	pe.ensure_supplier_is_not_blocked()

	pe.paid_from = party_account if payment_type=="Receive" else bank.account
	pe.paid_to = party_account if payment_type=="Pay" else bank.account
	pe.paid_from_account_currency = party_account_currency \
		if payment_type=="Receive" else bank.account_currency
	pe.paid_to_account_currency = party_account_currency if payment_type=="Pay" else bank.account_currency
	pe.paid_amount = paid_amount
	pe.received_amount = received_amount
	pe.allocate_payment_amount = 1
	pe.letter_head = doc.get("letter_head")

	if pe.party_type in ["Customer", "Supplier"]:
		bank_account = get_party_bank_account(pe.party_type, pe.party)
		pe.set("bank_account", bank_account)
		pe.set_bank_account_data()

	# only Purchase Invoice can be blocked individually
	if doc.doctype == "Purchase Invoice" and doc.invoice_is_blocked():
		frappe.msgprint(_('{0} is on hold till {1}'.format(doc.name, doc.release_date)))
	else:
		pe.append("references", {
			'reference_doctype': dt,
			'reference_name': dn,
			"bill_no": doc.get("bill_no"),
			"due_date": doc.get("due_date"),
			'total_amount': grand_total,
			'outstanding_amount': outstanding_amount,
			'allocated_amount': outstanding_amount
		})

	pe.setup_party_account_field()
	pe.set_missing_values()
	if party_account and bank:
		pe.set_exchange_rate()
		pe.set_amounts()
	return pe
def get_payment_entry(dt,
                      dn,
                      party_amount=None,
                      bank_account=None,
                      bank_amount=None):
    doc = frappe.get_doc(dt, dn)
    if flt(doc.per_billed, 2) > 0:
        frappe.throw(
            _("Can only make payment against unbilled {0}").format(dt))

    party_type = "Customer"

    # party account
    party_account = get_party_account(party_type, doc.get(party_type.lower()),
                                      doc.company)

    party_account_currency = doc.get(
        "party_account_currency") or get_account_currency(party_account)

    # payment type
    payment_type = "Receive"

    # amounts
    grand_total = outstanding_amount = 0
    if party_amount:
        grand_total = outstanding_amount = party_amount
    else:
        if party_account_currency == doc.company_currency:
            grand_total = flt(
                doc.get("base_rounded_total") or doc.base_grand_total)
        else:
            grand_total = flt(doc.get("rounded_total") or doc.grand_total)
        outstanding_amount = grand_total - flt(doc.advance_paid)

    # bank or cash
    bank = get_default_bank_cash_account(
        doc.company,
        "Bank",
        mode_of_payment=doc.get("mode_of_payment"),
        account=bank_account)

    if not bank:
        bank = get_default_bank_cash_account(
            doc.company,
            "Cash",
            mode_of_payment=doc.get("mode_of_payment"),
            account=bank_account)

    paid_amount = received_amount = 0
    if party_account_currency == bank.account_currency:
        paid_amount = received_amount = abs(outstanding_amount)
    elif payment_type == "Receive":
        paid_amount = abs(outstanding_amount)
        if bank_amount:
            received_amount = bank_amount
        else:
            received_amount = paid_amount * doc.get('conversion_rate', 1)
    else:
        received_amount = abs(outstanding_amount)
        if bank_amount:
            paid_amount = bank_amount
        else:
            # if party account currency and bank currency is different then populate paid amount as well
            paid_amount = received_amount * doc.get('conversion_rate', 1)

    pe = frappe.new_doc("Payment Entry")
    pe.payment_type = payment_type
    pe.company = doc.company
    pe.cost_center = doc.get("cost_center")
    pe.posting_date = nowdate()
    pe.mode_of_payment = doc.get("mode_of_payment")
    pe.party_type = party_type
    pe.party = doc.get(scrub(party_type))
    pe.contact_person = doc.get("contact_person")
    pe.contact_email = doc.get("contact_email")
    pe.ensure_supplier_is_not_blocked()

    pe.paid_from = party_account if payment_type == "Receive" else bank.account
    pe.paid_to = party_account if payment_type == "Pay" else bank.account
    pe.paid_from_account_currency = party_account_currency \
     if payment_type=="Receive" else bank.account_currency
    pe.paid_to_account_currency = party_account_currency if payment_type == "Pay" else bank.account_currency
    pe.paid_amount = paid_amount
    pe.received_amount = received_amount
    pe.letter_head = doc.get("letter_head")

    if pe.party_type in ["Customer", "Supplier"]:
        bank_account = get_party_bank_account(pe.party_type, pe.party)
        pe.set("bank_account", bank_account)
        pe.set_bank_account_data()

    # only Purchase Invoice can be blocked individually
    pe.append(
        "references", {
            'reference_doctype': dt,
            'reference_name': dn,
            "bill_no": doc.get("bill_no"),
            "due_date": doc.get("due_date"),
            'total_amount': grand_total,
            'outstanding_amount': outstanding_amount,
            'allocated_amount': outstanding_amount
        })

    pe.setup_party_account_field()
    pe.set_missing_values()
    if party_account and bank:
        pe.set_exchange_rate()
        pe.set_amounts()
    return pe