Payment Entry: Test cases and default remarks
This commit is contained in:
parent
13093b4b68
commit
9db1b223da
@ -12,6 +12,7 @@ def _make_test_records(verbose):
|
||||
["_Test Bank", "Bank Accounts", 0, "Bank", None],
|
||||
["_Test Bank USD", "Bank Accounts", 0, "Bank", "USD"],
|
||||
["_Test Bank EUR", "Bank Accounts", 0, "Bank", "EUR"],
|
||||
["_Test Cash", "Cash In Hand", 0, "Cash", None],
|
||||
|
||||
["_Test Account Stock Expenses", "Direct Expenses", 1, None, None],
|
||||
["_Test Account Shipping Charges", "_Test Account Stock Expenses", 0, "Chargeable", None],
|
||||
@ -32,6 +33,7 @@ def _make_test_records(verbose):
|
||||
["_Test Account CST", "Direct Expenses", 0, "Tax", None],
|
||||
["_Test Account Discount", "Direct Expenses", 0, None, None],
|
||||
["_Test Write Off", "Indirect Expenses", 0, None, None],
|
||||
["_Test Exchange Gain/Loss", "Indirect Expenses", 0, None, None],
|
||||
|
||||
# related to Account Inventory Integration
|
||||
["_Test Account Stock In Hand", "Current Assets", 0, None, None],
|
||||
|
@ -38,7 +38,7 @@ class GLEntry(Document):
|
||||
self.against_voucher)
|
||||
|
||||
def check_mandatory(self):
|
||||
mandatory = ['account','remarks','voucher_type','voucher_no','company']
|
||||
mandatory = ['account','voucher_type','voucher_no','company']
|
||||
for k in mandatory:
|
||||
if not self.get(k):
|
||||
frappe.throw(_("{0} is required").format(_(self.meta.get_label(k))))
|
||||
|
@ -44,7 +44,7 @@ class PaymentEntry(AccountsController):
|
||||
self.clear_unallocated_reference_document_rows()
|
||||
self.set_title()
|
||||
self.validate_transaction_reference()
|
||||
|
||||
self.set_remarks()
|
||||
|
||||
def on_submit(self):
|
||||
self.make_gl_entries()
|
||||
@ -137,7 +137,7 @@ class PaymentEntry(AccountsController):
|
||||
frappe.throw(_("Account Type for {0} must be {1}").format(comma_or(account_types)))
|
||||
|
||||
def set_exchange_rate(self):
|
||||
if self.paid_from:
|
||||
if self.paid_from and not self.source_exchange_rate:
|
||||
if self.paid_from_account_currency == self.company_currency:
|
||||
self.source_exchange_rate = 1
|
||||
elif self.payment_type in ("Pay", "Internal Transfer"):
|
||||
@ -146,7 +146,7 @@ class PaymentEntry(AccountsController):
|
||||
self.source_exchange_rate = get_exchange_rate(self.paid_from_account_currency,
|
||||
self.company_currency)
|
||||
|
||||
if self.paid_to:
|
||||
if self.paid_to and not self.target_exchange_rate:
|
||||
self.target_exchange_rate = get_exchange_rate(self.paid_to_account_currency,
|
||||
self.company_currency)
|
||||
|
||||
@ -204,7 +204,6 @@ class PaymentEntry(AccountsController):
|
||||
self.total_allocated_amount, self.base_total_allocated_amount = 0, 0
|
||||
for d in self.get("references"):
|
||||
if d.allocated_amount:
|
||||
print d.allocated_amount, d.outstanding_amount
|
||||
if d.reference_doctype not in ("Sales Order", "Purchase Order") \
|
||||
and d.allocated_amount > d.outstanding_amount:
|
||||
frappe.throw(_("Row #{0}: Allocated amount cannot be greater than outstanding amount")
|
||||
@ -226,7 +225,7 @@ class PaymentEntry(AccountsController):
|
||||
base_unallocated_amount = self.unallocated_amount * \
|
||||
(self.source_exchange_rate if self.payment_type=="Receive" else self.target_exchange_rate)
|
||||
|
||||
base_party_amount = self.base_total_allocated_amount + base_unallocated_amount
|
||||
base_party_amount = flt(self.base_total_allocated_amount) + flt(base_unallocated_amount)
|
||||
|
||||
if self.payment_type == "Receive":
|
||||
self.difference_amount = base_party_amount - self.base_received_amount
|
||||
@ -259,6 +258,37 @@ class PaymentEntry(AccountsController):
|
||||
if not self.reference_no or not self.reference_date:
|
||||
frappe.throw(_("Reference No and Reference Date is mandatory for Bank transaction"))
|
||||
|
||||
def set_remarks(self):
|
||||
if self.remarks: return
|
||||
|
||||
if self.payment_type=="Internal Transfer":
|
||||
remarks = [_("Amount {0} {1} transferred from {2} to {3}")
|
||||
.format(self.paid_from_account_currency, self.paid_amount, self.paid_from, self.paid_to)]
|
||||
else:
|
||||
|
||||
remarks = [_("Amount {0} {1} {2} {3}").format(
|
||||
self.party_account_currency,
|
||||
self.paid_amount if self.payment_type=="Receive" else self.received_amount,
|
||||
_("received from") if self.payment_type=="Receive" else _("to"), self.party
|
||||
)]
|
||||
|
||||
if self.reference_no:
|
||||
remarks.append(_("Transaction reference no {0} dated {1}")
|
||||
.format(self.reference_no, self.reference_date))
|
||||
|
||||
if self.payment_type in ["Receive", "Pay"]:
|
||||
for d in self.get("references"):
|
||||
if d.allocated_amount:
|
||||
remarks.append(_("Amount {0} {1} against {2} {3}").format(self.party_account_currency,
|
||||
d.allocated_amount, d.reference_doctype, d.reference_name))
|
||||
|
||||
for d in self.get("deductions"):
|
||||
if d.amount:
|
||||
remarks.append(_("Amount {0} {1} deducted against {2}")
|
||||
.format(self.company_currency, d.amount, d.account))
|
||||
|
||||
self.set("remarks", "\n".join(remarks))
|
||||
|
||||
def make_gl_entries(self, cancel=0, adv_adj=0):
|
||||
gl_entries = []
|
||||
self.add_party_gl_entries(gl_entries)
|
||||
@ -520,7 +550,7 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
||||
received_amount = outstanding_amount
|
||||
if bank_amount:
|
||||
paid_amount = bank_amount
|
||||
|
||||
|
||||
pe = frappe.new_doc("Payment Entry")
|
||||
pe.payment_type = payment_type
|
||||
pe.company = doc.company
|
||||
|
@ -5,50 +5,163 @@ from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
from erpnext.accounts.doctype.sales_order.test_sales_order import make_sales_order
|
||||
from erpnext.accounts.doctype.payment_entry.payment_entry import make_payment_entry
|
||||
from frappe.utils import flt, nowdate
|
||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
||||
|
||||
test_dependencies = ["Item"]
|
||||
|
||||
class TestPaymentEntry(unittest.TestCase):
|
||||
def test_payment_entry_against_order(self):
|
||||
so = make_sales_order()
|
||||
pe = make_payment_entry("Sales Order", so.name)
|
||||
pe.paid_to = "_Test Bank - _TC"
|
||||
pe = get_payment_entry("Sales Order", so.name, bank_account="_Test Cash - _TC")
|
||||
pe.paid_from = "Debtors - _TC"
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
||||
expected_gle = {
|
||||
"_Test Bank - _TC": {
|
||||
"account_currency": "INR",
|
||||
"debit": 1000,
|
||||
"debit_in_account_currency": 1000,
|
||||
"credit": 0,
|
||||
"credit_in_account_currency": 0,
|
||||
"against_voucher": None
|
||||
},
|
||||
"_Test Receivable - _TC": {
|
||||
"account_currency": "INR",
|
||||
"debit": 0,
|
||||
"debit_in_account_currency": 0,
|
||||
"credit": 1000,
|
||||
"credit_in_account_currency": 1000,
|
||||
"against_voucher": so.name
|
||||
}
|
||||
}
|
||||
expected_gle = dict((d[0], d) for d in [
|
||||
["Debtors - _TC", 0, 1000, so.name],
|
||||
["_Test Cash - _TC", 1000.0, 0, None]
|
||||
])
|
||||
|
||||
self.validate_gl_entries(pe.name, expected_gle)
|
||||
|
||||
so_advance_paid = frappe.db.get_value("Sales Order", so.name, "advance_paid")
|
||||
self.assertEqual(so_advance_paid, 1000)
|
||||
|
||||
pe.cancel()
|
||||
|
||||
self.assertFalse(self.get_gle(pe.name))
|
||||
|
||||
so_advance_paid = frappe.db.get_value("Sales Order", so.name, "advance_paid")
|
||||
self.assertEqual(so_advance_paid, 0)
|
||||
|
||||
def test_payment_entry_against_si_usd_to_usd(self):
|
||||
si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
||||
currency="USD", conversion_rate=50)
|
||||
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC")
|
||||
pe.reference_no = "1"
|
||||
pe.reference_date = "2016-01-01"
|
||||
pe.target_exchange_rate = 50
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
||||
expected_gle = dict((d[0], d) for d in [
|
||||
["_Test Receivable USD - _TC", 0, 5000, si.name],
|
||||
["_Test Bank USD - _TC", 5000.0, 0, None]
|
||||
])
|
||||
|
||||
self.validate_gl_entries(pe.name, expected_gle)
|
||||
|
||||
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
|
||||
self.assertEqual(outstanding_amount, 0)
|
||||
|
||||
pe.cancel()
|
||||
self.assertFalse(self.get_gle(pe.name))
|
||||
|
||||
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
|
||||
self.assertEqual(outstanding_amount, 100)
|
||||
|
||||
def test_payment_entry_against_pi(self):
|
||||
pi = make_purchase_invoice(supplier="_Test Supplier USD", debit_to="_Test Payable USD - _TC",
|
||||
currency="USD", conversion_rate=50)
|
||||
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank USD - _TC")
|
||||
pe.reference_no = "1"
|
||||
pe.reference_date = "2016-01-01"
|
||||
pe.target_exchange_rate = 50
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
||||
expected_gle = dict((d[0], d) for d in [
|
||||
["_Test Payable USD - _TC", 12500, 0, pi.name],
|
||||
["_Test Bank USD - _TC", 0, 12500, None]
|
||||
])
|
||||
|
||||
self.validate_gl_entries(pe.name, expected_gle)
|
||||
|
||||
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", pi.name, "outstanding_amount"))
|
||||
self.assertEqual(outstanding_amount, 0)
|
||||
|
||||
def test_payment_entry_against_si_usd_to_inr(self):
|
||||
si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
||||
currency="USD", conversion_rate=50)
|
||||
pe = get_payment_entry("Sales Invoice", si.name, party_amount=20,
|
||||
bank_account="_Test Bank - _TC", bank_amount=900)
|
||||
pe.reference_no = "1"
|
||||
pe.reference_date = "2016-01-01"
|
||||
|
||||
self.assertEqual(pe.difference_amount, 100)
|
||||
|
||||
pe.append("deductions", {
|
||||
"account": "_Test Exchange Gain/Loss - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"amount": 100
|
||||
})
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
||||
expected_gle = dict((d[0], d) for d in [
|
||||
["_Test Receivable USD - _TC", 0, 1000, si.name],
|
||||
["_Test Bank - _TC", 900, 0, None],
|
||||
["_Test Exchange Gain/Loss - _TC", 100.0, 0, None],
|
||||
])
|
||||
|
||||
self.validate_gl_entries(pe.name, expected_gle)
|
||||
|
||||
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
|
||||
self.assertEqual(outstanding_amount, 80)
|
||||
|
||||
def test_internal_transfer_usd_to_inr(self):
|
||||
pe = frappe.new_doc("Payment Entry")
|
||||
pe.payment_type = "Internal Transfer"
|
||||
pe.company = "_Test Company"
|
||||
pe.paid_from = "_Test Bank USD - _TC"
|
||||
pe.paid_to = "_Test Bank - _TC"
|
||||
pe.paid_amount = 100
|
||||
pe.source_exchange_rate = 50
|
||||
pe.received_amount = 4500
|
||||
pe.reference_no = "2"
|
||||
pe.reference_date = nowdate()
|
||||
|
||||
pe.setup_party_account_field()
|
||||
pe.set_missing_values()
|
||||
pe.set_exchange_rate()
|
||||
pe.set_amounts()
|
||||
|
||||
self.assertEquals(pe.difference_amount, 500)
|
||||
|
||||
pe.append("deductions", {
|
||||
"account": "_Test Exchange Gain/Loss - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"amount": 500
|
||||
})
|
||||
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
||||
expected_gle = dict((d[0], d) for d in [
|
||||
["_Test Bank USD - _TC", 0, 5000, None],
|
||||
["_Test Bank - _TC", 4500, 0, None],
|
||||
["_Test Exchange Gain/Loss - _TC", 500.0, 0, None],
|
||||
])
|
||||
|
||||
self.validate_gl_entries(pe.name, expected_gle)
|
||||
|
||||
so.load_from_db()
|
||||
|
||||
def validate_gl_entries(self, voucher_no, expected_gle):
|
||||
gl_entries = frappe.db.sql("""select account, account_currency, debit, credit,
|
||||
debit_in_account_currency, credit_in_account_currency, against_voucher
|
||||
gl_entries = self.get_gle(voucher_no)
|
||||
|
||||
self.assertTrue(gl_entries)
|
||||
|
||||
for i, gle in enumerate(gl_entries):
|
||||
self.assertEquals(expected_gle[gle.account][0], gle.account)
|
||||
self.assertEquals(expected_gle[gle.account][1], gle.debit)
|
||||
self.assertEquals(expected_gle[gle.account][2], gle.credit)
|
||||
self.assertEquals(expected_gle[gle.account][3], gle.against_voucher)
|
||||
|
||||
def get_gle(self, voucher_no):
|
||||
return frappe.db.sql("""select account, debit, credit, against_voucher
|
||||
from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
|
||||
order by account asc""", voucher_no, as_dict=1)
|
||||
|
||||
self.assertTrue(gl_entries)
|
||||
|
||||
for field in ("account_currency", "debit", "debit_in_account_currency",
|
||||
"credit", "credit_in_account_currency"):
|
||||
for i, gle in enumerate(gl_entries):
|
||||
self.assertEquals(expected_gle[gle.account][field], gle[field])
|
||||
|
||||
|
@ -462,7 +462,7 @@ class AccountsController(TransactionBase):
|
||||
formatted_order_total = fmt_money(order_total, precision=self.precision("base_grand_total"),
|
||||
currency=advance.account_currency)
|
||||
|
||||
if self.currency == self.company_currency:
|
||||
if self.currency == self.company_currency and advance_paid > order_total:
|
||||
frappe.throw(_("Total advance ({0}) against Order {1} cannot be greater than the Grand Total ({2})")
|
||||
.format(formatted_advance_paid, self.name, formatted_order_total))
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user