From fa28e600b5c32066cb12ae6c4641abd5218341a9 Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Tue, 28 Jul 2020 08:49:21 +0530 Subject: [PATCH] fix: Unable to submit backdated stock transactions for different items (#22822) * fix: Unable to submit backdated stock transactions for different items * fix: Test cases * fix: Test Cases * fix: Test Cases * fix: Test for stock account JV * fix: Journal Entry Test * fix: Delete unwanted code --- .../doctype/coupon_code/test_coupon_code.py | 27 ++++++------ .../journal_entry/test_journal_entry.py | 42 +++++++++++++++---- erpnext/accounts/general_ledger.py | 5 ++- erpnext/stock/doctype/item/item.py | 4 +- .../doctype/stock_entry/test_stock_entry.py | 26 +++++++++--- 5 files changed, 75 insertions(+), 29 deletions(-) diff --git a/erpnext/accounts/doctype/coupon_code/test_coupon_code.py b/erpnext/accounts/doctype/coupon_code/test_coupon_code.py index 990b896fde..3a0d4162ae 100644 --- a/erpnext/accounts/doctype/coupon_code/test_coupon_code.py +++ b/erpnext/accounts/doctype/coupon_code/test_coupon_code.py @@ -26,22 +26,22 @@ def test_create_test_data(): "item_group": "_Test Item Group", "item_name": "_Test Tesla Car", "apply_warehouse_wise_reorder_level": 0, - "warehouse":"_Test Warehouse - _TC", + "warehouse":"Stores - TCP1", "gst_hsn_code": "999800", "valuation_rate": 5000, "standard_rate":5000, "item_defaults": [{ - "company": "_Test Company", - "default_warehouse": "_Test Warehouse - _TC", + "company": "_Test Company with perpetual inventory", + "default_warehouse": "Stores - TCP1", "default_price_list":"_Test Price List", - "expense_account": "_Test Account Cost for Goods Sold - _TC", - "buying_cost_center": "_Test Cost Center - _TC", - "selling_cost_center": "_Test Cost Center - _TC", - "income_account": "Sales - _TC" + "expense_account": "Cost of Goods Sold - TCP1", + "buying_cost_center": "Main - TCP1", + "selling_cost_center": "Main - TCP1", + "income_account": "Sales - TCP1" }], "show_in_website": 1, "route":"-test-tesla-car", - "website_warehouse": "_Test Warehouse - _TC" + "website_warehouse": "Stores - TCP1" }) item.insert() # create test item price @@ -63,12 +63,12 @@ def test_create_test_data(): "items": [{ "item_code": "_Test Tesla Car" }], - "warehouse":"_Test Warehouse - _TC", + "warehouse":"Stores - TCP1", "coupon_code_based":1, "selling": 1, "rate_or_discount": "Discount Percentage", "discount_percentage": 30, - "company": "_Test Company", + "company": "_Test Company with perpetual inventory", "currency":"INR", "for_price_list":"_Test Price List" }) @@ -112,7 +112,10 @@ class TestCouponCode(unittest.TestCase): self.assertEqual(coupon_code.get("used"),0) def test_2_sales_order_with_coupon_code(self): - so = make_sales_order(customer="_Test Customer",selling_price_list="_Test Price List",item_code="_Test Tesla Car", rate=5000,qty=1, do_not_submit=True) + so = make_sales_order(company='_Test Company with perpetual inventory', warehouse='Stores - TCP1', + customer="_Test Customer", selling_price_list="_Test Price List", item_code="_Test Tesla Car", rate=5000,qty=1, + do_not_submit=True) + so = frappe.get_doc('Sales Order', so.name) # check item price before coupon code is applied self.assertEqual(so.items[0].rate, 5000) @@ -120,7 +123,7 @@ class TestCouponCode(unittest.TestCase): so.sales_partner='_Test Coupon Partner' so.save() # check item price after coupon code is applied - self.assertEqual(so.items[0].rate, 3500) + self.assertEqual(so.items[0].rate, 3500) so.submit() def test_3_check_coupon_code_used_after_so(self): diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py index 23ad1eef14..479d4b64bb 100644 --- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py @@ -6,6 +6,7 @@ import unittest, frappe from frappe.utils import flt, nowdate from erpnext.accounts.doctype.account.test_account import get_inventory_account from erpnext.exceptions import InvalidAccountCurrency +from erpnext.accounts.general_ledger import StockAccountInvalidTransaction class TestJournalEntry(unittest.TestCase): def test_journal_entry_with_against_jv(self): @@ -81,19 +82,46 @@ class TestJournalEntry(unittest.TestCase): from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory set_perpetual_inventory() - jv = frappe.copy_doc(test_records[0]) + jv = frappe.copy_doc({ + "cheque_date": nowdate(), + "cheque_no": "33", + "company": "_Test Company with perpetual inventory", + "doctype": "Journal Entry", + "accounts": [ + { + "account": "Debtors - TCP1", + "party_type": "Customer", + "party": "_Test Customer", + "credit_in_account_currency": 400.0, + "debit_in_account_currency": 0.0, + "doctype": "Journal Entry Account", + "parentfield": "accounts", + "cost_center": "Main - TCP1" + }, + { + "account": "_Test Bank - TCP1", + "credit_in_account_currency": 0.0, + "debit_in_account_currency": 400.0, + "doctype": "Journal Entry Account", + "parentfield": "accounts", + "cost_center": "Main - TCP1" + } + ], + "naming_series": "_T-Journal Entry-", + "posting_date": nowdate(), + "user_remark": "test", + "voucher_type": "Bank Entry" + }) + jv.get("accounts")[0].update({ - "account": get_inventory_account('_Test Company'), - "company": "_Test Company", + "account": get_inventory_account('_Test Company with perpetual inventory'), + "company": "_Test Company with perpetual inventory", "party_type": None, "party": None }) - jv.insert() - - from erpnext.accounts.general_ledger import StockAccountInvalidTransaction self.assertRaises(StockAccountInvalidTransaction, jv.submit) - + jv.cancel() set_perpetual_inventory(0) def test_multi_currency(self): diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index a245d63f52..cf3deb828f 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -158,8 +158,10 @@ def validate_account_for_perpetual_inventory(gl_map): if account not in aii_accounts: continue + # Always use current date to get stock and account balance as there can future entries for + # other items account_bal, stock_bal, warehouse_list = get_stock_and_account_balance(account, - gl_map[0].posting_date, gl_map[0].company) + getdate(), gl_map[0].company) if gl_map[0].voucher_type=="Journal Entry": # In case of Journal Entry, there are no corresponding SL entries, @@ -169,7 +171,6 @@ def validate_account_for_perpetual_inventory(gl_map): frappe.throw(_("Account: {0} can only be updated via Stock Transactions") .format(account), StockAccountInvalidTransaction) - # This has been comment for a temporary, will add this code again on release of immutable ledger elif account_bal != stock_bal: precision = get_field_precision(frappe.get_meta("GL Entry").get_field("debit"), currency=frappe.get_cached_value('Company', gl_map[0].company, "default_currency")) diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index d5f479ff82..991ec4743d 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -13,7 +13,7 @@ from erpnext.controllers.item_variant import (ItemVariantExistsError, from erpnext.setup.doctype.item_group.item_group import (get_parent_item_groups, invalidate_cache_for) from frappe import _, msgprint from frappe.utils import (cint, cstr, flt, formatdate, get_timestamp, getdate, - now_datetime, random_string, strip, get_link_to_form) + now_datetime, random_string, strip, get_link_to_form, nowtime) from frappe.utils.html_utils import clean_html from frappe.website.doctype.website_slideshow.website_slideshow import \ get_slideshow @@ -194,7 +194,7 @@ class Item(WebsiteGenerator): if default_warehouse: stock_entry = make_stock_entry(item_code=self.name, target=default_warehouse, qty=self.opening_stock, - rate=self.valuation_rate, company=default.company) + rate=self.valuation_rate, company=default.company, posting_date=getdate(), posting_time=nowtime()) stock_entry.add_comment("Comment", _("Opening Stock")) diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index 0fbc63101e..8e25804511 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -413,7 +413,7 @@ class TestStockEntry(unittest.TestCase): def test_serial_item_error(self): se, serial_nos = self.test_serial_by_series() if not frappe.db.exists('Serial No', 'ABCD'): - make_serialized_item("_Test Serialized Item", "ABCD\nEFGH") + make_serialized_item(item_code="_Test Serialized Item", serial_no="ABCD\nEFGH") se = frappe.copy_doc(test_records[0]) se.purpose = "Material Transfer" @@ -823,15 +823,29 @@ class TestStockEntry(unittest.TestCase): ]) ) -def make_serialized_item(item_code=None, serial_no=None, target_warehouse=None): +def make_serialized_item(**args): + args = frappe._dict(args) se = frappe.copy_doc(test_records[0]) - se.get("items")[0].item_code = item_code or "_Test Serialized Item With Series" - se.get("items")[0].serial_no = serial_no + + if args.company: + se.company = args.company + + se.get("items")[0].item_code = args.item_code or "_Test Serialized Item With Series" + + if args.serial_no: + se.get("items")[0].serial_no = args.serial_no + + if args.cost_center: + se.get("items")[0].cost_center = args.cost_center + + if args.expense_account: + se.get("items")[0].expense_account = args.expense_account + se.get("items")[0].qty = 2 se.get("items")[0].transfer_qty = 2 - if target_warehouse: - se.get("items")[0].t_warehouse = target_warehouse + if args.target_warehouse: + se.get("items")[0].t_warehouse = args.target_warehouse se.set_stock_entry_type() se.insert()