test: Internal tranfer precision loss test

This commit is contained in:
Deepesh Garg 2022-10-11 14:54:27 +05:30
parent b31c3bd35d
commit dc20b21fb5
4 changed files with 147 additions and 96 deletions

View File

@ -32,10 +32,20 @@ from erpnext.stock.doctype.stock_entry.test_stock_entry import (
get_qty_after_transaction,
make_stock_entry,
)
from erpnext.stock.utils import get_incoming_rate
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import (
create_stock_reconciliation,
)
from erpnext.stock.utils import get_incoming_rate, get_stock_balance
class TestSalesInvoice(unittest.TestCase):
def setUp(self):
from erpnext.stock.doctype.stock_ledger_entry.test_stock_ledger_entry import create_items
create_items(["_Test Internal Transfer Item"], uoms=[{"uom": "Box", "conversion_factor": 10}])
create_internal_parties()
setup_accounts()
def make(self):
w = frappe.copy_doc(test_records[0])
w.is_pos = 0
@ -1705,7 +1715,7 @@ class TestSalesInvoice(unittest.TestCase):
si.save()
self.assertEqual(si.get("items")[0].rate, flt((price_list_rate * 25) / 100 + price_list_rate))
def test_outstanding_amount_after_advance_jv_cancelation(self):
def test_outstanding_amount_after_advance_jv_cancellation(self):
from erpnext.accounts.doctype.journal_entry.test_journal_entry import (
test_records as jv_test_records,
)
@ -1749,7 +1759,7 @@ class TestSalesInvoice(unittest.TestCase):
flt(si.rounded_total + si.total_advance, si.precision("outstanding_amount")),
)
def test_outstanding_amount_after_advance_payment_entry_cancelation(self):
def test_outstanding_amount_after_advance_payment_entry_cancellation(self):
pe = frappe.get_doc(
{
"doctype": "Payment Entry",
@ -2367,29 +2377,6 @@ class TestSalesInvoice(unittest.TestCase):
acc_settings.save()
def test_inter_company_transaction(self):
from erpnext.selling.doctype.customer.test_customer import create_internal_customer
create_internal_customer(
customer_name="_Test Internal Customer",
represents_company="_Test Company 1",
allowed_to_interact_with="Wind Power LLC",
)
if not frappe.db.exists("Supplier", "_Test Internal Supplier"):
supplier = frappe.get_doc(
{
"supplier_group": "_Test Supplier Group",
"supplier_name": "_Test Internal Supplier",
"doctype": "Supplier",
"is_internal_supplier": 1,
"represents_company": "Wind Power LLC",
}
)
supplier.append("companies", {"company": "_Test Company 1"})
supplier.insert()
si = create_sales_invoice(
company="Wind Power LLC",
customer="_Test Internal Customer",
@ -2440,38 +2427,6 @@ class TestSalesInvoice(unittest.TestCase):
"Expenses Included In Valuation - _TC1",
)
if not frappe.db.exists("Customer", "_Test Internal Customer"):
customer = frappe.get_doc(
{
"customer_group": "_Test Customer Group",
"customer_name": "_Test Internal Customer",
"customer_type": "Individual",
"doctype": "Customer",
"territory": "_Test Territory",
"is_internal_customer": 1,
"represents_company": "_Test Company 1",
}
)
customer.append("companies", {"company": "Wind Power LLC"})
customer.insert()
if not frappe.db.exists("Supplier", "_Test Internal Supplier"):
supplier = frappe.get_doc(
{
"supplier_group": "_Test Supplier Group",
"supplier_name": "_Test Internal Supplier",
"doctype": "Supplier",
"is_internal_supplier": 1,
"represents_company": "Wind Power LLC",
}
)
supplier.append("companies", {"company": "_Test Company 1"})
supplier.insert()
# begin test
si = create_sales_invoice(
company="Wind Power LLC",
@ -2541,34 +2496,9 @@ class TestSalesInvoice(unittest.TestCase):
se.cancel()
def test_internal_transfer_gl_entry(self):
## Create internal transfer account
from erpnext.selling.doctype.customer.test_customer import create_internal_customer
account = create_account(
account_name="Unrealized Profit",
parent_account="Current Liabilities - TCP1",
company="_Test Company with perpetual inventory",
)
frappe.db.set_value(
"Company", "_Test Company with perpetual inventory", "unrealized_profit_loss_account", account
)
customer = create_internal_customer(
"_Test Internal Customer 2",
"_Test Company with perpetual inventory",
"_Test Company with perpetual inventory",
)
create_internal_supplier(
"_Test Internal Supplier 2",
"_Test Company with perpetual inventory",
"_Test Company with perpetual inventory",
)
si = create_sales_invoice(
company="_Test Company with perpetual inventory",
customer=customer,
customer="_Test Internal Customer 2",
debit_to="Debtors - TCP1",
warehouse="Stores - TCP1",
income_account="Sales - TCP1",
@ -2582,7 +2512,7 @@ class TestSalesInvoice(unittest.TestCase):
si.update_stock = 1
si.items[0].target_warehouse = "Work In Progress - TCP1"
# Add stock to stores for succesful stock transfer
# Add stock to stores for successful stock transfer
make_stock_entry(
target="Stores - TCP1", company="_Test Company with perpetual inventory", qty=1, basic_rate=100
)
@ -2638,6 +2568,77 @@ class TestSalesInvoice(unittest.TestCase):
check_gl_entries(self, target_doc.name, pi_gl_entries, add_days(nowdate(), -1))
def test_internal_transfer_gl_precision_issues(self):
# Make a stock queue of an item with two valuations
# Remove all existing stock for this
if get_stock_balance("_Test Internal Transfer Item", "Stores - TCP1", "2022-04-10"):
create_stock_reconciliation(
item_code="_Test Internal Transfer Item",
warehouse="Stores - TCP1",
qty=0,
rate=0,
company="_Test Company with perpetual inventory",
expense_account="Stock Adjustment - TCP1"
if frappe.get_all("Stock Ledger Entry")
else "Temporary Opening - TCP1",
posting_date="2020-04-10",
posting_time="14:00",
)
make_stock_entry(
item_code="_Test Internal Transfer Item",
target="Stores - TCP1",
qty=9000000,
basic_rate=52.0,
posting_date="2020-04-10",
posting_time="14:00",
)
make_stock_entry(
item_code="_Test Internal Transfer Item",
target="Stores - TCP1",
qty=60000000,
basic_rate=52.349777,
posting_date="2020-04-10",
posting_time="14:00",
)
# Make an internal transfer Sales Invoice Stock in non stock uom to check
# for rounding errors while converting to stock uom
si = create_sales_invoice(
company="_Test Company with perpetual inventory",
customer="_Test Internal Customer 2",
item_code="_Test Internal Transfer Item",
qty=5000000,
uom="Box",
debit_to="Debtors - TCP1",
warehouse="Stores - TCP1",
income_account="Sales - TCP1",
expense_account="Cost of Goods Sold - TCP1",
cost_center="Main - TCP1",
currency="INR",
do_not_save=1,
)
# Check GL Entries with precision
si.update_stock = 1
si.items[0].target_warehouse = "Work In Progress - TCP1"
si.items[0].conversion_factor = 10
si.save()
si.submit()
# Check if adjustment entry is created
self.assertTrue(
frappe.db.exists(
"GL Entry",
{
"voucher_type": "Sales Invoice",
"voucher_no": si.name,
"remarks": "Rounding gain/loss Entry for Stock Transfer",
},
)
)
def test_item_tax_net_range(self):
item = create_item("T Shirt")
@ -3077,7 +3078,7 @@ class TestSalesInvoice(unittest.TestCase):
[deferred_account, 2022.47, 0.0, "2019-03-15"],
]
gl_entries = gl_entries = frappe.db.sql(
gl_entries = frappe.db.sql(
"""select account, debit, credit, posting_date
from `tabGL Entry`
where voucher_type='Journal Entry' and voucher_detail_no=%s and posting_date <= %s
@ -3431,6 +3432,34 @@ def get_taxes_and_charges():
]
def create_internal_parties():
from erpnext.selling.doctype.customer.test_customer import create_internal_customer
create_internal_customer(
customer_name="_Test Internal Customer",
represents_company="_Test Company 1",
allowed_to_interact_with="Wind Power LLC",
)
create_internal_customer(
customer_name="_Test Internal Customer 2",
represents_company="_Test Company with perpetual inventory",
allowed_to_interact_with="_Test Company with perpetual inventory",
)
create_internal_supplier(
supplier_name="_Test Internal Supplier",
represents_company="Wind Power LLC",
allowed_to_interact_with="_Test Company 1",
)
create_internal_supplier(
supplier_name="_Test Internal Supplier 2",
represents_company="_Test Company with perpetual inventory",
allowed_to_interact_with="_Test Company with perpetual inventory",
)
def create_internal_supplier(supplier_name, represents_company, allowed_to_interact_with):
if not frappe.db.exists("Supplier", supplier_name):
supplier = frappe.get_doc(
@ -3453,6 +3482,19 @@ def create_internal_supplier(supplier_name, represents_company, allowed_to_inter
return supplier_name
def setup_accounts():
## Create internal transfer account
account = create_account(
account_name="Unrealized Profit",
parent_account="Current Liabilities - TCP1",
company="_Test Company with perpetual inventory",
)
frappe.db.set_value(
"Company", "_Test Company with perpetual inventory", "unrealized_profit_loss_account", account
)
def add_taxes(doc):
doc.append(
"taxes",

View File

@ -32,7 +32,7 @@ test_ignore = ["BOM"]
test_dependencies = ["Warehouse", "Item Group", "Item Tax Template", "Brand", "Item Attribute"]
def make_item(item_code=None, properties=None):
def make_item(item_code=None, properties=None, uoms=None):
if not item_code:
item_code = frappe.generate_hash(length=16)
@ -56,6 +56,11 @@ def make_item(item_code=None, properties=None):
for item_default in [doc for doc in item.get("item_defaults") if not doc.default_warehouse]:
item_default.default_warehouse = "_Test Warehouse - _TC"
item_default.company = "_Test Company"
if uoms:
for uom in uoms:
item.append("uoms", uom)
item.insert()
return item

View File

@ -1323,13 +1323,15 @@ def create_product_bundle_item(new_item_code, packed_items):
item.save()
def create_items():
items = [
"_Test Item for Reposting",
"_Test Finished Item for Reposting",
"_Test Subcontracted Item for Reposting",
"_Test Bundled Item for Reposting",
]
def create_items(items=None, uoms=None):
if not items:
items = [
"_Test Item for Reposting",
"_Test Finished Item for Reposting",
"_Test Subcontracted Item for Reposting",
"_Test Bundled Item for Reposting",
]
for d in items:
properties = {"valuation_method": "FIFO"}
if d == "_Test Bundled Item for Reposting":
@ -1337,7 +1339,7 @@ def create_items():
elif d == "_Test Subcontracted Item for Reposting":
properties.update({"is_sub_contracted_item": 1})
make_item(d, properties=properties)
make_item(d, properties=properties, uoms=uoms)
return items

View File

@ -132,7 +132,9 @@ class StockReconciliation(StockController):
key.append(row.get(field))
if key in item_warehouse_combinations:
self.validation_messages.append(_get_msg(row_num, _("Duplicate entry")))
self.validation_messages.append(
_get_msg(row_num, _("Same item and warehouse combination already entered."))
)
else:
item_warehouse_combinations.append(key)