Skip to content

Commit 0f9bf08

Browse files
kavin-114mergify[bot]
authored andcommitted
fix(credit-note): set incoming rate as zero for expired batch
(cherry picked from commit e78c750)
1 parent b84fd46 commit 0f9bf08

3 files changed

Lines changed: 57 additions & 5 deletions

File tree

erpnext/controllers/sales_and_purchase_return.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
import erpnext
1414
from erpnext.stock.serial_batch_bundle import get_batches_from_bundle
15-
from erpnext.stock.utils import get_combine_datetime, get_incoming_rate, get_valuation_method
15+
from erpnext.stock.utils import get_combine_datetime, get_incoming_rate, get_valuation_method, getdate
1616

1717

1818
class StockOverReturnError(frappe.ValidationError):
@@ -759,6 +759,29 @@ def get_rate_for_return(
759759
StockLedgerEntry = frappe.qb.DocType("Stock Ledger Entry")
760760
select_field = Abs(StockLedgerEntry.stock_value_difference / StockLedgerEntry.actual_qty)
761761

762+
item_details = frappe.get_cached_value("Item", item_code, ["has_batch_no", "has_expiry_date"], as_dict=1)
763+
set_zero_rate_for_expired_batch = frappe.db.get_single_value(
764+
"Selling Settings", "set_zero_rate_for_expired_batch"
765+
)
766+
767+
if (
768+
set_zero_rate_for_expired_batch
769+
and item_details.has_batch_no
770+
and item_details.has_expiry_date
771+
and not return_against
772+
and voucher_type in ["Sales Invoice", "Delivery Note"]
773+
):
774+
# set incoming_rate zero explicitly for standalone credit note with expired batch
775+
batch_no = frappe.db.get_value(f"{voucher_type} Item", voucher_detail_no, "batch_no")
776+
if batch_no and is_batch_expired(batch_no, sle.get("posting_date")):
777+
frappe.db.set_value(
778+
voucher_type + " Item",
779+
voucher_detail_no,
780+
"incoming_rate",
781+
0,
782+
)
783+
return 0
784+
762785
rate = flt(frappe.db.get_value("Stock Ledger Entry", filters, select_field))
763786
if not (rate and return_against) and voucher_type in ["Sales Invoice", "Delivery Note"]:
764787
rate = frappe.db.get_value(f"{voucher_type} Item", voucher_detail_no, "incoming_rate")
@@ -1276,3 +1299,17 @@ def get_sales_invoice_item_from_consolidated_invoice(return_against_pos_invoice,
12761299
return result[0].name if result else None
12771300
except Exception:
12781301
return None
1302+
1303+
1304+
def is_batch_expired(batch_no, posting_date):
1305+
"""
1306+
To check whether the batch is expired or not based on the posting date.
1307+
"""
1308+
expiry_date = frappe.db.get_value("Batch", batch_no, "expiry_date")
1309+
if not expiry_date:
1310+
return
1311+
1312+
if getdate(posting_date) > getdate(expiry_date):
1313+
return True
1314+
1315+
return False

erpnext/controllers/selling_controller.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from erpnext.accounts.party import render_address
1010
from erpnext.controllers.accounts_controller import get_taxes_and_charges
11-
from erpnext.controllers.sales_and_purchase_return import get_rate_for_return
11+
from erpnext.controllers.sales_and_purchase_return import get_rate_for_return, is_batch_expired
1212
from erpnext.controllers.stock_controller import StockController
1313
from erpnext.stock.doctype.item.item import set_item_default
1414
from erpnext.stock.get_item_details import get_bin_details, get_conversion_factor
@@ -536,16 +536,31 @@ def set_incoming_rate(self):
536536
allow_at_arms_length_price = frappe.get_cached_value(
537537
"Stock Settings", None, "allow_internal_transfer_at_arms_length_price"
538538
)
539+
set_zero_rate_for_expired_batch = frappe.db.get_single_value(
540+
"Selling Settings", "set_zero_rate_for_expired_batch"
541+
)
542+
539543
items = self.get("items") + (self.get("packed_items") or [])
540544
for d in items:
541545
if not frappe.get_cached_value("Item", d.item_code, "is_stock_item"):
542546
continue
543547

544548
item_details = frappe.get_cached_value(
545-
"Item", d.item_code, ["has_serial_no", "has_batch_no"], as_dict=1
549+
"Item", d.item_code, ["has_serial_no", "has_batch_no", "has_expiry_date"], as_dict=1
546550
)
547551

548-
if not self.get("return_against") or (
552+
if (
553+
set_zero_rate_for_expired_batch
554+
and item_details.has_batch_no
555+
and item_details.has_expiry_date
556+
and self.get("is_return")
557+
and not self.get("return_against")
558+
and is_batch_expired(d.batch_no, self.get("posting_date"))
559+
):
560+
# set incoming rate as zero for stand-lone credit note with expired batch
561+
d.incoming_rate = 0
562+
563+
elif not self.get("return_against") or (
549564
get_valuation_method(d.item_code, self.company) == "Moving Average"
550565
and self.get("is_return")
551566
and not item_details.has_serial_no

erpnext/selling/doctype/selling_settings/selling_settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class SellingSettings(Document):
4444
role_to_override_stop_action: DF.Link | None
4545
sales_update_frequency: DF.Literal["Monthly", "Each Transaction", "Daily"]
4646
selling_price_list: DF.Link | None
47-
set_zero_rate_for_expired: DF.Check
47+
set_zero_rate_for_expired_batch: DF.Check
4848
so_required: DF.Literal["No", "Yes"]
4949
territory: DF.Link | None
5050
use_legacy_js_reactivity: DF.Check

0 commit comments

Comments
 (0)