mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-27 00:44:45 +00:00
Merge pull request #50235 from mihir-kandoi/sre-sco
feat: stock reservation for subcontracting order
This commit is contained in:
@@ -556,131 +556,6 @@ class SubcontractingInwardController:
|
||||
item.basic_rate + (item.additional_cost / item.transfer_qty), item.precision("basic_rate")
|
||||
)
|
||||
|
||||
def update_sre_for_subcontracting_delivery(self) -> None:
|
||||
if self.purpose == "Subcontracting Delivery":
|
||||
if self._action == "submit":
|
||||
self.update_sre_for_subcontracting_delivery_submit()
|
||||
elif self._action == "cancel":
|
||||
self.update_sre_for_subcontracting_delivery_cancel()
|
||||
|
||||
def update_sre_for_subcontracting_delivery_submit(self):
|
||||
for item in self.get("items"):
|
||||
table = frappe.qb.DocType("Stock Reservation Entry")
|
||||
query = (
|
||||
frappe.qb.from_(table)
|
||||
.select(table.name)
|
||||
.where(
|
||||
(table.docstatus == 1)
|
||||
& (table.voucher_type == "Subcontracting Inward Order")
|
||||
& (table.voucher_no == self.subcontracting_inward_order)
|
||||
& (table.voucher_detail_no == item.scio_detail)
|
||||
)
|
||||
.orderby(table.creation)
|
||||
)
|
||||
sre_list = query.run(pluck="name")
|
||||
|
||||
if not sre_list:
|
||||
continue
|
||||
|
||||
qty_to_deliver = item.transfer_qty
|
||||
for sre in sre_list:
|
||||
if qty_to_deliver <= 0:
|
||||
break
|
||||
|
||||
sre_doc = frappe.get_doc("Stock Reservation Entry", sre)
|
||||
|
||||
qty_can_be_deliver = 0
|
||||
if sre_doc.reservation_based_on == "Serial and Batch":
|
||||
sbb = frappe.get_doc("Serial and Batch Bundle", item.serial_and_batch_bundle)
|
||||
if sre_doc.has_serial_no:
|
||||
delivered_serial_nos = [d.serial_no for d in sbb.entries]
|
||||
for entry in sre_doc.sb_entries:
|
||||
if entry.serial_no in delivered_serial_nos:
|
||||
entry.delivered_qty = 1
|
||||
entry.db_update()
|
||||
qty_can_be_deliver += 1
|
||||
delivered_serial_nos.remove(entry.serial_no)
|
||||
else:
|
||||
delivered_batch_qty = {d.batch_no: -1 * d.qty for d in sbb.entries}
|
||||
for entry in sre_doc.sb_entries:
|
||||
if entry.batch_no in delivered_batch_qty:
|
||||
delivered_qty = min(
|
||||
(entry.qty - entry.delivered_qty),
|
||||
delivered_batch_qty[entry.batch_no],
|
||||
)
|
||||
entry.delivered_qty += delivered_qty
|
||||
entry.db_update()
|
||||
qty_can_be_deliver += delivered_qty
|
||||
delivered_batch_qty[entry.batch_no] -= delivered_qty
|
||||
else:
|
||||
qty_can_be_deliver = min((sre_doc.reserved_qty - sre_doc.delivered_qty), qty_to_deliver)
|
||||
|
||||
sre_doc.delivered_qty += qty_can_be_deliver
|
||||
sre_doc.db_update()
|
||||
sre_doc.update_status()
|
||||
sre_doc.update_reserved_stock_in_bin()
|
||||
|
||||
qty_to_deliver -= qty_can_be_deliver
|
||||
|
||||
def update_sre_for_subcontracting_delivery_cancel(self):
|
||||
for item in self.get("items"):
|
||||
table = frappe.qb.DocType("Stock Reservation Entry")
|
||||
query = (
|
||||
frappe.qb.from_(table)
|
||||
.select(table.name)
|
||||
.where(
|
||||
(table.docstatus == 1)
|
||||
& (table.voucher_type == "Subcontracting Inward Order")
|
||||
& (table.voucher_no == self.subcontracting_inward_order)
|
||||
& (table.voucher_detail_no == item.scio_detail)
|
||||
& (table.warehouse == item.s_warehouse)
|
||||
)
|
||||
.orderby(table.creation)
|
||||
)
|
||||
sre_list = query.run(pluck="name")
|
||||
|
||||
if not sre_list:
|
||||
continue
|
||||
|
||||
qty_to_undelivered = item.transfer_qty
|
||||
for sre in sre_list:
|
||||
if qty_to_undelivered <= 0:
|
||||
break
|
||||
|
||||
sre_doc = frappe.get_doc("Stock Reservation Entry", sre)
|
||||
|
||||
qty_can_be_undelivered = 0
|
||||
if sre_doc.reservation_based_on == "Serial and Batch":
|
||||
sbb = frappe.get_doc("Serial and Batch Bundle", item.serial_and_batch_bundle)
|
||||
if sre_doc.has_serial_no:
|
||||
serial_nos_to_undelivered = [d.serial_no for d in sbb.entries]
|
||||
for entry in sre_doc.sb_entries:
|
||||
if entry.serial_no in serial_nos_to_undelivered:
|
||||
entry.delivered_qty = 0
|
||||
entry.db_update()
|
||||
qty_can_be_undelivered += 1
|
||||
serial_nos_to_undelivered.remove(entry.serial_no)
|
||||
else:
|
||||
batch_qty_to_undelivered = {d.batch_no: -1 * d.qty for d in sbb.entries}
|
||||
for entry in sre_doc.sb_entries:
|
||||
if entry.batch_no in batch_qty_to_undelivered:
|
||||
undelivered_qty = min(
|
||||
entry.delivered_qty, batch_qty_to_undelivered[entry.batch_no]
|
||||
)
|
||||
entry.delivered_qty -= undelivered_qty
|
||||
entry.db_update()
|
||||
qty_can_be_undelivered += undelivered_qty
|
||||
batch_qty_to_undelivered[entry.batch_no] -= undelivered_qty
|
||||
else:
|
||||
qty_can_be_undelivered = min(sre_doc.delivered_qty, qty_to_undelivered)
|
||||
|
||||
sre_doc.delivered_qty -= qty_can_be_undelivered
|
||||
sre_doc.db_update()
|
||||
sre_doc.update_status()
|
||||
sre_doc.update_reserved_stock_in_bin()
|
||||
|
||||
qty_to_undelivered -= qty_can_be_undelivered
|
||||
|
||||
def validate_receive_from_customer_cancel(self):
|
||||
if self.purpose == "Receive from Customer":
|
||||
for item in self.items:
|
||||
|
||||
Reference in New Issue
Block a user