diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 73e8286f2d894d41b6fe7b78258ab85b8a5d1a55..63a6bd8a8cabc34b8e504dde3b7256359e356a08 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -1758,6 +1758,9 @@ def make_bundle_for_material_transfer(**kwargs): bundle_doc.calculate_qty_and_amount() bundle_doc.flags.ignore_permissions = True bundle_doc.flags.ignore_validate = True - bundle_doc.save(ignore_permissions=True) + if kwargs.do_not_submit: + bundle_doc.save(ignore_permissions=True) + else: + bundle_doc.submit() return bundle_doc.name diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py index 1afbb034ab139ea459e0e4de5e55f98e605b8e8a..bb1ebd1be75eee9a70bb172c702f7bc0cc355648 100644 --- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py +++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py @@ -90,12 +90,10 @@ class SerialandBatchBundle(Document): self.validate_duplicate_serial_and_batch_no() self.validate_voucher_no() - if self.docstatus == 0: - self.allow_existing_serial_nos() - if self.type_of_transaction == "Maintenance": return + self.allow_existing_serial_nos() if not self.flags.ignore_validate_serial_batch or frappe.flags.in_test: self.validate_serial_nos_duplicate() self.check_future_entries_exists() @@ -2110,6 +2108,8 @@ def update_available_batches(available_batches, *reserved_batches) -> None: def get_available_batches(kwargs): + from erpnext.stock.utils import get_combine_datetime + stock_ledger_entry = frappe.qb.DocType("Stock Ledger Entry") batch_ledger = frappe.qb.DocType("Serial and Batch Entry") batch_table = frappe.qb.DocType("Batch") @@ -2137,9 +2137,9 @@ def get_available_batches(kwargs): if kwargs.get("posting_time") is None: kwargs.posting_time = nowtime() - timestamp_condition = CombineDatetime( - stock_ledger_entry.posting_date, stock_ledger_entry.posting_time - ) <= CombineDatetime(kwargs.posting_date, kwargs.posting_time) + timestamp_condition = stock_ledger_entry.posting_datetime <= get_combine_datetime( + kwargs.posting_date, kwargs.posting_time + ) query = query.where(timestamp_condition) diff --git a/erpnext/stock/serial_batch_bundle.py b/erpnext/stock/serial_batch_bundle.py index a3b16a360a4843dad29dc9a8a8fb9ea048d23efa..6c7f437298a00e6a085613383776ce9fb8bf29bd 100644 --- a/erpnext/stock/serial_batch_bundle.py +++ b/erpnext/stock/serial_batch_bundle.py @@ -735,15 +735,6 @@ class BatchNoValuation(DeprecatedBatchNoValuation): stock_value_change = self.batch_avg_rate[batch_no] * ledger.qty self.stock_value_change += stock_value_change - frappe.db.set_value( - "Serial and Batch Entry", - ledger.name, - { - "stock_value_difference": stock_value_change, - "incoming_rate": self.batch_avg_rate[batch_no], - }, - ) - def calculate_valuation_rate(self): if not hasattr(self, "wh_data"): return @@ -957,12 +948,13 @@ class SerialBatchCreation: if self.get("make_bundle_from_sle") and self.type_of_transaction == "Inward": doc.flags.ignore_validate_serial_batch = True - doc.save() - self.validate_qty(doc) - if not hasattr(self, "do_not_submit") or not self.do_not_submit: doc.flags.ignore_voucher_validation = True doc.submit() + else: + doc.save() + + self.validate_qty(doc) return doc diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index 5ad6008b4040c58981db67e39ec2315816ccfad3..db8fa618d7c26bcf734dc2acd18aceaf14c03fc7 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -989,18 +989,23 @@ class update_entries_after: if not frappe.db.exists("Serial and Batch Bundle", sle.serial_and_batch_bundle): return - doc = frappe.get_cached_doc("Serial and Batch Bundle", sle.serial_and_batch_bundle) - - doc.set_incoming_rate(save=True, allow_negative_stock=self.allow_negative_stock) - doc.calculate_qty_and_amount(save=True) + if self.args.get("sle_id") and sle.actual_qty < 0: + doc = frappe.db.get_value( + "Serial and Batch Bundle", + sle.serial_and_batch_bundle, + ["total_amount", "total_qty"], + as_dict=1, + ) + else: + doc = frappe.get_doc("Serial and Batch Bundle", sle.serial_and_batch_bundle) + doc.set_incoming_rate(save=True, allow_negative_stock=self.allow_negative_stock) + doc.calculate_qty_and_amount(save=True) self.wh_data.stock_value = round_off_if_near_zero(self.wh_data.stock_value + doc.total_amount) - - precision = doc.precision("total_qty") - self.wh_data.qty_after_transaction += flt(doc.total_qty, precision) - if flt(self.wh_data.qty_after_transaction, precision): - self.wh_data.valuation_rate = flt(self.wh_data.stock_value, precision) / flt( - self.wh_data.qty_after_transaction, precision + self.wh_data.qty_after_transaction += flt(doc.total_qty, self.flt_precision) + if flt(self.wh_data.qty_after_transaction, self.flt_precision): + self.wh_data.valuation_rate = flt(self.wh_data.stock_value, self.flt_precision) / flt( + self.wh_data.qty_after_transaction, self.flt_precision ) def update_valuation_rate_in_serial_and_batch_bundle(self, sle, valuation_rate):