PR and PI gl entries fixes for landed cost
This commit is contained in:
parent
11594c7927
commit
f807cda375
@ -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
|
||||
|
@ -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],
|
||||
|
@ -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"
|
||||
}
|
||||
]
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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",
|
||||
|
@ -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"]
|
||||
|
Loading…
x
Reference in New Issue
Block a user