|
12 | 12 |
|
13 | 13 | import erpnext |
14 | 14 | 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 |
16 | 16 |
|
17 | 17 |
|
18 | 18 | class StockOverReturnError(frappe.ValidationError): |
@@ -759,6 +759,29 @@ def get_rate_for_return( |
759 | 759 | StockLedgerEntry = frappe.qb.DocType("Stock Ledger Entry") |
760 | 760 | select_field = Abs(StockLedgerEntry.stock_value_difference / StockLedgerEntry.actual_qty) |
761 | 761 |
|
| 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 | + |
762 | 785 | rate = flt(frappe.db.get_value("Stock Ledger Entry", filters, select_field)) |
763 | 786 | if not (rate and return_against) and voucher_type in ["Sales Invoice", "Delivery Note"]: |
764 | 787 | 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, |
1276 | 1299 | return result[0].name if result else None |
1277 | 1300 | except Exception: |
1278 | 1301 | 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 |
0 commit comments