fix: Unable to submit backdated stock transactions for different items (#22648)
* 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
This commit is contained in:
parent
3c136ebf92
commit
9119b4c538
@ -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):
|
||||
|
@ -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):
|
||||
|
@ -23,13 +23,13 @@ class TestPOSInvoice(unittest.TestCase):
|
||||
import time
|
||||
time.sleep(1)
|
||||
self.assertRaises(frappe.TimestampMismatchError, w2.save)
|
||||
|
||||
|
||||
def test_change_naming_series(self):
|
||||
inv = create_pos_invoice(do_not_submit=1)
|
||||
inv.naming_series = 'TEST-'
|
||||
|
||||
self.assertRaises(frappe.CannotChangeConstantError, inv.save)
|
||||
|
||||
|
||||
def test_discount_and_inclusive_tax(self):
|
||||
inv = create_pos_invoice(qty=100, rate=50, do_not_save=1)
|
||||
inv.append("taxes", {
|
||||
@ -66,7 +66,7 @@ class TestPOSInvoice(unittest.TestCase):
|
||||
|
||||
self.assertEqual(inv.net_total, 4298.25)
|
||||
self.assertEqual(inv.grand_total, 4900.00)
|
||||
|
||||
|
||||
def test_tax_calculation_with_multiple_items(self):
|
||||
inv = create_pos_invoice(qty=84, rate=4.6, do_not_save=True)
|
||||
item_row = inv.get("items")[0]
|
||||
@ -148,7 +148,7 @@ class TestPOSInvoice(unittest.TestCase):
|
||||
self.assertEqual(inv.grand_total, 5675.57)
|
||||
self.assertEqual(inv.rounding_adjustment, 0.43)
|
||||
self.assertEqual(inv.rounded_total, 5676.0)
|
||||
|
||||
|
||||
def test_tax_calculation_with_multiple_items_and_discount(self):
|
||||
inv = create_pos_invoice(qty=1, rate=75, do_not_save=True)
|
||||
item_row = inv.get("items")[0]
|
||||
@ -194,7 +194,7 @@ class TestPOSInvoice(unittest.TestCase):
|
||||
|
||||
self.assertEqual(pos_return.get('payments')[0].amount, -500)
|
||||
self.assertEqual(pos_return.get('payments')[1].amount, -500)
|
||||
|
||||
|
||||
def test_pos_change_amount(self):
|
||||
pos = create_pos_invoice(company= "_Test Company", debit_to="Debtors - _TC",
|
||||
income_account = "Sales - _TC", expense_account = "Cost of Goods Sold - _TC", rate=105,
|
||||
@ -208,33 +208,43 @@ class TestPOSInvoice(unittest.TestCase):
|
||||
|
||||
self.assertEqual(pos.grand_total, 105.0)
|
||||
self.assertEqual(pos.change_amount, 5.0)
|
||||
|
||||
|
||||
def test_without_payment(self):
|
||||
inv = create_pos_invoice(do_not_save=1)
|
||||
# Check that the invoice cannot be submitted without payments
|
||||
inv.payments = []
|
||||
self.assertRaises(frappe.ValidationError, inv.insert)
|
||||
|
||||
|
||||
def test_serialized_item_transaction(self):
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
|
||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||
|
||||
se = make_serialized_item(target_warehouse="_Test Warehouse - _TC")
|
||||
se = make_serialized_item(company='_Test Company with perpetual inventory',
|
||||
target_warehouse="Stores - TCP1", cost_center='Main - TCP1', expense_account='Cost of Goods Sold - TCP1')
|
||||
|
||||
serial_nos = get_serial_nos(se.get("items")[0].serial_no)
|
||||
|
||||
pos = create_pos_invoice(item=se.get("items")[0].item_code, rate=1000, do_not_save=1)
|
||||
pos = create_pos_invoice(company='_Test Company with perpetual inventory', debit_to='Debtors - TCP1',
|
||||
account_for_change_amount='Cash - TCP1', warehouse='Stores - TCP1', income_account='Sales - TCP1',
|
||||
expense_account='Cost of Goods Sold - TCP1', cost_center='Main - TCP1',
|
||||
item=se.get("items")[0].item_code, rate=1000, do_not_save=1)
|
||||
|
||||
pos.get("items")[0].serial_no = serial_nos[0]
|
||||
pos.append("payments", {'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - _TC', 'amount': 1000})
|
||||
pos.append("payments", {'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - TCP1', 'amount': 1000})
|
||||
|
||||
pos.insert()
|
||||
pos.submit()
|
||||
|
||||
pos2 = create_pos_invoice(item=se.get("items")[0].item_code, rate=1000, do_not_save=1)
|
||||
pos2 = create_pos_invoice(company='_Test Company with perpetual inventory', debit_to='Debtors - TCP1',
|
||||
account_for_change_amount='Cash - TCP1', warehouse='Stores - TCP1', income_account='Sales - TCP1',
|
||||
expense_account='Cost of Goods Sold - TCP1', cost_center='Main - TCP1',
|
||||
item=se.get("items")[0].item_code, rate=1000, do_not_save=1)
|
||||
|
||||
pos2.get("items")[0].serial_no = serial_nos[0]
|
||||
pos2.append("payments", {'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - _TC', 'amount': 1000})
|
||||
|
||||
pos2.append("payments", {'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - TCP1', 'amount': 1000})
|
||||
|
||||
self.assertRaises(frappe.ValidationError, pos2.insert)
|
||||
|
||||
|
||||
def test_loyalty_points(self):
|
||||
from erpnext.accounts.doctype.loyalty_program.test_loyalty_program import create_records
|
||||
from erpnext.accounts.doctype.loyalty_program.loyalty_program import get_loyalty_program_details_with_points
|
||||
@ -255,14 +265,14 @@ class TestPOSInvoice(unittest.TestCase):
|
||||
inv.cancel()
|
||||
after_cancel_lp_details = get_loyalty_program_details_with_points(inv.customer, company=inv.company, loyalty_program=inv.loyalty_program)
|
||||
self.assertEqual(after_cancel_lp_details.loyalty_points, before_lp_details.loyalty_points)
|
||||
|
||||
|
||||
def test_loyalty_points_redeemption(self):
|
||||
from erpnext.accounts.doctype.loyalty_program.loyalty_program import get_loyalty_program_details_with_points
|
||||
# add 10 loyalty points
|
||||
create_pos_invoice(customer="Test Loyalty Customer", rate=10000)
|
||||
|
||||
before_lp_details = get_loyalty_program_details_with_points("Test Loyalty Customer", company="_Test Company", loyalty_program="Test Single Loyalty")
|
||||
|
||||
|
||||
inv = create_pos_invoice(customer="Test Loyalty Customer", rate=10000, do_not_save=1)
|
||||
inv.redeem_loyalty_points = 1
|
||||
inv.loyalty_points = before_lp_details.loyalty_points
|
||||
@ -299,7 +309,7 @@ def create_pos_invoice(**args):
|
||||
pos_inv.return_against = args.return_against
|
||||
pos_inv.currency=args.currency or "INR"
|
||||
pos_inv.conversion_rate = args.conversion_rate or 1
|
||||
pos_inv.account_for_change_amount = "Cash - _TC"
|
||||
pos_inv.account_for_change_amount = args.account_for_change_amount or "Cash - _TC"
|
||||
|
||||
pos_inv.append("items", {
|
||||
"item_code": args.item or args.item_code or "_Test Item",
|
||||
|
@ -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"))
|
||||
|
@ -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"))
|
||||
|
||||
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user