fix: added process loss in job card
This commit is contained in:
parent
9e650a004a
commit
e9a6191af9
@ -83,7 +83,7 @@ frappe.ui.form.on('Job Card', {
|
|||||||
// and if stock mvt for WIP is required
|
// and if stock mvt for WIP is required
|
||||||
if (frm.doc.work_order) {
|
if (frm.doc.work_order) {
|
||||||
frappe.db.get_value('Work Order', frm.doc.work_order, ['skip_transfer', 'status'], (result) => {
|
frappe.db.get_value('Work Order', frm.doc.work_order, ['skip_transfer', 'status'], (result) => {
|
||||||
if (result.skip_transfer === 1 || result.status == 'In Process' || frm.doc.transferred_qty > 0) {
|
if (result.skip_transfer === 1 || result.status == 'In Process' || frm.doc.transferred_qty > 0 || !frm.doc.items.length) {
|
||||||
frm.trigger("prepare_timer_buttons");
|
frm.trigger("prepare_timer_buttons");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -411,6 +411,16 @@ frappe.ui.form.on('Job Card', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (frm.doc.total_completed_qty && frm.doc.for_quantity > frm.doc.total_completed_qty) {
|
||||||
|
let flt_precision = precision('for_quantity', frm.doc);
|
||||||
|
let process_loss_qty = (
|
||||||
|
flt(frm.doc.for_quantity, flt_precision)
|
||||||
|
- flt(frm.doc.total_completed_qty, flt_precision)
|
||||||
|
);
|
||||||
|
|
||||||
|
frm.set_value('process_loss_qty', process_loss_qty);
|
||||||
|
}
|
||||||
|
|
||||||
refresh_field("total_completed_qty");
|
refresh_field("total_completed_qty");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
"time_logs",
|
"time_logs",
|
||||||
"section_break_13",
|
"section_break_13",
|
||||||
"total_completed_qty",
|
"total_completed_qty",
|
||||||
|
"process_loss_qty",
|
||||||
"column_break_15",
|
"column_break_15",
|
||||||
"total_time_in_mins",
|
"total_time_in_mins",
|
||||||
"section_break_8",
|
"section_break_8",
|
||||||
@ -448,11 +449,17 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Serial and Batch Bundle",
|
"options": "Serial and Batch Bundle",
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "process_loss_qty",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"label": "Process Loss Qty",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-05-23 09:56:43.826602",
|
"modified": "2023-06-09 12:04:55.534264",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Job Card",
|
"name": "Job Card",
|
||||||
|
@ -161,7 +161,7 @@ class JobCard(Document):
|
|||||||
self.total_completed_qty = flt(self.total_completed_qty, self.precision("total_completed_qty"))
|
self.total_completed_qty = flt(self.total_completed_qty, self.precision("total_completed_qty"))
|
||||||
|
|
||||||
for row in self.sub_operations:
|
for row in self.sub_operations:
|
||||||
self.total_completed_qty += row.completed_qty
|
self.c += row.completed_qty
|
||||||
|
|
||||||
def get_overlap_for(self, args, check_next_available_slot=False):
|
def get_overlap_for(self, args, check_next_available_slot=False):
|
||||||
production_capacity = 1
|
production_capacity = 1
|
||||||
@ -451,6 +451,9 @@ class JobCard(Document):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def before_save(self):
|
||||||
|
self.set_process_loss()
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
self.validate_transfer_qty()
|
self.validate_transfer_qty()
|
||||||
self.validate_job_card()
|
self.validate_job_card()
|
||||||
@ -487,19 +490,35 @@ class JobCard(Document):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.for_quantity and self.total_completed_qty != self.for_quantity:
|
precision = self.precision("total_completed_qty")
|
||||||
|
total_completed_qty = flt(
|
||||||
|
flt(self.total_completed_qty, precision) + flt(self.process_loss_qty, precision)
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.for_quantity and flt(total_completed_qty, precision) != flt(
|
||||||
|
self.for_quantity, precision
|
||||||
|
):
|
||||||
total_completed_qty = bold(_("Total Completed Qty"))
|
total_completed_qty = bold(_("Total Completed Qty"))
|
||||||
qty_to_manufacture = bold(_("Qty to Manufacture"))
|
qty_to_manufacture = bold(_("Qty to Manufacture"))
|
||||||
|
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
_("The {0} ({1}) must be equal to {2} ({3})").format(
|
_("The {0} ({1}) must be equal to {2} ({3})").format(
|
||||||
total_completed_qty,
|
total_completed_qty,
|
||||||
bold(self.total_completed_qty),
|
bold(flt(total_completed_qty, precision)),
|
||||||
qty_to_manufacture,
|
qty_to_manufacture,
|
||||||
bold(self.for_quantity),
|
bold(self.for_quantity),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def set_process_loss(self):
|
||||||
|
precision = self.precision("total_completed_qty")
|
||||||
|
|
||||||
|
self.process_loss_qty = 0.0
|
||||||
|
if self.total_completed_qty and self.for_quantity > self.total_completed_qty:
|
||||||
|
self.process_loss_qty = flt(self.for_quantity, precision) - flt(
|
||||||
|
self.total_completed_qty, precision
|
||||||
|
)
|
||||||
|
|
||||||
def update_work_order(self):
|
def update_work_order(self):
|
||||||
if not self.work_order:
|
if not self.work_order:
|
||||||
return
|
return
|
||||||
@ -511,7 +530,7 @@ class JobCard(Document):
|
|||||||
):
|
):
|
||||||
return
|
return
|
||||||
|
|
||||||
for_quantity, time_in_mins = 0, 0
|
for_quantity, time_in_mins, process_loss_qty = 0, 0, 0
|
||||||
from_time_list, to_time_list = [], []
|
from_time_list, to_time_list = [], []
|
||||||
|
|
||||||
field = "operation_id"
|
field = "operation_id"
|
||||||
@ -519,6 +538,7 @@ class JobCard(Document):
|
|||||||
if data and len(data) > 0:
|
if data and len(data) > 0:
|
||||||
for_quantity = flt(data[0].completed_qty)
|
for_quantity = flt(data[0].completed_qty)
|
||||||
time_in_mins = flt(data[0].time_in_mins)
|
time_in_mins = flt(data[0].time_in_mins)
|
||||||
|
process_loss_qty = flt(data[0].process_loss_qty)
|
||||||
|
|
||||||
wo = frappe.get_doc("Work Order", self.work_order)
|
wo = frappe.get_doc("Work Order", self.work_order)
|
||||||
|
|
||||||
@ -526,8 +546,8 @@ class JobCard(Document):
|
|||||||
self.update_corrective_in_work_order(wo)
|
self.update_corrective_in_work_order(wo)
|
||||||
|
|
||||||
elif self.operation_id:
|
elif self.operation_id:
|
||||||
self.validate_produced_quantity(for_quantity, wo)
|
self.validate_produced_quantity(for_quantity, process_loss_qty, wo)
|
||||||
self.update_work_order_data(for_quantity, time_in_mins, wo)
|
self.update_work_order_data(for_quantity, process_loss_qty, time_in_mins, wo)
|
||||||
|
|
||||||
def update_corrective_in_work_order(self, wo):
|
def update_corrective_in_work_order(self, wo):
|
||||||
wo.corrective_operation_cost = 0.0
|
wo.corrective_operation_cost = 0.0
|
||||||
@ -542,11 +562,11 @@ class JobCard(Document):
|
|||||||
wo.flags.ignore_validate_update_after_submit = True
|
wo.flags.ignore_validate_update_after_submit = True
|
||||||
wo.save()
|
wo.save()
|
||||||
|
|
||||||
def validate_produced_quantity(self, for_quantity, wo):
|
def validate_produced_quantity(self, for_quantity, process_loss_qty, wo):
|
||||||
if self.docstatus < 2:
|
if self.docstatus < 2:
|
||||||
return
|
return
|
||||||
|
|
||||||
if wo.produced_qty > for_quantity:
|
if wo.produced_qty > for_quantity + process_loss_qty:
|
||||||
first_part_msg = _(
|
first_part_msg = _(
|
||||||
"The {0} {1} is used to calculate the valuation cost for the finished good {2}."
|
"The {0} {1} is used to calculate the valuation cost for the finished good {2}."
|
||||||
).format(
|
).format(
|
||||||
@ -561,7 +581,7 @@ class JobCard(Document):
|
|||||||
_("{0} {1}").format(first_part_msg, second_part_msg), JobCardCancelError, title=_("Error")
|
_("{0} {1}").format(first_part_msg, second_part_msg), JobCardCancelError, title=_("Error")
|
||||||
)
|
)
|
||||||
|
|
||||||
def update_work_order_data(self, for_quantity, time_in_mins, wo):
|
def update_work_order_data(self, for_quantity, process_loss_qty, time_in_mins, wo):
|
||||||
workstation_hour_rate = frappe.get_value("Workstation", self.workstation, "hour_rate")
|
workstation_hour_rate = frappe.get_value("Workstation", self.workstation, "hour_rate")
|
||||||
jc = frappe.qb.DocType("Job Card")
|
jc = frappe.qb.DocType("Job Card")
|
||||||
jctl = frappe.qb.DocType("Job Card Time Log")
|
jctl = frappe.qb.DocType("Job Card Time Log")
|
||||||
@ -582,6 +602,7 @@ class JobCard(Document):
|
|||||||
for data in wo.operations:
|
for data in wo.operations:
|
||||||
if data.get("name") == self.operation_id:
|
if data.get("name") == self.operation_id:
|
||||||
data.completed_qty = for_quantity
|
data.completed_qty = for_quantity
|
||||||
|
data.process_loss_qty = process_loss_qty
|
||||||
data.actual_operation_time = time_in_mins
|
data.actual_operation_time = time_in_mins
|
||||||
data.actual_start_time = time_data[0].start_time if time_data else None
|
data.actual_start_time = time_data[0].start_time if time_data else None
|
||||||
data.actual_end_time = time_data[0].end_time if time_data else None
|
data.actual_end_time = time_data[0].end_time if time_data else None
|
||||||
@ -599,7 +620,11 @@ class JobCard(Document):
|
|||||||
def get_current_operation_data(self):
|
def get_current_operation_data(self):
|
||||||
return frappe.get_all(
|
return frappe.get_all(
|
||||||
"Job Card",
|
"Job Card",
|
||||||
fields=["sum(total_time_in_mins) as time_in_mins", "sum(total_completed_qty) as completed_qty"],
|
fields=[
|
||||||
|
"sum(total_time_in_mins) as time_in_mins",
|
||||||
|
"sum(total_completed_qty) as completed_qty",
|
||||||
|
"sum(process_loss_qty) as process_loss_qty",
|
||||||
|
],
|
||||||
filters={
|
filters={
|
||||||
"docstatus": 1,
|
"docstatus": 1,
|
||||||
"work_order": self.work_order,
|
"work_order": self.work_order,
|
||||||
@ -777,7 +802,7 @@ class JobCard(Document):
|
|||||||
|
|
||||||
data = frappe.get_all(
|
data = frappe.get_all(
|
||||||
"Work Order Operation",
|
"Work Order Operation",
|
||||||
fields=["operation", "status", "completed_qty"],
|
fields=["operation", "status", "completed_qty", "sequence_id"],
|
||||||
filters={"docstatus": 1, "parent": self.work_order, "sequence_id": ("<", self.sequence_id)},
|
filters={"docstatus": 1, "parent": self.work_order, "sequence_id": ("<", self.sequence_id)},
|
||||||
order_by="sequence_id, idx",
|
order_by="sequence_id, idx",
|
||||||
)
|
)
|
||||||
@ -795,6 +820,16 @@ class JobCard(Document):
|
|||||||
OperationSequenceError,
|
OperationSequenceError,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if row.completed_qty < current_operation_qty:
|
||||||
|
msg = f"""The completed quantity {bold(current_operation_qty)}
|
||||||
|
of an operation {bold(self.operation)} cannot be greater
|
||||||
|
than the completed quantity {bold(row.completed_qty)}
|
||||||
|
of a previous operation
|
||||||
|
{bold(row.operation)}.
|
||||||
|
"""
|
||||||
|
|
||||||
|
frappe.throw(_(msg))
|
||||||
|
|
||||||
def validate_work_order(self):
|
def validate_work_order(self):
|
||||||
if self.is_work_order_closed():
|
if self.is_work_order_closed():
|
||||||
frappe.throw(_("You can't make any changes to Job Card since Work Order is closed."))
|
frappe.throw(_("You can't make any changes to Job Card since Work Order is closed."))
|
||||||
|
@ -139,7 +139,7 @@ frappe.ui.form.on("Work Order", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (frm.doc.status != "Closed") {
|
if (frm.doc.status != "Closed") {
|
||||||
if (frm.doc.docstatus === 1
|
if (frm.doc.docstatus === 1 && frm.doc.status !== "Completed"
|
||||||
&& frm.doc.operations && frm.doc.operations.length) {
|
&& frm.doc.operations && frm.doc.operations.length) {
|
||||||
|
|
||||||
const not_completed = frm.doc.operations.filter(d => {
|
const not_completed = frm.doc.operations.filter(d => {
|
||||||
@ -256,6 +256,12 @@ frappe.ui.form.on("Work Order", {
|
|||||||
label: __('Batch Size'),
|
label: __('Batch Size'),
|
||||||
read_only: 1
|
read_only: 1
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
fieldtype: 'Int',
|
||||||
|
fieldname: 'sequence_id',
|
||||||
|
label: __('Sequence Id'),
|
||||||
|
read_only: 1
|
||||||
|
},
|
||||||
],
|
],
|
||||||
data: operations_data,
|
data: operations_data,
|
||||||
in_place_edit: true,
|
in_place_edit: true,
|
||||||
@ -280,8 +286,8 @@ frappe.ui.form.on("Work Order", {
|
|||||||
|
|
||||||
var pending_qty = 0;
|
var pending_qty = 0;
|
||||||
frm.doc.operations.forEach(data => {
|
frm.doc.operations.forEach(data => {
|
||||||
if(data.completed_qty != frm.doc.qty) {
|
if(data.completed_qty + data.process_loss_qty != frm.doc.qty) {
|
||||||
pending_qty = frm.doc.qty - flt(data.completed_qty);
|
pending_qty = frm.doc.qty - flt(data.completed_qty) - flt(data.process_loss_qty);
|
||||||
|
|
||||||
if (pending_qty) {
|
if (pending_qty) {
|
||||||
dialog.fields_dict.operations.df.data.push({
|
dialog.fields_dict.operations.df.data.push({
|
||||||
@ -290,7 +296,8 @@ frappe.ui.form.on("Work Order", {
|
|||||||
'workstation': data.workstation,
|
'workstation': data.workstation,
|
||||||
'batch_size': data.batch_size,
|
'batch_size': data.batch_size,
|
||||||
'qty': pending_qty,
|
'qty': pending_qty,
|
||||||
'pending_qty': pending_qty
|
'pending_qty': pending_qty,
|
||||||
|
'sequence_id': data.sequence_id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,8 +46,8 @@
|
|||||||
"required_items_section",
|
"required_items_section",
|
||||||
"materials_and_operations_tab",
|
"materials_and_operations_tab",
|
||||||
"operations_section",
|
"operations_section",
|
||||||
"operations",
|
|
||||||
"transfer_material_against",
|
"transfer_material_against",
|
||||||
|
"operations",
|
||||||
"time",
|
"time",
|
||||||
"planned_start_date",
|
"planned_start_date",
|
||||||
"planned_end_date",
|
"planned_end_date",
|
||||||
@ -330,7 +330,6 @@
|
|||||||
"label": "Expected Delivery Date"
|
"label": "Expected Delivery Date"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
|
||||||
"fieldname": "operations_section",
|
"fieldname": "operations_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Operations",
|
"label": "Operations",
|
||||||
@ -591,7 +590,7 @@
|
|||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-04-06 12:35:12.149827",
|
"modified": "2023-06-09 13:20:09.154362",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Work Order",
|
"name": "Work Order",
|
||||||
|
@ -245,7 +245,9 @@ class WorkOrder(Document):
|
|||||||
status = "Not Started"
|
status = "Not Started"
|
||||||
if flt(self.material_transferred_for_manufacturing) > 0:
|
if flt(self.material_transferred_for_manufacturing) > 0:
|
||||||
status = "In Process"
|
status = "In Process"
|
||||||
if flt(self.produced_qty) >= flt(self.qty):
|
|
||||||
|
total_qty = flt(self.produced_qty) + flt(self.process_loss_qty)
|
||||||
|
if flt(total_qty) >= flt(self.qty):
|
||||||
status = "Completed"
|
status = "Completed"
|
||||||
else:
|
else:
|
||||||
status = "Cancelled"
|
status = "Cancelled"
|
||||||
@ -761,13 +763,15 @@ class WorkOrder(Document):
|
|||||||
max_allowed_qty_for_wo = flt(self.qty) + (allowance_percentage / 100 * flt(self.qty))
|
max_allowed_qty_for_wo = flt(self.qty) + (allowance_percentage / 100 * flt(self.qty))
|
||||||
|
|
||||||
for d in self.get("operations"):
|
for d in self.get("operations"):
|
||||||
if not d.completed_qty:
|
precision = d.precision("completed_qty")
|
||||||
|
qty = flt(d.completed_qty, precision) + flt(d.process_loss_qty, precision)
|
||||||
|
if not qty:
|
||||||
d.status = "Pending"
|
d.status = "Pending"
|
||||||
elif flt(d.completed_qty) < flt(self.qty):
|
elif flt(qty) < flt(self.qty):
|
||||||
d.status = "Work in Progress"
|
d.status = "Work in Progress"
|
||||||
elif flt(d.completed_qty) == flt(self.qty):
|
elif flt(qty) == flt(self.qty):
|
||||||
d.status = "Completed"
|
d.status = "Completed"
|
||||||
elif flt(d.completed_qty) <= max_allowed_qty_for_wo:
|
elif flt(qty) <= max_allowed_qty_for_wo:
|
||||||
d.status = "Completed"
|
d.status = "Completed"
|
||||||
else:
|
else:
|
||||||
frappe.throw(_("Completed Qty cannot be greater than 'Qty to Manufacture'"))
|
frappe.throw(_("Completed Qty cannot be greater than 'Qty to Manufacture'"))
|
||||||
|
@ -2,12 +2,14 @@
|
|||||||
"actions": [],
|
"actions": [],
|
||||||
"creation": "2014-10-16 14:35:41.950175",
|
"creation": "2014-10-16 14:35:41.950175",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"details",
|
"details",
|
||||||
"operation",
|
"operation",
|
||||||
"status",
|
"status",
|
||||||
"completed_qty",
|
"completed_qty",
|
||||||
|
"process_loss_qty",
|
||||||
"column_break_4",
|
"column_break_4",
|
||||||
"bom",
|
"bom",
|
||||||
"workstation_type",
|
"workstation_type",
|
||||||
@ -36,6 +38,7 @@
|
|||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"columns": 2,
|
||||||
"fieldname": "operation",
|
"fieldname": "operation",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@ -46,6 +49,7 @@
|
|||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"columns": 2,
|
||||||
"fieldname": "bom",
|
"fieldname": "bom",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@ -62,7 +66,7 @@
|
|||||||
"oldfieldtype": "Text"
|
"oldfieldtype": "Text"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"columns": 1,
|
"columns": 2,
|
||||||
"description": "Operation completed for how many finished goods?",
|
"description": "Operation completed for how many finished goods?",
|
||||||
"fieldname": "completed_qty",
|
"fieldname": "completed_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
@ -80,6 +84,7 @@
|
|||||||
"options": "Pending\nWork in Progress\nCompleted"
|
"options": "Pending\nWork in Progress\nCompleted"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"columns": 1,
|
||||||
"fieldname": "workstation",
|
"fieldname": "workstation",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@ -115,7 +120,7 @@
|
|||||||
"fieldname": "time_in_mins",
|
"fieldname": "time_in_mins",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Operation Time",
|
"label": "Time",
|
||||||
"oldfieldname": "time_in_mins",
|
"oldfieldname": "time_in_mins",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
@ -203,12 +208,21 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Workstation Type",
|
"label": "Workstation Type",
|
||||||
"options": "Workstation Type"
|
"options": "Workstation Type"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"columns": 2,
|
||||||
|
"fieldname": "process_loss_qty",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Process Loss Qty",
|
||||||
|
"no_copy": 1,
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-11-09 01:37:56.563068",
|
"modified": "2023-06-09 14:03:01.612909",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Work Order Operation",
|
"name": "Work Order Operation",
|
||||||
|
@ -656,6 +656,21 @@ frappe.ui.form.on('Stock Entry', {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
process_loss_qty(frm) {
|
||||||
|
if (frm.doc.process_loss_qty) {
|
||||||
|
frm.doc.process_loss_percentage = flt(frm.doc.process_loss_qty / frm.doc.fg_completed_qty * 100, precision("process_loss_qty", frm.doc));
|
||||||
|
refresh_field("process_loss_percentage");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
process_loss_percentage(frm) {
|
||||||
|
debugger
|
||||||
|
if (frm.doc.process_loss_percentage) {
|
||||||
|
frm.doc.process_loss_qty = flt((frm.doc.fg_completed_qty * frm.doc.process_loss_percentage) / 100 , precision("process_loss_qty", frm.doc));
|
||||||
|
refresh_field("process_loss_qty");
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
frappe.ui.form.on('Stock Entry Detail', {
|
frappe.ui.form.on('Stock Entry Detail', {
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
"company",
|
"company",
|
||||||
"posting_date",
|
"posting_date",
|
||||||
"posting_time",
|
"posting_time",
|
||||||
|
"column_break_eaoa",
|
||||||
"set_posting_time",
|
"set_posting_time",
|
||||||
"inspection_required",
|
"inspection_required",
|
||||||
"apply_putaway_rule",
|
"apply_putaway_rule",
|
||||||
@ -640,16 +641,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
|
"depends_on": "eval: doc.fg_completed_qty > 0 && in_list([\"Manufacture\", \"Repack\"], doc.purpose)",
|
||||||
"fieldname": "section_break_7qsm",
|
"fieldname": "section_break_7qsm",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Process Loss"
|
"label": "Process Loss"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "process_loss_percentage",
|
"depends_on": "eval: doc.fg_completed_qty > 0 && in_list([\"Manufacture\", \"Repack\"], doc.purpose)",
|
||||||
"fieldname": "process_loss_qty",
|
"fieldname": "process_loss_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Process Loss Qty",
|
"label": "Process Loss Qty"
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_e92r",
|
"fieldname": "column_break_e92r",
|
||||||
@ -657,8 +658,6 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.from_bom && doc.fg_completed_qty",
|
"depends_on": "eval:doc.from_bom && doc.fg_completed_qty",
|
||||||
"fetch_from": "bom_no.process_loss_percentage",
|
|
||||||
"fetch_if_empty": 1,
|
|
||||||
"fieldname": "process_loss_percentage",
|
"fieldname": "process_loss_percentage",
|
||||||
"fieldtype": "Percent",
|
"fieldtype": "Percent",
|
||||||
"label": "% Process Loss"
|
"label": "% Process Loss"
|
||||||
@ -667,6 +666,10 @@
|
|||||||
"fieldname": "items_section",
|
"fieldname": "items_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Items"
|
"label": "Items"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_eaoa",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
@ -674,7 +677,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-04-06 12:42:56.673180",
|
"modified": "2023-06-09 15:46:28.418339",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Stock Entry",
|
"name": "Stock Entry",
|
||||||
|
@ -442,13 +442,16 @@ class StockEntry(StockController):
|
|||||||
if self.purpose == "Manufacture" and self.work_order:
|
if self.purpose == "Manufacture" and self.work_order:
|
||||||
for d in self.items:
|
for d in self.items:
|
||||||
if d.is_finished_item:
|
if d.is_finished_item:
|
||||||
|
if self.process_loss_qty:
|
||||||
|
d.qty = self.fg_completed_qty - self.process_loss_qty
|
||||||
|
|
||||||
item_wise_qty.setdefault(d.item_code, []).append(d.qty)
|
item_wise_qty.setdefault(d.item_code, []).append(d.qty)
|
||||||
|
|
||||||
precision = frappe.get_precision("Stock Entry Detail", "qty")
|
precision = frappe.get_precision("Stock Entry Detail", "qty")
|
||||||
for item_code, qty_list in item_wise_qty.items():
|
for item_code, qty_list in item_wise_qty.items():
|
||||||
total = flt(sum(qty_list), precision)
|
total = flt(sum(qty_list), precision)
|
||||||
|
|
||||||
if (self.fg_completed_qty - total) > 0:
|
if (self.fg_completed_qty - total) > 0 and not self.process_loss_qty:
|
||||||
self.process_loss_qty = flt(self.fg_completed_qty - total, precision)
|
self.process_loss_qty = flt(self.fg_completed_qty - total, precision)
|
||||||
self.process_loss_percentage = flt(self.process_loss_qty * 100 / self.fg_completed_qty)
|
self.process_loss_percentage = flt(self.process_loss_qty * 100 / self.fg_completed_qty)
|
||||||
|
|
||||||
@ -1640,16 +1643,36 @@ class StockEntry(StockController):
|
|||||||
if self.purpose not in ("Manufacture", "Repack"):
|
if self.purpose not in ("Manufacture", "Repack"):
|
||||||
return
|
return
|
||||||
|
|
||||||
self.process_loss_qty = 0.0
|
precision = self.precision("process_loss_qty")
|
||||||
if not self.process_loss_percentage:
|
if self.work_order:
|
||||||
|
data = frappe.get_all(
|
||||||
|
"Work Order Operation",
|
||||||
|
filters={"parent": self.work_order},
|
||||||
|
fields=["max(process_loss_qty) as process_loss_qty"],
|
||||||
|
)
|
||||||
|
|
||||||
|
if data and data[0].process_loss_qty is not None:
|
||||||
|
process_loss_qty = data[0].process_loss_qty
|
||||||
|
if flt(self.process_loss_qty, precision) != flt(process_loss_qty, precision):
|
||||||
|
self.process_loss_qty = flt(process_loss_qty, precision)
|
||||||
|
|
||||||
|
frappe.msgprint(
|
||||||
|
_("The Process Loss Qty has reset as per job cards Process Loss Qty"), alert=True
|
||||||
|
)
|
||||||
|
|
||||||
|
if not self.process_loss_percentage and not self.process_loss_qty:
|
||||||
self.process_loss_percentage = frappe.get_cached_value(
|
self.process_loss_percentage = frappe.get_cached_value(
|
||||||
"BOM", self.bom_no, "process_loss_percentage"
|
"BOM", self.bom_no, "process_loss_percentage"
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.process_loss_percentage:
|
if self.process_loss_percentage and not self.process_loss_qty:
|
||||||
self.process_loss_qty = flt(
|
self.process_loss_qty = flt(
|
||||||
(flt(self.fg_completed_qty) * flt(self.process_loss_percentage)) / 100
|
(flt(self.fg_completed_qty) * flt(self.process_loss_percentage)) / 100
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
self.process_loss_percentage = flt(
|
||||||
|
(flt(self.process_loss_qty) / flt(self.fg_completed_qty)) * 100
|
||||||
|
)
|
||||||
|
|
||||||
def set_work_order_details(self):
|
def set_work_order_details(self):
|
||||||
if not getattr(self, "pro_doc", None):
|
if not getattr(self, "pro_doc", None):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user