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):
|
def make_gl_entries(self):
|
||||||
auto_accounting_for_stock = \
|
auto_accounting_for_stock = \
|
||||||
cint(frappe.defaults.get_global_default("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 = []
|
gl_entries = []
|
||||||
|
|
||||||
@ -313,7 +315,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
(tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.tax_amount)
|
(tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.tax_amount)
|
||||||
|
|
||||||
# item gl entries
|
# item gl entries
|
||||||
stock_item_and_auto_accounting_for_stock = False
|
negative_expense_to_be_booked = 0.0
|
||||||
stock_items = self.get_stock_items()
|
stock_items = self.get_stock_items()
|
||||||
for item in self.get("entries"):
|
for item in self.get("entries"):
|
||||||
if flt(item.base_amount):
|
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_accounting_for_stock and item.item_code in stock_items and item.item_tax_amount:
|
||||||
# if auto inventory accounting enabled and stock item,
|
# Post reverse entry for Stock-Received-But-Not-Billed if it is booked in Purchase Receipt
|
||||||
# then do stock related gl entries
|
stock_rbnb_booked_in_pr = None
|
||||||
# expense will be booked in sales invoice
|
if item.purchase_receipt:
|
||||||
stock_item_and_auto_accounting_for_stock = True
|
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))
|
||||||
|
|
||||||
|
if stock_rbnb_booked_in_pr:
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": item.expense_account,
|
"account": stock_received_but_not_billed,
|
||||||
"against": self.credit_to,
|
"against": self.credit_to,
|
||||||
"debit": valuation_amt,
|
"debit": flt(item.item_tax_amount),
|
||||||
"remarks": self.remarks or "Accounting Entry for Stock"
|
"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"
|
# credit valuation tax amount in "Expenses Included In Valuation"
|
||||||
# this will balance out valuation amount included in cost of goods sold
|
# this will balance out valuation amount included in cost of goods sold
|
||||||
expenses_included_in_valuation = \
|
expenses_included_in_valuation = self.get_company_default("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
|
|
||||||
|
|
||||||
|
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():
|
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(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": expenses_included_in_valuation,
|
"account": expenses_included_in_valuation,
|
||||||
"cost_center": cost_center,
|
"cost_center": cost_center,
|
||||||
"against": self.credit_to,
|
"against": self.credit_to,
|
||||||
"credit": amount,
|
"credit": applicable_amount,
|
||||||
"remarks": self.remarks or "Accounting Entry for Stock"
|
"remarks": self.remarks or "Accounting Entry for Stock"
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
|
||||||
# writeoff account includes petty difference in the invoice amount
|
# writeoff account includes petty difference in the invoice amount
|
||||||
# and the amount that is paid
|
# and the amount that is paid
|
||||||
|
@ -9,7 +9,8 @@ import frappe.model
|
|||||||
import json
|
import json
|
||||||
from frappe.utils import cint
|
from frappe.utils import cint
|
||||||
import frappe.defaults
|
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_dependencies = ["Item", "Cost Center"]
|
||||||
test_ignore = ["Serial No"]
|
test_ignore = ["Serial No"]
|
||||||
@ -54,6 +55,38 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
order by account asc""", pi.name, as_dict=1)
|
order by account asc""", pi.name, as_dict=1)
|
||||||
self.assertTrue(gl_entries)
|
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([
|
expected_values = sorted([
|
||||||
["_Test Supplier - _TC", 0, 720],
|
["_Test Supplier - _TC", 0, 720],
|
||||||
["Stock Received But Not Billed - _TC", 750.0, 0],
|
["Stock Received But Not Billed - _TC", 750.0, 0],
|
||||||
|
@ -138,6 +138,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"posting_date": "2013-02-03",
|
"posting_date": "2013-02-03",
|
||||||
|
"supplier": "_Test Supplier",
|
||||||
"supplier_name": "_Test Supplier"
|
"supplier_name": "_Test Supplier"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -201,6 +202,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"posting_date": "2013-02-03",
|
"posting_date": "2013-02-03",
|
||||||
|
"supplier": "_Test Supplier",
|
||||||
"supplier_name": "_Test Supplier"
|
"supplier_name": "_Test Supplier"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -11,7 +11,6 @@ from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt \
|
|||||||
|
|
||||||
class TestLandedCostVoucher(unittest.TestCase):
|
class TestLandedCostVoucher(unittest.TestCase):
|
||||||
def test_landed_cost_voucher(self):
|
def test_landed_cost_voucher(self):
|
||||||
frappe.db.set_default("cost_center", "Main - _TC")
|
|
||||||
set_perpetual_inventory(1)
|
set_perpetual_inventory(1)
|
||||||
pr = self.submit_pr()
|
pr = self.submit_pr()
|
||||||
self.submit_landed_cost_voucher(pr)
|
self.submit_landed_cost_voucher(pr)
|
||||||
@ -30,8 +29,8 @@ class TestLandedCostVoucher(unittest.TestCase):
|
|||||||
expected_values = {
|
expected_values = {
|
||||||
stock_in_hand_account: [400.0, 0.0],
|
stock_in_hand_account: [400.0, 0.0],
|
||||||
fixed_asset_account: [400.0, 0.0],
|
fixed_asset_account: [400.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, 50.0]
|
"Expenses Included In Valuation - _TC": [0.0, 300.0]
|
||||||
}
|
}
|
||||||
|
|
||||||
for gle in gl_entries:
|
for gle in gl_entries:
|
||||||
|
@ -354,12 +354,12 @@ class PurchaseReceipt(BuyingController):
|
|||||||
# 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"
|
||||||
|
|
||||||
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
|
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, stock_rbnb))
|
||||||
|
|
||||||
if pi_exists:
|
if stock_rbnb_booked_in_pi:
|
||||||
expenses_included_in_valuation = stock_rbnb
|
expenses_included_in_valuation = stock_rbnb
|
||||||
|
|
||||||
# Expense included in valuation
|
# Expense included in valuation
|
||||||
|
@ -55,7 +55,6 @@ class TestPurchaseReceipt(unittest.TestCase):
|
|||||||
|
|
||||||
set_perpetual_inventory()
|
set_perpetual_inventory()
|
||||||
self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 1)
|
self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 1)
|
||||||
|
|
||||||
pr = frappe.copy_doc(test_records[0])
|
pr = frappe.copy_doc(test_records[0])
|
||||||
pr.insert()
|
pr.insert()
|
||||||
pr.submit()
|
pr.submit()
|
||||||
@ -72,7 +71,8 @@ class TestPurchaseReceipt(unittest.TestCase):
|
|||||||
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 - _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:
|
for gle in gl_entries:
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
"doctype": "Purchase Taxes and Charges",
|
"doctype": "Purchase Taxes and Charges",
|
||||||
"parentfield": "other_charges",
|
"parentfield": "other_charges",
|
||||||
"rate": 100.0,
|
"rate": 100.0,
|
||||||
"tax_amount": 100.0
|
"tax_amount": 100.0,
|
||||||
|
"cost_center": "Main - _TC"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"account_head": "_Test Account VAT - _TC",
|
"account_head": "_Test Account VAT - _TC",
|
||||||
@ -30,7 +31,8 @@
|
|||||||
"doctype": "Purchase Taxes and Charges",
|
"doctype": "Purchase Taxes and Charges",
|
||||||
"parentfield": "other_charges",
|
"parentfield": "other_charges",
|
||||||
"rate": 120.0,
|
"rate": 120.0,
|
||||||
"tax_amount": 120.0
|
"tax_amount": 120.0,
|
||||||
|
"cost_center": "Main - _TC"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"account_head": "_Test Account Customs Duty - _TC",
|
"account_head": "_Test Account Customs Duty - _TC",
|
||||||
@ -41,7 +43,8 @@
|
|||||||
"doctype": "Purchase Taxes and Charges",
|
"doctype": "Purchase Taxes and Charges",
|
||||||
"parentfield": "other_charges",
|
"parentfield": "other_charges",
|
||||||
"rate": 150.0,
|
"rate": 150.0,
|
||||||
"tax_amount": 150.0
|
"tax_amount": 150.0,
|
||||||
|
"cost_center": "Main - _TC"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"posting_date": "2013-02-12",
|
"posting_date": "2013-02-12",
|
||||||
@ -61,7 +64,8 @@
|
|||||||
"rejected_qty": 0.0,
|
"rejected_qty": 0.0,
|
||||||
"stock_uom": "Nos",
|
"stock_uom": "Nos",
|
||||||
"uom": "_Test UOM",
|
"uom": "_Test UOM",
|
||||||
"warehouse": "_Test Warehouse - _TC"
|
"warehouse": "_Test Warehouse - _TC",
|
||||||
|
"cost_center": "Main - _TC"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"base_amount": 250.0,
|
"base_amount": 250.0,
|
||||||
@ -77,7 +81,8 @@
|
|||||||
"rejected_qty": 0.0,
|
"rejected_qty": 0.0,
|
||||||
"stock_uom": "Nos",
|
"stock_uom": "Nos",
|
||||||
"uom": "_Test UOM",
|
"uom": "_Test UOM",
|
||||||
"warehouse": "_Test Warehouse 1 - _TC"
|
"warehouse": "_Test Warehouse 1 - _TC",
|
||||||
|
"cost_center": "Main - _TC"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"supplier": "_Test Supplier"
|
"supplier": "_Test Supplier"
|
||||||
@ -109,7 +114,8 @@
|
|||||||
"rejected_qty": 0.0,
|
"rejected_qty": 0.0,
|
||||||
"stock_uom": "Nos",
|
"stock_uom": "Nos",
|
||||||
"uom": "_Test UOM",
|
"uom": "_Test UOM",
|
||||||
"warehouse": "_Test Warehouse - _TC"
|
"warehouse": "_Test Warehouse - _TC",
|
||||||
|
"cost_center": "Main - _TC"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"supplier": "_Test Supplier",
|
"supplier": "_Test Supplier",
|
||||||
|
@ -16,3 +16,6 @@ class TestAddress(unittest.TestCase):
|
|||||||
address = frappe.get_list("Address")[0].name
|
address = frappe.get_list("Address")[0].name
|
||||||
display = get_address_display(frappe.get_doc("Address", address).as_dict())
|
display = get_address_display(frappe.get_doc("Address", address).as_dict())
|
||||||
self.assertTrue(display)
|
self.assertTrue(display)
|
||||||
|
|
||||||
|
|
||||||
|
test_dependencies = ["Address Template"]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user