mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-13 20:05:09 +00:00
fix: validation for negative batch
(cherry picked from commit f9c8f27586)
This commit is contained in:
committed by
Mergify
parent
44f39e0b43
commit
b9dd05f292
@@ -78,6 +78,7 @@ class DeprecatedBatchNoValuation:
|
|||||||
for ledger in entries:
|
for ledger in entries:
|
||||||
self.stock_value_differece[ledger.batch_no] += flt(ledger.batch_value)
|
self.stock_value_differece[ledger.batch_no] += flt(ledger.batch_value)
|
||||||
self.available_qty[ledger.batch_no] += flt(ledger.batch_qty)
|
self.available_qty[ledger.batch_no] += flt(ledger.batch_qty)
|
||||||
|
self.total_qty[ledger.batch_no] += flt(ledger.batch_qty)
|
||||||
|
|
||||||
@deprecated
|
@deprecated
|
||||||
def get_sle_for_batches(self):
|
def get_sle_for_batches(self):
|
||||||
@@ -230,6 +231,7 @@ class DeprecatedBatchNoValuation:
|
|||||||
batch_data = query.run(as_dict=True)
|
batch_data = query.run(as_dict=True)
|
||||||
for d in batch_data:
|
for d in batch_data:
|
||||||
self.available_qty[d.batch_no] += flt(d.batch_qty)
|
self.available_qty[d.batch_no] += flt(d.batch_qty)
|
||||||
|
self.total_qty[d.batch_no] += flt(d.batch_qty)
|
||||||
|
|
||||||
for d in batch_data:
|
for d in batch_data:
|
||||||
if self.available_qty.get(d.batch_no):
|
if self.available_qty.get(d.batch_no):
|
||||||
@@ -330,6 +332,7 @@ class DeprecatedBatchNoValuation:
|
|||||||
batch_data = query.run(as_dict=True)
|
batch_data = query.run(as_dict=True)
|
||||||
for d in batch_data:
|
for d in batch_data:
|
||||||
self.available_qty[d.batch_no] += flt(d.batch_qty)
|
self.available_qty[d.batch_no] += flt(d.batch_qty)
|
||||||
|
self.total_qty[d.batch_no] += flt(d.batch_qty)
|
||||||
|
|
||||||
if not self.last_sle:
|
if not self.last_sle:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -518,12 +518,15 @@ class SerialandBatchBundle(Document):
|
|||||||
else:
|
else:
|
||||||
d.incoming_rate = abs(flt(sn_obj.batch_avg_rate.get(d.batch_no)))
|
d.incoming_rate = abs(flt(sn_obj.batch_avg_rate.get(d.batch_no)))
|
||||||
|
|
||||||
available_qty = flt(sn_obj.available_qty.get(d.batch_no), d.precision("qty"))
|
precision = d.precision("qty")
|
||||||
if self.docstatus == 1:
|
for field in ["available_qty", "total_qty"]:
|
||||||
available_qty += flt(d.qty, d.precision("qty"))
|
value = getattr(sn_obj, field)
|
||||||
|
available_qty = flt(value.get(d.batch_no), precision)
|
||||||
|
if self.docstatus == 1:
|
||||||
|
available_qty += flt(d.qty, precision)
|
||||||
|
|
||||||
if not allow_negative_stock:
|
if not allow_negative_stock:
|
||||||
self.validate_negative_batch(d.batch_no, available_qty)
|
self.validate_negative_batch(d.batch_no, available_qty)
|
||||||
|
|
||||||
d.stock_value_difference = flt(d.qty) * flt(d.incoming_rate)
|
d.stock_value_difference = flt(d.qty) * flt(d.incoming_rate)
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from collections import defaultdict
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _, bold
|
from frappe import _, bold
|
||||||
from frappe.model.naming import make_autoname
|
from frappe.model.naming import make_autoname
|
||||||
|
from frappe.query_builder import Case
|
||||||
from frappe.query_builder.functions import CombineDatetime, Sum, Timestamp
|
from frappe.query_builder.functions import CombineDatetime, Sum, Timestamp
|
||||||
from frappe.utils import add_days, cint, cstr, flt, get_link_to_form, now, nowtime, today
|
from frappe.utils import add_days, cint, cstr, flt, get_link_to_form, now, nowtime, today
|
||||||
from pypika import Order
|
from pypika import Order
|
||||||
@@ -708,6 +709,7 @@ class BatchNoValuation(DeprecatedBatchNoValuation):
|
|||||||
for key, value in kwargs.items():
|
for key, value in kwargs.items():
|
||||||
setattr(self, key, value)
|
setattr(self, key, value)
|
||||||
|
|
||||||
|
self.total_qty = defaultdict(float)
|
||||||
self.stock_queue = []
|
self.stock_queue = []
|
||||||
self.batch_nos = self.get_batch_nos()
|
self.batch_nos = self.get_batch_nos()
|
||||||
self.prepare_batches()
|
self.prepare_batches()
|
||||||
@@ -729,6 +731,7 @@ class BatchNoValuation(DeprecatedBatchNoValuation):
|
|||||||
for ledger in entries:
|
for ledger in entries:
|
||||||
self.stock_value_differece[ledger.batch_no] += flt(ledger.incoming_rate)
|
self.stock_value_differece[ledger.batch_no] += flt(ledger.incoming_rate)
|
||||||
self.available_qty[ledger.batch_no] += flt(ledger.qty)
|
self.available_qty[ledger.batch_no] += flt(ledger.qty)
|
||||||
|
self.total_qty[ledger.batch_no] += flt(ledger.total_qty)
|
||||||
|
|
||||||
self.calculate_avg_rate_from_deprecarated_ledgers()
|
self.calculate_avg_rate_from_deprecarated_ledgers()
|
||||||
self.calculate_avg_rate_for_non_batchwise_valuation()
|
self.calculate_avg_rate_for_non_batchwise_valuation()
|
||||||
@@ -762,13 +765,16 @@ class BatchNoValuation(DeprecatedBatchNoValuation):
|
|||||||
.on(parent.name == child.parent)
|
.on(parent.name == child.parent)
|
||||||
.select(
|
.select(
|
||||||
child.batch_no,
|
child.batch_no,
|
||||||
Sum(child.stock_value_difference).as_("incoming_rate"),
|
Sum(Case().when(timestamp_condition, child.stock_value_difference).else_(0)).as_(
|
||||||
Sum(child.qty).as_("qty"),
|
"incoming_rate"
|
||||||
|
),
|
||||||
|
Sum(Case().when(timestamp_condition, child.qty).else_(0)).as_("qty"),
|
||||||
|
Sum(child.qty).as_("total_qty"),
|
||||||
)
|
)
|
||||||
.where(
|
.where(
|
||||||
(child.batch_no.isin(self.batchwise_valuation_batches))
|
(parent.warehouse == self.sle.warehouse)
|
||||||
& (parent.warehouse == self.sle.warehouse)
|
|
||||||
& (parent.item_code == self.sle.item_code)
|
& (parent.item_code == self.sle.item_code)
|
||||||
|
& (child.batch_no.isin(self.batchwise_valuation_batches))
|
||||||
& (parent.docstatus == 1)
|
& (parent.docstatus == 1)
|
||||||
& (parent.is_cancelled == 0)
|
& (parent.is_cancelled == 0)
|
||||||
& (parent.type_of_transaction.isin(["Inward", "Outward"]))
|
& (parent.type_of_transaction.isin(["Inward", "Outward"]))
|
||||||
@@ -784,8 +790,6 @@ class BatchNoValuation(DeprecatedBatchNoValuation):
|
|||||||
query = query.where(parent.voucher_no != self.sle.voucher_no)
|
query = query.where(parent.voucher_no != self.sle.voucher_no)
|
||||||
|
|
||||||
query = query.where(parent.voucher_type != "Pick List")
|
query = query.where(parent.voucher_type != "Pick List")
|
||||||
if timestamp_condition:
|
|
||||||
query = query.where(timestamp_condition)
|
|
||||||
|
|
||||||
return query.run(as_dict=True)
|
return query.run(as_dict=True)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user