refactor: rename field against_pick_list

This commit is contained in:
s-aga-r 2023-10-19 17:51:34 +05:30
parent 78fe567419
commit 961d2d9926
9 changed files with 96 additions and 62 deletions

View File

@ -265,7 +265,8 @@ frappe.ui.form.on('Pick List', {
from_date: moment(frm.doc.creation).format('YYYY-MM-DD'),
to_date: to_date,
voucher_type: "Sales Order",
against_pick_list: frm.doc.name,
from_voucher_type: "Pick List",
from_voucher_no: frm.doc.name,
}
frappe.set_route("query-report", "Reserved Stock");
}

View File

@ -242,7 +242,7 @@ class PickList(Document):
for so, locations in so_details.items():
so_doc = frappe.get_doc("Sales Order", so)
create_stock_reservation_entries_for_so_items(
sales_order=so_doc, items_details=locations, against_pick_list=True, notify=notify
sales_order=so_doc, items_details=locations, from_voucher_type="Pick List", notify=notify
)
@frappe.whitelist()
@ -253,7 +253,9 @@ class PickList(Document):
cancel_stock_reservation_entries,
)
cancel_stock_reservation_entries(against_pick_list=self.name, notify=notify)
cancel_stock_reservation_entries(
from_voucher_type="Pick List", from_voucher_no=self.name, notify=notify
)
def validate_picked_qty(self, data):
over_delivery_receipt_allowance = 100 + flt(

View File

@ -2,7 +2,7 @@ def get_data():
return {
"fieldname": "pick_list",
"non_standard_fieldnames": {
"Stock Reservation Entry": "against_pick_list",
"Stock Reservation Entry": "from_voucher_no",
},
"internal_links": {
"Sales Order": ["locations", "sales_order"],

View File

@ -92,7 +92,7 @@ frappe.ui.form.on('Stock Reservation Entry', {
'qty', 'read_only', frm.doc.has_serial_no
);
frm.set_df_property('sb_entries', 'allow_on_submit', frm.doc.against_pick_list ? 0 : 1);
frm.set_df_property('sb_entries', 'allow_on_submit', frm.doc.from_voucher_type == "Pick List" ? 0 : 1);
},
hide_rate_related_fields(frm) {

View File

@ -18,7 +18,7 @@
"voucher_detail_no",
"column_break_7dxj",
"from_voucher_type",
"against_pick_list",
"from_voucher_no",
"from_voucher_detail_no",
"section_break_xt4m",
"stock_uom",
@ -159,7 +159,7 @@
"oldfieldname": "actual_qty",
"oldfieldtype": "Currency",
"print_width": "150px",
"read_only_depends_on": "eval: ((doc.reservation_based_on == \"Serial and Batch\") || (doc.against_pick_list) || (doc.delivered_qty > 0))",
"read_only_depends_on": "eval: ((doc.reservation_based_on == \"Serial and Batch\") || (doc.from_voucher_type == \"Pick List\") || (doc.delivered_qty > 0))",
"width": "150px"
},
{
@ -269,18 +269,7 @@
"label": "Reservation Based On",
"no_copy": 1,
"options": "Qty\nSerial and Batch",
"read_only_depends_on": "eval: (doc.delivered_qty > 0 || doc.against_pick_list)"
},
{
"fieldname": "against_pick_list",
"fieldtype": "Dynamic Link",
"label": "From Voucher No",
"no_copy": 1,
"options": "from_voucher_type",
"print_hide": 1,
"read_only": 1,
"report_hide": 1,
"search_index": 1
"read_only_depends_on": "eval: (doc.delivered_qty > 0 || doc.from_voucher_type == \"Pick List\")"
},
{
"fieldname": "column_break_7dxj",
@ -308,6 +297,17 @@
"print_hide": 1,
"read_only": 1,
"report_hide": 1
},
{
"fieldname": "from_voucher_no",
"fieldtype": "Dynamic Link",
"label": "From Voucher No",
"no_copy": 1,
"options": "from_voucher_type",
"print_hide": 1,
"read_only": 1,
"report_hide": 1,
"search_index": 1
}
],
"hide_toolbar": 1,
@ -315,7 +315,7 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2023-10-19 16:26:46.598043",
"modified": "2023-10-19 16:41:16.545416",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Reservation Entry",

View File

@ -1,6 +1,8 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from typing import Literal
import frappe
from frappe import _
from frappe.model.document import Document
@ -113,7 +115,7 @@ class StockReservationEntry(Document):
"""Auto pick Serial and Batch Nos to reserve when `Reservation Based On` is `Serial and Batch`."""
if (
not self.against_pick_list
not self.from_voucher_type
and (self.get("_action") == "submit")
and (self.has_serial_no or self.has_batch_no)
and cint(frappe.db.get_single_value("Stock Settings", "auto_reserve_serial_and_batch"))
@ -317,7 +319,7 @@ class StockReservationEntry(Document):
"""Updates total reserved qty in the Pick List."""
if (
self.from_voucher_type == "Pick List" and self.against_pick_list and self.from_voucher_detail_no
self.from_voucher_type == "Pick List" and self.from_voucher_no and self.from_voucher_detail_no
):
sre = frappe.qb.DocType("Stock Reservation Entry")
reserved_qty = (
@ -326,7 +328,7 @@ class StockReservationEntry(Document):
.where(
(sre.docstatus == 1)
& (sre.from_voucher_type == "Pick List")
& (sre.against_pick_list == self.against_pick_list)
& (sre.from_voucher_no == self.from_voucher_no)
& (sre.from_voucher_detail_no == self.from_voucher_detail_no)
)
).run(as_list=True)[0][0] or 0
@ -368,7 +370,7 @@ class StockReservationEntry(Document):
).format(self.status, self.doctype)
frappe.throw(msg)
if self.against_pick_list:
if self.from_voucher_type == "Pick List":
msg = _(
"Stock Reservation Entry created against a Pick List cannot be updated. If you need to make changes, we recommend canceling the existing entry and creating a new one."
)
@ -766,14 +768,14 @@ def has_reserved_stock(voucher_type: str, voucher_no: str, voucher_detail_no: st
def create_stock_reservation_entries_for_so_items(
sales_order: object,
items_details: list[dict] = None,
against_pick_list: bool = False,
from_voucher_type: Literal["Pick List", "Purchase Receipt"] = None,
notify=True,
) -> None:
"""Creates Stock Reservation Entries for Sales Order Items."""
from erpnext.selling.doctype.sales_order.sales_order import get_unreserved_qty
if not against_pick_list and (
if not from_voucher_type and (
sales_order.get("_action") == "submit"
and sales_order.set_warehouse
and cint(frappe.get_cached_value("Warehouse", sales_order.set_warehouse, "is_group"))
@ -792,20 +794,20 @@ def create_stock_reservation_entries_for_so_items(
items = []
if items_details:
item_field = "sales_order_item" if against_pick_list else "name"
item_field = "sales_order_item" if from_voucher_type == "Pick List" else "name"
for item in items_details:
so_item = frappe.get_doc("Sales Order Item", item.get(item_field))
so_item.warehouse = item.get("warehouse")
so_item.qty_to_reserve = (
item.get("picked_qty") - item.get("stock_reserved_qty", 0)
if against_pick_list
if from_voucher_type == "Pick List"
else (flt(item.get("qty_to_reserve")) * flt(so_item.conversion_factor, 1))
)
so_item.serial_and_batch_bundle = item.get("serial_and_batch_bundle")
if against_pick_list:
so_item.pick_list = item.get("parent")
if from_voucher_type == "Pick List":
so_item.from_voucher_no = item.get("parent")
so_item.from_voucher_detail_no = item.get("name")
items.append(so_item)
@ -819,7 +821,7 @@ def create_stock_reservation_entries_for_so_items(
continue
# Stock should be reserved from the Pick List if has Picked Qty.
if not against_pick_list and flt(item.picked_qty) > 0:
if not from_voucher_type == "Pick List" and flt(item.picked_qty) > 0:
frappe.throw(
_("Row #{0}: Item {1} has been picked, please reserve stock from the Pick List.").format(
item.idx, frappe.bold(item.item_code)
@ -929,9 +931,9 @@ def create_stock_reservation_entries_for_so_items(
sre.stock_uom = item.stock_uom
sre.project = sales_order.project
if against_pick_list:
sre.from_voucher_type = "Pick List"
sre.against_pick_list = item.pick_list
if from_voucher_type:
sre.from_voucher_type = from_voucher_type
sre.from_voucher_no = item.from_voucher_no
sre.from_voucher_detail_no = item.from_voucher_detail_no
if item.serial_and_batch_bundle:
@ -961,29 +963,37 @@ def cancel_stock_reservation_entries(
voucher_type: str = None,
voucher_no: str = None,
voucher_detail_no: str = None,
against_pick_list: str = None,
from_voucher_type: Literal["Pick List", "Purchase Receipt"] = None,
from_voucher_no: str = None,
from_voucher_detail_no: str = None,
sre_list: list[dict] = None,
notify: bool = True,
) -> None:
"""Cancel Stock Reservation Entries."""
if not sre_list and against_pick_list:
sre = frappe.qb.DocType("Stock Reservation Entry")
sre_list = (
frappe.qb.from_(sre)
.select(sre.name)
.where(
(sre.docstatus == 1)
& (sre.against_pick_list == against_pick_list)
& (sre.status.notin(["Delivered", "Cancelled"]))
if not sre_list:
if voucher_type and voucher_no:
sre_list = get_stock_reservation_entries_for_voucher(
voucher_type, voucher_no, voucher_detail_no, fields=["name"]
)
elif from_voucher_type and from_voucher_no:
sre = frappe.qb.DocType("Stock Reservation Entry")
query = (
frappe.qb.from_(sre)
.select(sre.name)
.where(
(sre.docstatus == 1)
& (sre.from_voucher_type == from_voucher_type)
& (sre.from_voucher_no == from_voucher_no)
& (sre.status.notin(["Delivered", "Cancelled"]))
)
.orderby(sre.creation)
)
.orderby(sre.creation)
).run(as_dict=True)
elif not sre_list and (voucher_type and voucher_no):
sre_list = get_stock_reservation_entries_for_voucher(
voucher_type, voucher_no, voucher_detail_no, fields=["name"]
)
if from_voucher_detail_no:
query = query.where(sre.from_voucher_detail_no == from_voucher_detail_no)
sre_list = query.run(as_dict=True)
if sre_list:
for sre in sre_list:

View File

@ -556,7 +556,7 @@ class TestStockReservationEntry(FrappeTestCase):
& (sre.voucher_no == location.sales_order)
& (sre.voucher_detail_no == location.sales_order_item)
& (sre.from_voucher_type == "Pick List")
& (sre.against_pick_list == pl.name)
& (sre.from_voucher_no == pl.name)
& (sre.from_voucher_detail_no == location.name)
)
).run(as_dict=True)

View File

@ -91,16 +91,30 @@ frappe.query_reports["Reserved Stock"] = {
},
},
{
fieldname: "against_pick_list",
label: __("Against Pick List"),
fieldname: "from_voucher_type",
label: __("From Voucher Type"),
fieldtype: "Link",
options: "Pick List",
options: "DocType",
get_query: () => ({
filters: {
name: ["in", ["Pick List", "Purchase Receipt"]],
}
}),
},
{
fieldname: "from_voucher_no",
label: __("From Voucher No"),
fieldtype: "Dynamic Link",
options: "from_voucher_type",
get_query: () => ({
filters: {
docstatus: 1,
company: frappe.query_report.get_filter_value("company"),
},
}),
get_options: function () {
return frappe.query_report.get_filter_value("from_voucher_type");
},
},
{
fieldname: "reservation_based_on",

View File

@ -44,7 +44,8 @@ def get_data(filters):
(sre.available_qty - sre.reserved_qty).as_("available_qty"),
sre.voucher_type,
sre.voucher_no,
sre.against_pick_list,
sre.from_voucher_type,
sre.from_voucher_no,
sre.name.as_("stock_reservation_entry"),
sre.status,
sre.project,
@ -65,7 +66,8 @@ def get_data(filters):
"warehouse",
"voucher_type",
"voucher_no",
"against_pick_list",
"from_voucher_type",
"from_voucher_no",
"reservation_based_on",
"status",
"project",
@ -142,7 +144,6 @@ def get_columns():
"fieldname": "voucher_type",
"label": _("Voucher Type"),
"fieldtype": "Data",
"options": "Warehouse",
"width": 110,
},
{
@ -153,11 +154,17 @@ def get_columns():
"width": 120,
},
{
"fieldname": "against_pick_list",
"label": _("Against Pick List"),
"fieldtype": "Link",
"options": "Pick List",
"width": 130,
"fieldname": "from_voucher_type",
"label": _("From Voucher Type"),
"fieldtype": "Data",
"width": 110,
},
{
"fieldname": "from_voucher_no",
"label": _("From Voucher No"),
"fieldtype": "Dynamic Link",
"options": "from_voucher_type",
"width": 120,
},
{
"fieldname": "stock_reservation_entry",