PR and PI gl entries fixes for landed cost

This commit is contained in:
nabinhait 2014-07-24 17:42:52 +05:30 committed by Nabin Hait
parent 11594c7927
commit f807cda375
8 changed files with 93 additions and 49 deletions

View File

@ -273,6 +273,8 @@ class PurchaseInvoice(BuyingController):
def make_gl_entries(self):
auto_accounting_for_stock = \
cint(frappe.defaults.get_global_default("auto_accounting_for_stock"))
stock_received_but_not_billed = self.get_company_default("stock_received_but_not_billed")
gl_entries = []
@ -313,7 +315,7 @@ class PurchaseInvoice(BuyingController):
(tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.tax_amount)
# item gl entries
stock_item_and_auto_accounting_for_stock = False
negative_expense_to_be_booked = 0.0
stock_items = self.get_stock_items()
for item in self.get("entries"):
if flt(item.base_amount):
@ -327,54 +329,53 @@ class PurchaseInvoice(BuyingController):
})
)
if auto_accounting_for_stock and item.item_code in stock_items and item.valuation_rate:
# if auto inventory accounting enabled and stock item,
# then do stock related gl entries
# expense will be booked in sales invoice
stock_item_and_auto_accounting_for_stock = True
if auto_accounting_for_stock and item.item_code in stock_items and item.item_tax_amount:
# Post reverse entry for Stock-Received-But-Not-Billed if it is booked in Purchase Receipt
stock_rbnb_booked_in_pr = None
if item.purchase_receipt:
stock_rbnb_booked_in_pr = frappe.db.sql("""select name from `tabGL Entry`
where voucher_type='Purchase Receipt' and voucher_no=%s and account=%s""",
(item.purchase_receipt, stock_received_but_not_billed))
gl_entries.append(
self.get_gl_dict({
"account": item.expense_account,
"against": self.credit_to,
"debit": valuation_amt,
"remarks": self.remarks or "Accounting Entry for Stock"
})
)
if stock_rbnb_booked_in_pr:
gl_entries.append(
self.get_gl_dict({
"account": stock_received_but_not_billed,
"against": self.credit_to,
"debit": flt(item.item_tax_amount),
"remarks": self.remarks or "Accounting Entry for Stock"
})
)
negative_expense_to_be_booked += flt(item.item_tax_amount)
elif flt(item.base_amount):
# if not a stock item or auto inventory accounting disabled, book the expense
gl_entries.append(
self.get_gl_dict({
"account": item.expense_account,
"against": self.credit_to,
"debit": item.base_amount,
"remarks": self.remarks,
"cost_center": item.cost_center
})
)
if stock_item_and_auto_accounting_for_stock and valuation_tax:
if negative_expense_to_be_booked and valuation_tax:
# credit valuation tax amount in "Expenses Included In Valuation"
# this will balance out valuation amount included in cost of goods sold
expenses_included_in_valuation = \
self.get_company_default("expenses_included_in_valuation")
# Backward compatibility:
# Post expenses_included_in_valuation only if it is not booked in Purchase Receipt
expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
total_valuation_amount = sum(valuation_tax.values())
amount_including_divisional_loss = negative_expense_to_be_booked
i = 1
for cost_center, amount in valuation_tax.items():
if i == len(valuation_tax):
applicable_amount = amount_including_divisional_loss
else:
applicable_amount = negative_expense_to_be_booked * (amount / total_valuation_amount)
amount_including_divisional_loss -= applicable_amount
gl_entries.append(
self.get_gl_dict({
"account": expenses_included_in_valuation,
"cost_center": cost_center,
"against": self.credit_to,
"credit": amount,
"credit": applicable_amount,
"remarks": self.remarks or "Accounting Entry for Stock"
})
)
i += 1
# writeoff account includes petty difference in the invoice amount
# and the amount that is paid

View File

@ -9,7 +9,8 @@ import frappe.model
import json
from frappe.utils import cint
import frappe.defaults
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \
test_records as pr_test_records
test_dependencies = ["Item", "Cost Center"]
test_ignore = ["Serial No"]
@ -54,6 +55,38 @@ class TestPurchaseInvoice(unittest.TestCase):
order by account asc""", pi.name, as_dict=1)
self.assertTrue(gl_entries)
expected_values = sorted([
["_Test Supplier - _TC", 0, 720],
["Stock Received But Not Billed - _TC", 500.0, 0],
["_Test Account Shipping Charges - _TC", 100.0, 0],
["_Test Account VAT - _TC", 120.0, 0],
])
for i, gle in enumerate(gl_entries):
self.assertEquals(expected_values[i][0], gle.account)
self.assertEquals(expected_values[i][1], gle.debit)
self.assertEquals(expected_values[i][2], gle.credit)
set_perpetual_inventory(0)
def test_gl_entries_with_auto_accounting_for_stock_against_pr(self):
set_perpetual_inventory(1)
self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 1)
pr = frappe.copy_doc(pr_test_records[0])
pr.submit()
pi = frappe.copy_doc(test_records[1])
for d in pi.get("entries"):
d.purchase_receipt = pr.name
pi.insert()
pi.submit()
gl_entries = frappe.db.sql("""select account, debit, credit
from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
order by account asc""", pi.name, as_dict=1)
self.assertTrue(gl_entries)
expected_values = sorted([
["_Test Supplier - _TC", 0, 720],
["Stock Received But Not Billed - _TC", 750.0, 0],

View File

@ -138,6 +138,7 @@
}
],
"posting_date": "2013-02-03",
"supplier": "_Test Supplier",
"supplier_name": "_Test Supplier"
},
{
@ -201,6 +202,7 @@
}
],
"posting_date": "2013-02-03",
"supplier": "_Test Supplier",
"supplier_name": "_Test Supplier"
}
]

View File

@ -11,7 +11,6 @@ from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt \
class TestLandedCostVoucher(unittest.TestCase):
def test_landed_cost_voucher(self):
frappe.db.set_default("cost_center", "Main - _TC")
set_perpetual_inventory(1)
pr = self.submit_pr()
self.submit_landed_cost_voucher(pr)
@ -30,8 +29,8 @@ class TestLandedCostVoucher(unittest.TestCase):
expected_values = {
stock_in_hand_account: [400.0, 0.0],
fixed_asset_account: [400.0, 0.0],
"Stock Received But Not Billed - _TC": [0.0, 750.0],
"Expenses Included In Valuation - _TC": [0.0, 50.0]
"Stock Received But Not Billed - _TC": [0.0, 500.0],
"Expenses Included In Valuation - _TC": [0.0, 300.0]
}
for gle in gl_entries:

View File

@ -354,12 +354,12 @@ class PurchaseReceipt(BuyingController):
# and charges added via Landed Cost Voucher,
# post valuation related charges on "Stock Received But Not Billed"
pi_exists = frappe.db.sql("""select name from `tabPurchase Invoice Item` pi
stock_rbnb_booked_in_pi = frappe.db.sql("""select name from `tabPurchase Invoice Item` pi
where docstatus = 1 and purchase_receipt=%s
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, stock_rbnb))
if pi_exists:
if stock_rbnb_booked_in_pi:
expenses_included_in_valuation = stock_rbnb
# Expense included in valuation

View File

@ -55,7 +55,6 @@ class TestPurchaseReceipt(unittest.TestCase):
set_perpetual_inventory()
self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 1)
pr = frappe.copy_doc(test_records[0])
pr.insert()
pr.submit()
@ -72,7 +71,8 @@ class TestPurchaseReceipt(unittest.TestCase):
expected_values = {
stock_in_hand_account: [375.0, 0.0],
fixed_asset_account: [375.0, 0.0],
"Stock Received But Not Billed - _TC": [0.0, 750.0]
"Stock Received But Not Billed - _TC": [0.0, 500.0],
"Expenses Included In Valuation - _TC": [0.0, 250.0]
}
for gle in gl_entries:

View File

@ -19,7 +19,8 @@
"doctype": "Purchase Taxes and Charges",
"parentfield": "other_charges",
"rate": 100.0,
"tax_amount": 100.0
"tax_amount": 100.0,
"cost_center": "Main - _TC"
},
{
"account_head": "_Test Account VAT - _TC",
@ -30,7 +31,8 @@
"doctype": "Purchase Taxes and Charges",
"parentfield": "other_charges",
"rate": 120.0,
"tax_amount": 120.0
"tax_amount": 120.0,
"cost_center": "Main - _TC"
},
{
"account_head": "_Test Account Customs Duty - _TC",
@ -41,7 +43,8 @@
"doctype": "Purchase Taxes and Charges",
"parentfield": "other_charges",
"rate": 150.0,
"tax_amount": 150.0
"tax_amount": 150.0,
"cost_center": "Main - _TC"
}
],
"posting_date": "2013-02-12",
@ -61,7 +64,8 @@
"rejected_qty": 0.0,
"stock_uom": "Nos",
"uom": "_Test UOM",
"warehouse": "_Test Warehouse - _TC"
"warehouse": "_Test Warehouse - _TC",
"cost_center": "Main - _TC"
},
{
"base_amount": 250.0,
@ -77,7 +81,8 @@
"rejected_qty": 0.0,
"stock_uom": "Nos",
"uom": "_Test UOM",
"warehouse": "_Test Warehouse 1 - _TC"
"warehouse": "_Test Warehouse 1 - _TC",
"cost_center": "Main - _TC"
}
],
"supplier": "_Test Supplier"
@ -109,7 +114,8 @@
"rejected_qty": 0.0,
"stock_uom": "Nos",
"uom": "_Test UOM",
"warehouse": "_Test Warehouse - _TC"
"warehouse": "_Test Warehouse - _TC",
"cost_center": "Main - _TC"
}
],
"supplier": "_Test Supplier",

View File

@ -16,3 +16,6 @@ class TestAddress(unittest.TestCase):
address = frappe.get_list("Address")[0].name
display = get_address_display(frappe.get_doc("Address", address).as_dict())
self.assertTrue(display)
test_dependencies = ["Address Template"]