fix: map DN items based on SRE
This commit is contained in:
parent
15cb99290c
commit
3602d1909e
@ -622,7 +622,36 @@ def make_project(source_name, target_doc=None):
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_delivery_note(source_name, target_doc=None, skip_item_mapping=False):
|
||||
from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import (
|
||||
get_stock_reservation_entry_for_voucher,
|
||||
has_reserved_stock,
|
||||
)
|
||||
|
||||
def set_missing_values(source, target):
|
||||
if not target.items and has_reserved_stock("Sales Order", source_name):
|
||||
sre_list = get_stock_reservation_entry_for_voucher("Sales Order", source_name)
|
||||
sre_dict = {d.pop("voucher_detail_no"): d for d in sre_list}
|
||||
|
||||
for item in source.get("items"):
|
||||
if item.name in sre_dict:
|
||||
qty_to_deliver = (
|
||||
sre_dict[item.name]["reserved_qty"] - sre_dict[item.name]["delivered_qty"]
|
||||
) / item.conversion_factor
|
||||
|
||||
row = frappe.new_doc("Delivery Note Item")
|
||||
row.against_sales_order = source.name
|
||||
row.against_sre = sre_dict[item.name]["name"]
|
||||
row.so_detail = item.name
|
||||
row.item_code = item.item_code
|
||||
row.item_name = item.item_name
|
||||
row.description = item.description
|
||||
row.qty = qty_to_deliver
|
||||
row.stock_uom = item.stock_uom
|
||||
row.uom = item.uom
|
||||
row.conversion_factor = item.conversion_factor
|
||||
|
||||
target.append("items", row)
|
||||
|
||||
target.run_method("set_missing_values")
|
||||
target.run_method("set_po_nos")
|
||||
target.run_method("calculate_taxes_and_totals")
|
||||
@ -651,6 +680,9 @@ def make_delivery_note(source_name, target_doc=None, skip_item_mapping=False):
|
||||
or item_group.get("buying_cost_center")
|
||||
)
|
||||
|
||||
if has_reserved_stock("Sales Order", source_name):
|
||||
skip_item_mapping = True
|
||||
|
||||
mapper = {
|
||||
"Sales Order": {"doctype": "Delivery Note", "validation": {"docstatus": ["=", 1]}},
|
||||
"Sales Taxes and Charges": {"doctype": "Sales Taxes and Charges", "add_if_empty": True},
|
||||
@ -678,7 +710,6 @@ def make_delivery_note(source_name, target_doc=None, skip_item_mapping=False):
|
||||
}
|
||||
|
||||
target_doc = get_mapped_doc("Sales Order", source_name, mapper, target_doc, set_missing_values)
|
||||
|
||||
target_doc.set_onload("ignore_price_list", True)
|
||||
|
||||
return target_doc
|
||||
|
@ -239,6 +239,8 @@ class DeliveryNote(SellingController):
|
||||
self.update_prevdoc_status()
|
||||
self.update_billing_status()
|
||||
|
||||
self.update_stock_reservation_entry()
|
||||
|
||||
if not self.is_return:
|
||||
self.check_credit_limit()
|
||||
elif self.issue_credit_note:
|
||||
@ -258,6 +260,8 @@ class DeliveryNote(SellingController):
|
||||
self.update_prevdoc_status()
|
||||
self.update_billing_status()
|
||||
|
||||
self.update_stock_reservation_entry()
|
||||
|
||||
# Updating stock ledger should always be called after updating prevdoc status,
|
||||
# because updating reserved qty in bin depends upon updated delivered qty in SO
|
||||
self.update_stock_ledger()
|
||||
@ -268,6 +272,16 @@ class DeliveryNote(SellingController):
|
||||
self.repost_future_sle_and_gle()
|
||||
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry", "Repost Item Valuation")
|
||||
|
||||
def update_stock_reservation_entry(self):
|
||||
if not self.is_return:
|
||||
from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import (
|
||||
update_delivered_qty,
|
||||
)
|
||||
|
||||
for item in self.get("items"):
|
||||
if item.against_sre:
|
||||
update_delivered_qty(item.doctype, item.against_sre)
|
||||
|
||||
def check_credit_limit(self):
|
||||
from erpnext.selling.doctype.customer.customer import check_credit_limit
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.query_builder.functions import Sum
|
||||
|
||||
from erpnext.utilities.transaction_base import TransactionBase
|
||||
|
||||
@ -62,8 +63,6 @@ class StockReservationEntry(TransactionBase):
|
||||
frappe.db.set_value(self.doctype, self.name, "status", status, update_modified=update_modified)
|
||||
|
||||
def update_reserved_qty_in_voucher(self, update_modified=True):
|
||||
from frappe.query_builder.functions import Sum
|
||||
|
||||
sre = frappe.qb.DocType("Stock Reservation Entry")
|
||||
reserved_qty = (
|
||||
frappe.qb.from_(sre)
|
||||
@ -83,3 +82,52 @@ class StockReservationEntry(TransactionBase):
|
||||
reserved_qty,
|
||||
update_modified=update_modified,
|
||||
)
|
||||
|
||||
|
||||
def get_stock_reservation_entry_for_voucher(voucher_type, voucher_no, voucher_detail_no=None):
|
||||
sre = frappe.qb.DocType("Stock Reservation Entry")
|
||||
query = (
|
||||
frappe.qb.from_(sre)
|
||||
.select(
|
||||
sre.name,
|
||||
sre.item_code,
|
||||
sre.warehouse,
|
||||
sre.voucher_detail_no,
|
||||
sre.reserved_qty,
|
||||
sre.delivered_qty,
|
||||
sre.stock_uom,
|
||||
)
|
||||
.where(
|
||||
(sre.docstatus == 1)
|
||||
& (sre.voucher_type == voucher_type)
|
||||
& (sre.voucher_no == voucher_no)
|
||||
& (sre.status.notin(["Delivered", "Cancelled"]))
|
||||
)
|
||||
.orderby(sre.creation)
|
||||
)
|
||||
|
||||
if voucher_detail_no:
|
||||
query = query.where(sre.voucher_detail_no == voucher_detail_no)
|
||||
|
||||
return query.run(as_dict=True)
|
||||
|
||||
|
||||
def has_reserved_stock(voucher_type, voucher_no, voucher_detail_no=None):
|
||||
if get_stock_reservation_entry_for_voucher(voucher_type, voucher_no, voucher_detail_no):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def update_delivered_qty(doctype, sre_name, sre_field="against_sre", qty_field="stock_qty"):
|
||||
table = frappe.qb.DocType(doctype)
|
||||
delivered_qty = (
|
||||
frappe.qb.from_(table)
|
||||
.select(Sum(table[qty_field]))
|
||||
.where((table.docstatus == 1) & (table[sre_field] == sre_name))
|
||||
).run(as_list=True)[0][0] or 0.0
|
||||
|
||||
sre_doc = frappe.get_doc("Stock Reservation Entry", sre_name)
|
||||
sre_doc.delivered_qty = delivered_qty
|
||||
sre_doc.db_update()
|
||||
sre_doc.update_status()
|
||||
|
Loading…
x
Reference in New Issue
Block a user