fix: Book valuation expense in specified account rather than expense included in valuation account (#19590)

* fix: Book valuation expense in specified accout rather than expense included in valuation account

* fix: Remove undefined variable

* fix: Test cases

* fix: Test Case
This commit is contained in:
Deepesh Garg 2019-11-18 12:34:30 +05:30 committed by Nabin Hait
parent d995609ffa
commit 87c6718d90
5 changed files with 88 additions and 58 deletions

View File

@ -714,14 +714,14 @@ class PurchaseInvoice(BuyingController):
if account_currency==self.company_currency \ if account_currency==self.company_currency \
else tax.tax_amount_after_discount_amount, else tax.tax_amount_after_discount_amount,
"cost_center": tax.cost_center "cost_center": tax.cost_center
}, account_currency) }, account_currency, item=tax)
) )
# accumulate valuation tax # accumulate valuation tax
if self.is_opening == "No" and tax.category in ("Valuation", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount): if self.is_opening == "No" and tax.category in ("Valuation", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount):
if self.auto_accounting_for_stock and not tax.cost_center: if self.auto_accounting_for_stock and not tax.cost_center:
frappe.throw(_("Cost Center is required in row {0} in Taxes table for type {1}").format(tax.idx, _(tax.category))) frappe.throw(_("Cost Center is required in row {0} in Taxes table for type {1}").format(tax.idx, _(tax.category)))
valuation_tax.setdefault(tax.cost_center, 0) valuation_tax.setdefault(tax.name, 0)
valuation_tax[tax.cost_center] += \ valuation_tax[tax.name] += \
(tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.base_tax_amount_after_discount_amount) (tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.base_tax_amount_after_discount_amount)
if self.is_opening == "No" and self.negative_expense_to_be_booked and valuation_tax: if self.is_opening == "No" and self.negative_expense_to_be_booked and valuation_tax:
@ -731,35 +731,37 @@ class PurchaseInvoice(BuyingController):
total_valuation_amount = sum(valuation_tax.values()) total_valuation_amount = sum(valuation_tax.values())
amount_including_divisional_loss = self.negative_expense_to_be_booked amount_including_divisional_loss = self.negative_expense_to_be_booked
i = 1 i = 1
for cost_center, amount in iteritems(valuation_tax): for tax in self.get("taxes"):
if valuation_tax.get(tax.name):
if i == len(valuation_tax): if i == len(valuation_tax):
applicable_amount = amount_including_divisional_loss applicable_amount = amount_including_divisional_loss
else: else:
applicable_amount = self.negative_expense_to_be_booked * (amount / total_valuation_amount) applicable_amount = self.negative_expense_to_be_booked * (valuation_tax[tax.name] / total_valuation_amount)
amount_including_divisional_loss -= applicable_amount amount_including_divisional_loss -= applicable_amount
gl_entries.append( gl_entries.append(
self.get_gl_dict({ self.get_gl_dict({
"account": self.expenses_included_in_valuation, "account": tax.account_head,
"cost_center": cost_center, "cost_center": tax.cost_center,
"against": self.supplier, "against": self.supplier,
"credit": applicable_amount, "credit": applicable_amount,
"remarks": self.remarks or "Accounting Entry for Stock" "remarks": self.remarks or _("Accounting Entry for Stock"),
}) }, item=tax)
) )
i += 1 i += 1
if self.auto_accounting_for_stock and self.update_stock and valuation_tax: if self.auto_accounting_for_stock and self.update_stock and valuation_tax:
for cost_center, amount in iteritems(valuation_tax): for tax in self.get("taxes"):
if valuation_tax.get(tax.name):
gl_entries.append( gl_entries.append(
self.get_gl_dict({ self.get_gl_dict({
"account": self.expenses_included_in_valuation, "account": tax.account_head,
"cost_center": cost_center, "cost_center": tax.cost_center,
"against": self.supplier, "against": self.supplier,
"credit": amount, "credit": valuation_tax[tax.name],
"remarks": self.remarks or "Accounting Entry for Stock" "remarks": self.remarks or "Accounting Entry for Stock"
}) }, item=tax)
) )
def make_payment_gl_entries(self, gl_entries): def make_payment_gl_entries(self, gl_entries):

View File

@ -204,19 +204,40 @@ class TestPurchaseInvoice(unittest.TestCase):
pi.insert() pi.insert()
pi.submit() pi.submit()
self.check_gle_for_pi(pi.name) self.check_gle_for_pi_against_pr(pi.name)
def check_gle_for_pi(self, pi): def check_gle_for_pi(self, pi):
gl_entries = frappe.db.sql("""select account, debit, credit gl_entries = frappe.db.sql("""select account, sum(debit) as debit, sum(credit) as credit
from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
order by account asc""", pi, as_dict=1) group by account""", pi, as_dict=1)
self.assertTrue(gl_entries) self.assertTrue(gl_entries)
expected_values = dict((d[0], d) for d in [ expected_values = dict((d[0], d) for d in [
["Creditors - TCP1", 0, 720], ["Creditors - TCP1", 0, 720],
["Stock Received But Not Billed - TCP1", 500.0, 0], ["Stock Received But Not Billed - TCP1", 500.0, 0],
["_Test Account Shipping Charges - TCP1", 100.0, 0], ["_Test Account Shipping Charges - TCP1", 100.0, 0.0],
["_Test Account VAT - TCP1", 120.0, 0]
])
for i, gle in enumerate(gl_entries):
self.assertEqual(expected_values[gle.account][0], gle.account)
self.assertEqual(expected_values[gle.account][1], gle.debit)
self.assertEqual(expected_values[gle.account][2], gle.credit)
def check_gle_for_pi_against_pr(self, pi):
gl_entries = frappe.db.sql("""select account, sum(debit) as debit, sum(credit) as credit
from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
group by account""", pi, as_dict=1)
self.assertTrue(gl_entries)
expected_values = dict((d[0], d) for d in [
["Creditors - TCP1", 0, 720],
["Stock Received But Not Billed - TCP1", 750.0, 0],
["_Test Account Shipping Charges - TCP1", 100.0, 100.0],
["_Test Account VAT - TCP1", 120.0, 0], ["_Test Account VAT - TCP1", 120.0, 0],
["_Test Account Customs Duty - TCP1", 0, 150]
]) ])
for i, gle in enumerate(gl_entries): for i, gle in enumerate(gl_entries):

View File

@ -54,9 +54,10 @@ class TestLandedCostVoucher(unittest.TestCase):
expected_values = { expected_values = {
stock_in_hand_account: [800.0, 0.0], stock_in_hand_account: [800.0, 0.0],
"Stock Received But Not Billed - TCP1": [0.0, 500.0], "Stock Received But Not Billed - TCP1": [0.0, 500.0],
"Expenses Included In Valuation - TCP1": [0.0, 300.0] "Expenses Included In Valuation - TCP1": [0.0, 50.0],
"_Test Account Customs Duty - TCP1": [0.0, 150],
"_Test Account Shipping Charges - TCP1": [0.0, 100.00]
} }
else: else:
expected_values = { expected_values = {
stock_in_hand_account: [400.0, 0.0], stock_in_hand_account: [400.0, 0.0],

View File

@ -288,8 +288,8 @@ class PurchaseReceipt(BuyingController):
if tax.category in ("Valuation", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount): if tax.category in ("Valuation", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount):
if not tax.cost_center: if not tax.cost_center:
frappe.throw(_("Cost Center is required in row {0} in Taxes table for type {1}").format(tax.idx, _(tax.category))) frappe.throw(_("Cost Center is required in row {0} in Taxes table for type {1}").format(tax.idx, _(tax.category)))
valuation_tax.setdefault(tax.cost_center, 0) valuation_tax.setdefault(tax.name, 0)
valuation_tax[tax.cost_center] += \ valuation_tax[tax.name] += \
(tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.base_tax_amount_after_discount_amount) (tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.base_tax_amount_after_discount_amount)
if negative_expense_to_be_booked and valuation_tax: if negative_expense_to_be_booked and valuation_tax:
@ -297,34 +297,39 @@ class PurchaseReceipt(BuyingController):
# If expenses_included_in_valuation account has been credited in against PI # If expenses_included_in_valuation account has been credited in against PI
# and charges added via Landed Cost Voucher, # and charges added via Landed Cost Voucher,
# post valuation related charges on "Stock Received But Not Billed" # post valuation related charges on "Stock Received But Not Billed"
# introduced in 2014 for backward compatibility of expenses already booked in expenses_included_in_valuation account
negative_expense_booked_in_pi = frappe.db.sql("""select name from `tabPurchase Invoice Item` pi negative_expense_booked_in_pi = frappe.db.sql("""select name from `tabPurchase Invoice Item` pi
where docstatus = 1 and purchase_receipt=%s where docstatus = 1 and purchase_receipt=%s
and exists(select name from `tabGL Entry` where voucher_type='Purchase Invoice' and exists(select name from `tabGL Entry` where voucher_type='Purchase Invoice'
and voucher_no=pi.parent and account=%s)""", (self.name, expenses_included_in_valuation)) and voucher_no=pi.parent and account=%s)""", (self.name, expenses_included_in_valuation))
if negative_expense_booked_in_pi:
expenses_included_in_valuation = stock_rbnb
against_account = ", ".join([d.account for d in gl_entries if flt(d.debit) > 0]) against_account = ", ".join([d.account for d in gl_entries if flt(d.debit) > 0])
total_valuation_amount = sum(valuation_tax.values()) total_valuation_amount = sum(valuation_tax.values())
amount_including_divisional_loss = negative_expense_to_be_booked amount_including_divisional_loss = negative_expense_to_be_booked
i = 1 i = 1
for cost_center, amount in iteritems(valuation_tax): for tax in self.get("taxes"):
if valuation_tax.get(tax.name):
if negative_expense_booked_in_pi:
account = stock_rbnb
else:
account = tax.account_head
if i == len(valuation_tax): if i == len(valuation_tax):
applicable_amount = amount_including_divisional_loss applicable_amount = amount_including_divisional_loss
else: else:
applicable_amount = negative_expense_to_be_booked * (amount / total_valuation_amount) applicable_amount = negative_expense_to_be_booked * (valuation_tax[tax.name] / total_valuation_amount)
amount_including_divisional_loss -= applicable_amount amount_including_divisional_loss -= applicable_amount
gl_entries.append( gl_entries.append(
self.get_gl_dict({ self.get_gl_dict({
"account": expenses_included_in_valuation, "account": account,
"cost_center": cost_center, "cost_center": tax.cost_center,
"credit": applicable_amount, "credit": applicable_amount,
"remarks": self.remarks or _("Accounting Entry for Stock"), "remarks": self.remarks or _("Accounting Entry for Stock"),
"against": against_account "against": against_account
}) }, item=tax)
) )
i += 1 i += 1

View File

@ -66,14 +66,15 @@ class TestPurchaseReceipt(unittest.TestCase):
expected_values = { expected_values = {
stock_in_hand_account: [750.0, 0.0], stock_in_hand_account: [750.0, 0.0],
"Stock Received But Not Billed - TCP1": [0.0, 500.0], "Stock Received But Not Billed - TCP1": [0.0, 500.0],
"Expenses Included In Valuation - TCP1": [0.0, 250.0] "_Test Account Shipping Charges - TCP1": [0.0, 100.0],
"_Test Account Customs Duty - TCP1": [0.0, 150.0]
} }
else: else:
expected_values = { expected_values = {
stock_in_hand_account: [375.0, 0.0], stock_in_hand_account: [375.0, 0.0],
fixed_asset_account: [375.0, 0.0], fixed_asset_account: [375.0, 0.0],
"Stock Received But Not Billed - TCP1": [0.0, 500.0], "Stock Received But Not Billed - TCP1": [0.0, 500.0],
"Expenses Included In Valuation - TCP1": [0.0, 250.0] "_Test Account Shipping Charges - TCP1": [0.0, 250.0]
} }
for gle in gl_entries: for gle in gl_entries:
self.assertEqual(expected_values[gle.account][0], gle.debit) self.assertEqual(expected_values[gle.account][0], gle.debit)