From ce7a53f810fae8fe10d81ab416845daaaa9d8089 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 21 Feb 2024 17:32:02 +0530 Subject: [PATCH] chore: remove microsecond from posting_datetime (cherry picked from commit a73ba2c0d26b9d27bb5a75bc6c9739e49035f266) # Conflicts: # erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py --- .../doctype/stock_entry/test_stock_entry.py | 10 +- .../test_stock_ledger_entry.py | 4 +- erpnext/stock/stock_ledger.py | 9 +- erpnext/stock/utils.py | 2 +- .../test_subcontracting_receipt.py | 253 ++++++++++++++++++ 5 files changed, 261 insertions(+), 17 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index 1d7e4da26d5..771dae53864 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -1671,24 +1671,22 @@ class TestStockEntry(FrappeTestCase): item_code = "Test Negative Item - 001" item_doc = create_item(item_code=item_code, is_stock_item=1, valuation_rate=10) - make_stock_entry( + se1 = make_stock_entry( item_code=item_code, posting_date=add_days(today(), -3), posting_time="00:00:00", - purpose="Material Receipt", + target="_Test Warehouse - _TC", qty=10, to_warehouse="_Test Warehouse - _TC", - do_not_save=True, ) - make_stock_entry( + se2 = make_stock_entry( item_code=item_code, posting_date=today(), posting_time="00:00:00", - purpose="Material Receipt", + source="_Test Warehouse - _TC", qty=8, from_warehouse="_Test Warehouse - _TC", - do_not_save=True, ) sr_doc = create_stock_reconciliation( diff --git a/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py index 570e280a934..6154910c2f1 100644 --- a/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py +++ b/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py @@ -1216,7 +1216,7 @@ class TestStockLedgerEntry(FrappeTestCase, StockTestMixin): filters={"voucher_no": reciept1.name}, fields=["qty_after_transaction", "actual_qty"], ) - self.assertEqual(sle[0].qty_after_transaction, 105) + self.assertEqual(sle[0].qty_after_transaction, 5) self.assertEqual(sle[0].actual_qty, 5) sle = frappe.get_all( @@ -1224,7 +1224,7 @@ class TestStockLedgerEntry(FrappeTestCase, StockTestMixin): filters={"voucher_no": reciept2.name}, fields=["qty_after_transaction", "actual_qty"], ) - self.assertEqual(sle[0].qty_after_transaction, 100) + self.assertEqual(sle[0].qty_after_transaction, 105) self.assertEqual(sle[0].actual_qty, 100) @change_settings("System Settings", {"float_precision": 3, "currency_precision": 2}) diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index ee06dcecd52..28ed449c451 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -13,7 +13,6 @@ from frappe.utils import cint, cstr, flt, get_link_to_form, getdate, now, nowdat ======= from frappe.query_builder.functions import Sum from frappe.utils import ( - add_to_date, cint, cstr, flt, @@ -470,7 +469,7 @@ class update_entries_after(object): posting_datetime = %(posting_datetime)s ) order by - posting_datetime ASC, creation ASC + creation ASC for update """, self.args, @@ -1208,17 +1207,12 @@ class update_entries_after(object): def get_previous_sle_of_current_voucher(args, operator="<", exclude_current_voucher=False): """get stock ledger entries filtered by specific posting datetime conditions""" - args["time_format"] = "%H:%i:%s" if not args.get("posting_date"): args["posting_datetime"] = "1900-01-01 00:00:00" if not args.get("posting_datetime"): args["posting_datetime"] = get_combine_datetime(args["posting_date"], args["posting_time"]) - if operator == "<=": - # Add 1 second to handle millisecond for less than and equal to condition - args["posting_datetime"] = add_to_date(args["posting_datetime"], seconds=1) - voucher_condition = "" if exclude_current_voucher: voucher_no = args.get("voucher_no") @@ -1508,7 +1502,6 @@ def update_qty_in_future_sle(args, allow_negative_stock=False): datetime_limit_condition = "" qty_shift = args.actual_qty - args["time_format"] = "%H:%i:%s" args["posting_datetime"] = get_combine_datetime(args["posting_date"], args["posting_time"]) # find difference/shift in qty caused by stock reconciliation diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py index c6ee01d3df1..0c3e15ac487 100644 --- a/erpnext/stock/utils.py +++ b/erpnext/stock/utils.py @@ -633,4 +633,4 @@ def get_combine_datetime(posting_date, posting_time): if isinstance(posting_time, datetime.timedelta): posting_time = (datetime.datetime.min + posting_time).time() - return datetime.datetime.combine(posting_date, posting_time) + return datetime.datetime.combine(posting_date, posting_time).replace(microsecond=0) diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py index b05ed755c7f..0862970c119 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py @@ -594,6 +594,259 @@ class TestSubcontractingReceipt(FrappeTestCase): self.assertNotEqual(scr.supplied_items[0].rate, prev_cost) self.assertEqual(scr.supplied_items[0].rate, sr.items[0].valuation_rate) +<<<<<<< HEAD +======= + def test_subcontracting_receipt_for_batch_raw_materials_without_material_transfer(self): + set_backflush_based_on("BOM") + + fg_item = make_item(properties={"is_stock_item": 1, "is_sub_contracted_item": 1}).name + rm_item1 = make_item( + properties={ + "is_stock_item": 1, + "has_batch_no": 1, + "create_new_batch": 1, + "batch_number_series": "BNGS-.####", + } + ).name + + bom = make_bom(item=fg_item, raw_materials=[rm_item1]) + + rm_batch_no = None + for row in bom.items: + se = make_stock_entry( + item_code=row.item_code, + qty=1, + target="_Test Warehouse 1 - _TC", + rate=300, + ) + + se.reload() + rm_batch_no = get_batch_from_bundle(se.items[0].serial_and_batch_bundle) + + service_items = [ + { + "warehouse": "_Test Warehouse - _TC", + "item_code": "Subcontracted Service Item 1", + "qty": 1, + "rate": 100, + "fg_item": fg_item, + "fg_item_qty": 1, + }, + ] + sco = get_subcontracting_order(service_items=service_items) + scr = make_subcontracting_receipt(sco.name) + scr.save() + scr.reload() + + bundle_doc = make_serial_batch_bundle( + { + "item_code": scr.supplied_items[0].rm_item_code, + "warehouse": "_Test Warehouse 1 - _TC", + "voucher_type": "Subcontracting Receipt", + "posting_date": today(), + "posting_time": nowtime(), + "qty": -1, + "batches": frappe._dict({rm_batch_no: 1}), + "type_of_transaction": "Outward", + "do_not_submit": True, + } + ) + + scr.supplied_items[0].serial_and_batch_bundle = bundle_doc.name + scr.submit() + scr.reload() + + batch_no = get_batch_from_bundle(scr.supplied_items[0].serial_and_batch_bundle) + self.assertEqual(batch_no, rm_batch_no) + self.assertEqual(scr.items[0].rm_cost_per_qty, 300) + self.assertEqual(scr.items[0].service_cost_per_qty, 100) + + def test_subcontracting_receipt_valuation_with_auto_created_serial_batch_bundle(self): + set_backflush_based_on("BOM") + + fg_item = make_item(properties={"is_stock_item": 1, "is_sub_contracted_item": 1}).name + rm_item1 = make_item( + properties={ + "is_stock_item": 1, + "has_batch_no": 1, + "create_new_batch": 1, + "batch_number_series": "BNGS-.####", + } + ).name + + rm_item2 = make_item( + properties={ + "is_stock_item": 1, + "has_batch_no": 1, + "has_serial_no": 1, + "create_new_batch": 1, + "batch_number_series": "BNGS-.####", + "serial_no_series": "BNSS-.####", + } + ).name + + rm_item3 = make_item( + properties={ + "is_stock_item": 1, + "has_serial_no": 1, + "serial_no_series": "BSSSS-.####", + } + ).name + + bom = make_bom(item=fg_item, raw_materials=[rm_item1, rm_item2, rm_item3]) + + rm_batch_no = None + for row in bom.items: + make_stock_entry( + item_code=row.item_code, + qty=1, + target="_Test Warehouse 1 - _TC", + rate=300, + ) + + make_stock_entry( + item_code=row.item_code, + qty=1, + target="_Test Warehouse 1 - _TC", + rate=400, + ) + + service_items = [ + { + "warehouse": "_Test Warehouse - _TC", + "item_code": "Subcontracted Service Item 1", + "qty": 1, + "rate": 100, + "fg_item": fg_item, + "fg_item_qty": 1, + }, + ] + sco = get_subcontracting_order(service_items=service_items) + + frappe.db.set_single_value( + "Stock Settings", "auto_create_serial_and_batch_bundle_for_outward", 1 + ) + scr = make_subcontracting_receipt(sco.name) + scr.save() + scr.submit() + scr.reload() + + for row in scr.supplied_items: + self.assertEqual(row.rate, 300.00) + self.assertTrue(row.serial_and_batch_bundle) + auto_created_serial_batch = frappe.db.get_value( + "Stock Ledger Entry", + {"voucher_no": scr.name, "voucher_detail_no": row.name}, + "auto_created_serial_and_batch_bundle", + ) + + self.assertTrue(auto_created_serial_batch) + + self.assertEqual(scr.items[0].rm_cost_per_qty, 900) + self.assertEqual(scr.items[0].service_cost_per_qty, 100) + frappe.db.set_single_value( + "Stock Settings", "auto_create_serial_and_batch_bundle_for_outward", 0 + ) + + def test_subcontracting_receipt_valuation_for_fg_with_auto_created_serial_batch_bundle(self): + set_backflush_based_on("BOM") + + fg_item = make_item( + properties={ + "is_stock_item": 1, + "is_sub_contracted_item": 1, + "has_batch_no": 1, + "create_new_batch": 1, + "batch_number_series": "BSSNGS-.####", + } + ).name + + rm_item1 = make_item( + properties={ + "is_stock_item": 1, + "has_batch_no": 1, + "create_new_batch": 1, + "batch_number_series": "BNGS-.####", + } + ).name + + rm_item2 = make_item( + properties={ + "is_stock_item": 1, + "has_batch_no": 1, + "has_serial_no": 1, + "create_new_batch": 1, + "batch_number_series": "BNGS-.####", + "serial_no_series": "BNSS-.####", + } + ).name + + rm_item3 = make_item( + properties={ + "is_stock_item": 1, + "has_serial_no": 1, + "serial_no_series": "BSSSS-.####", + } + ).name + + bom = make_bom(item=fg_item, raw_materials=[rm_item1, rm_item2, rm_item3]) + + rm_batch_no = None + for row in bom.items: + make_stock_entry( + item_code=row.item_code, + qty=1, + target="_Test Warehouse 1 - _TC", + rate=300, + ) + + service_items = [ + { + "warehouse": "_Test Warehouse - _TC", + "item_code": "Subcontracted Service Item 1", + "qty": 1, + "rate": 100, + "fg_item": fg_item, + "fg_item_qty": 1, + }, + ] + sco = get_subcontracting_order(service_items=service_items) + + frappe.db.set_single_value( + "Stock Settings", "auto_create_serial_and_batch_bundle_for_outward", 1 + ) + scr = make_subcontracting_receipt(sco.name) + scr.save() + scr.submit() + scr.reload() + + for row in scr.supplied_items: + self.assertEqual(row.rate, 300.00) + self.assertTrue(row.serial_and_batch_bundle) + auto_created_serial_batch = frappe.db.get_value( + "Stock Ledger Entry", + {"voucher_no": scr.name, "voucher_detail_no": row.name}, + "auto_created_serial_and_batch_bundle", + ) + + self.assertTrue(auto_created_serial_batch) + + self.assertEqual(scr.items[0].rm_cost_per_qty, 900) + self.assertEqual(scr.items[0].service_cost_per_qty, 100) + self.assertEqual(scr.items[0].rate, 1000) + valuation_rate = frappe.db.get_value( + "Stock Ledger Entry", + {"voucher_no": scr.name, "voucher_detail_no": scr.items[0].name}, + "valuation_rate", + ) + + self.assertEqual(flt(valuation_rate), flt(1000)) + + frappe.db.set_single_value( + "Stock Settings", "auto_create_serial_and_batch_bundle_for_outward", 0 + ) + +>>>>>>> a73ba2c0d2 (chore: remove microsecond from posting_datetime) def test_subcontracting_receipt_raw_material_rate(self): from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom