mirror of
https://github.com/frappe/erpnext.git
synced 2026-02-17 00:25:01 +00:00
Merge pull request #49781 from rohitwaghchaure/fixed-extra-tramsfer-materials
fix: additional material transfer
This commit is contained in:
@@ -756,12 +756,26 @@ erpnext.work_order = {
|
||||
});
|
||||
start_btn.addClass("btn-primary");
|
||||
} else if (transfer_extra_materials && allowed_qty) {
|
||||
let qty = allowed_qty - flt(frm.doc.material_transferred_for_manufacturing);
|
||||
let qty =
|
||||
allowed_qty -
|
||||
flt(
|
||||
flt(frm.doc.material_transferred_for_manufacturing) +
|
||||
flt(frm.doc.additional_transferred_qty)
|
||||
);
|
||||
|
||||
if (qty > 0) {
|
||||
frm.add_custom_button(__("Transfer Extra Material"), function () {
|
||||
erpnext.work_order.make_se(frm, "Material Transfer for Manufacture", qty);
|
||||
});
|
||||
frm.add_custom_button(
|
||||
__("Additional Transfer"),
|
||||
function () {
|
||||
erpnext.work_order.make_se(
|
||||
frm,
|
||||
"Material Transfer for Manufacture",
|
||||
qty,
|
||||
1
|
||||
);
|
||||
},
|
||||
__("Make")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -988,13 +1002,14 @@ erpnext.work_order = {
|
||||
});
|
||||
},
|
||||
|
||||
make_se: function (frm, purpose, qty) {
|
||||
make_se: function (frm, purpose, qty, is_additional_transfer_entry) {
|
||||
if (qty) {
|
||||
frappe
|
||||
.xcall("erpnext.manufacturing.doctype.work_order.work_order.make_stock_entry", {
|
||||
work_order_id: frm.doc.name,
|
||||
purpose: purpose,
|
||||
qty: qty,
|
||||
is_additional_transfer_entry: is_additional_transfer_entry || 0,
|
||||
})
|
||||
.then((stock_entry) => {
|
||||
frappe.model.sync(stock_entry);
|
||||
|
||||
@@ -19,13 +19,15 @@
|
||||
"column_break1",
|
||||
"company",
|
||||
"qty",
|
||||
"material_transferred_for_manufacturing",
|
||||
"produced_qty",
|
||||
"disassembled_qty",
|
||||
"process_loss_qty",
|
||||
"project",
|
||||
"track_semi_finished_goods",
|
||||
"reserve_stock",
|
||||
"column_break_agjv",
|
||||
"material_transferred_for_manufacturing",
|
||||
"additional_transferred_qty",
|
||||
"produced_qty",
|
||||
"disassembled_qty",
|
||||
"process_loss_qty",
|
||||
"warehouses",
|
||||
"source_warehouse",
|
||||
"wip_warehouse",
|
||||
@@ -609,6 +611,17 @@
|
||||
"label": "MPS",
|
||||
"options": "Master Production Schedule",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_agjv",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "additional_transferred_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Additional Transferred Qty",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"grid_page_length": 50,
|
||||
@@ -617,7 +630,7 @@
|
||||
"image_field": "image",
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2025-08-28 11:01:48.719824",
|
||||
"modified": "2025-09-29 15:57:47.022616",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Work Order",
|
||||
|
||||
@@ -82,6 +82,7 @@ class WorkOrder(Document):
|
||||
actual_operating_cost: DF.Currency
|
||||
actual_start_date: DF.Datetime | None
|
||||
additional_operating_cost: DF.Currency
|
||||
additional_transferred_qty: DF.Float
|
||||
allow_alternative_item: DF.Check
|
||||
amended_from: DF.Link | None
|
||||
batch_size: DF.Float
|
||||
@@ -481,6 +482,7 @@ class WorkOrder(Document):
|
||||
for purpose, fieldname in (
|
||||
("Manufacture", "produced_qty"),
|
||||
("Material Transfer for Manufacture", "material_transferred_for_manufacturing"),
|
||||
("Material Transfer for Manufacture", "additional_transferred_qty"),
|
||||
):
|
||||
if (
|
||||
purpose == "Material Transfer for Manufacture"
|
||||
@@ -489,7 +491,7 @@ class WorkOrder(Document):
|
||||
):
|
||||
continue
|
||||
|
||||
qty = self.get_transferred_or_manufactured_qty(purpose)
|
||||
qty = self.get_transferred_or_manufactured_qty(purpose, fieldname)
|
||||
|
||||
if not allowance_percentage and purpose == "Material Transfer for Manufacture":
|
||||
allowance_percentage = flt(
|
||||
@@ -519,6 +521,30 @@ class WorkOrder(Document):
|
||||
self.set_produced_qty_for_sub_assembly_item()
|
||||
self.update_production_plan_status()
|
||||
|
||||
if self.additional_transferred_qty:
|
||||
self.validate_additional_transferred_qty()
|
||||
|
||||
def validate_additional_transferred_qty(self):
|
||||
transfer_extra_materials_percentage = frappe.db.get_single_value(
|
||||
"Manufacturing Settings", "transfer_extra_materials_percentage"
|
||||
)
|
||||
|
||||
allowed_qty = flt(self.qty) + flt(flt(self.qty) * flt(transfer_extra_materials_percentage) / 100)
|
||||
|
||||
actual_qty = flt(self.material_transferred_for_manufacturing) + flt(self.additional_transferred_qty)
|
||||
|
||||
precision = frappe.get_precision("Work Order", "qty")
|
||||
if flt(allowed_qty - actual_qty, precision) < 0:
|
||||
frappe.throw(
|
||||
_(
|
||||
"""Additional Transferred Qty {0}
|
||||
cannot be greater than {1}.
|
||||
To fix this, increase the percentage value
|
||||
of the field 'Transfer Extra Raw Materials to WIP'
|
||||
in Manufacturing Settings."""
|
||||
).format(actual_qty, allowed_qty),
|
||||
)
|
||||
|
||||
def update_disassembled_qty(self, qty, is_cancel=False):
|
||||
if is_cancel:
|
||||
self.disassembled_qty = max(0, self.disassembled_qty - qty)
|
||||
@@ -531,7 +557,7 @@ class WorkOrder(Document):
|
||||
|
||||
self.db_set("disassembled_qty", self.disassembled_qty)
|
||||
|
||||
def get_transferred_or_manufactured_qty(self, purpose):
|
||||
def get_transferred_or_manufactured_qty(self, purpose, fieldname):
|
||||
table = frappe.qb.DocType("Stock Entry")
|
||||
query = frappe.qb.from_(table).where(
|
||||
(table.work_order == self.name) & (table.docstatus == 1) & (table.purpose == purpose)
|
||||
@@ -542,6 +568,10 @@ class WorkOrder(Document):
|
||||
else:
|
||||
query = query.select(Sum(table.fg_completed_qty))
|
||||
|
||||
query = query.where(
|
||||
table.is_additional_transfer_entry == cint(fieldname == "additional_transferred_qty")
|
||||
)
|
||||
|
||||
return flt(query.run()[0][0])
|
||||
|
||||
def set_process_loss_qty(self):
|
||||
@@ -1991,7 +2021,9 @@ def set_work_order_ops(name):
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_stock_entry(work_order_id, purpose, qty=None, target_warehouse=None):
|
||||
def make_stock_entry(
|
||||
work_order_id, purpose, qty=None, target_warehouse=None, is_additional_transfer_entry=False
|
||||
):
|
||||
work_order = frappe.get_doc("Work Order", work_order_id)
|
||||
if not frappe.db.get_value("Warehouse", work_order.wip_warehouse, "is_group"):
|
||||
wip_warehouse = work_order.wip_warehouse
|
||||
@@ -2030,6 +2062,7 @@ def make_stock_entry(work_order_id, purpose, qty=None, target_warehouse=None):
|
||||
stock_entry.to_warehouse = target_warehouse or work_order.source_warehouse
|
||||
|
||||
stock_entry.set_stock_entry_type()
|
||||
stock_entry.is_additional_transfer_entry = is_additional_transfer_entry
|
||||
stock_entry.get_items(qty, work_order.production_item)
|
||||
|
||||
if purpose != "Disassemble":
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
"set_posting_time",
|
||||
"inspection_required",
|
||||
"apply_putaway_rule",
|
||||
"is_additional_transfer_entry",
|
||||
"bom_info_section",
|
||||
"from_bom",
|
||||
"use_multi_level_bom",
|
||||
@@ -699,6 +700,15 @@
|
||||
"fieldtype": "Data",
|
||||
"is_virtual": 1,
|
||||
"label": "Last Scanned Warehouse"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "eval:doc.purpose == \"Material Transfer for Manufacture\"",
|
||||
"fieldname": "is_additional_transfer_entry",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 1,
|
||||
"label": "Is Additional Transfer Entry",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-file-text",
|
||||
@@ -706,7 +716,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2025-08-04 19:21:03.338958",
|
||||
"modified": "2025-09-29 15:56:21.344296",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Stock Entry",
|
||||
|
||||
@@ -110,6 +110,7 @@ class StockEntry(StockController):
|
||||
from_bom: DF.Check
|
||||
from_warehouse: DF.Link | None
|
||||
inspection_required: DF.Check
|
||||
is_additional_transfer_entry: DF.Check
|
||||
is_opening: DF.Literal["No", "Yes"]
|
||||
is_return: DF.Check
|
||||
items: DF.Table[StockEntryDetail]
|
||||
|
||||
Reference in New Issue
Block a user