Payment Entry: Test cases and default remarks

This commit is contained in:
Nabin Hait 2016-06-30 12:37:53 +05:30
parent 13093b4b68
commit 9db1b223da
5 changed files with 186 additions and 41 deletions

View File

@ -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],

View File

@ -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))))

View File

@ -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

View File

@ -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])

View File

@ -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))