[refactor] Material Transfer for Manufacture
This commit is contained in:
parent
46e03eadca
commit
06072c1e51
@ -7,7 +7,7 @@ $.extend(cur_frm.cscript, {
|
|||||||
cfn_set_fields(doc, dt, dn);
|
cfn_set_fields(doc, dt, dn);
|
||||||
|
|
||||||
this.frm.add_fetch("sales_order", "delivery_date", "expected_delivery_date");
|
this.frm.add_fetch("sales_order", "delivery_date", "expected_delivery_date");
|
||||||
|
|
||||||
if(doc.__islocal) {
|
if(doc.__islocal) {
|
||||||
cur_frm.set_value({
|
cur_frm.set_value({
|
||||||
"actual_start_date": "",
|
"actual_start_date": "",
|
||||||
@ -70,7 +70,7 @@ $.extend(cur_frm.cscript, {
|
|||||||
method: "set_production_order_operations"
|
method: "set_production_order_operations"
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
planned_start_date: function() {
|
planned_start_date: function() {
|
||||||
return this.frm.call({
|
return this.frm.call({
|
||||||
doc: this.frm.doc,
|
doc: this.frm.doc,
|
||||||
@ -144,7 +144,7 @@ cur_frm.cscript['Unstop Production Order'] = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript['Transfer Raw Materials'] = function() {
|
cur_frm.cscript['Transfer Raw Materials'] = function() {
|
||||||
cur_frm.cscript.make_se('Material Transfer');
|
cur_frm.cscript.make_se('Material Transfer for Manufacture');
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript['Update Finished Goods'] = function() {
|
cur_frm.cscript['Update Finished Goods'] = function() {
|
||||||
|
@ -210,7 +210,7 @@ class ProductionOrder(Document):
|
|||||||
d.status = "Completed"
|
d.status = "Completed"
|
||||||
else:
|
else:
|
||||||
frappe.throw(_("Completed Qty can not be greater than 'Qty to Manufacture'"))
|
frappe.throw(_("Completed Qty can not be greater than 'Qty to Manufacture'"))
|
||||||
|
|
||||||
def set_actual_dates(self):
|
def set_actual_dates(self):
|
||||||
if self.get("operations"):
|
if self.get("operations"):
|
||||||
actual_date = frappe.db.sql("""select min(actual_start_time) as start_date, max(actual_end_time) as end_date from `tabProduction Order Operation`
|
actual_date = frappe.db.sql("""select min(actual_start_time) as start_date, max(actual_end_time) as end_date from `tabProduction Order Operation`
|
||||||
@ -220,11 +220,11 @@ class ProductionOrder(Document):
|
|||||||
else:
|
else:
|
||||||
self.actual_start_date = None
|
self.actual_start_date = None
|
||||||
self.actual_end_date = None
|
self.actual_end_date = None
|
||||||
|
|
||||||
def validate_delivery_date(self):
|
def validate_delivery_date(self):
|
||||||
if self.planned_start_date and self.expected_delivery_date and getdate(self.expected_delivery_date) < getdate(self.planned_start_date):
|
if self.planned_start_date and self.expected_delivery_date and getdate(self.expected_delivery_date) < getdate(self.planned_start_date):
|
||||||
frappe.throw(_("Expected Delivery Date cannot be greater than Planned Start Date"))
|
frappe.throw(_("Expected Delivery Date cannot be greater than Planned Start Date"))
|
||||||
|
|
||||||
if self.planned_end_date and self.expected_delivery_date and getdate(self.expected_delivery_date) < getdate(self.planned_end_date):
|
if self.planned_end_date and self.expected_delivery_date and getdate(self.expected_delivery_date) < getdate(self.planned_end_date):
|
||||||
frappe.msgprint(_("Production might not be able to finish by the Expected Delivery Date."))
|
frappe.msgprint(_("Production might not be able to finish by the Expected Delivery Date."))
|
||||||
|
|
||||||
@ -254,7 +254,7 @@ def make_stock_entry(production_order_id, purpose, qty=None):
|
|||||||
stock_entry.use_multi_level_bom = production_order.use_multi_level_bom
|
stock_entry.use_multi_level_bom = production_order.use_multi_level_bom
|
||||||
stock_entry.fg_completed_qty = qty or (flt(production_order.qty) - flt(production_order.produced_qty))
|
stock_entry.fg_completed_qty = qty or (flt(production_order.qty) - flt(production_order.produced_qty))
|
||||||
|
|
||||||
if purpose=="Material Transfer":
|
if purpose=="Material Transfer for Manufacture":
|
||||||
stock_entry.to_warehouse = production_order.wip_warehouse
|
stock_entry.to_warehouse = production_order.wip_warehouse
|
||||||
else:
|
else:
|
||||||
stock_entry.from_warehouse = production_order.wip_warehouse
|
stock_entry.from_warehouse = production_order.wip_warehouse
|
||||||
|
@ -111,3 +111,4 @@ erpnext.patches.v5_0.update_item_name_in_bom
|
|||||||
execute:frappe.reload_doc('crm', 'doctype', 'lead')
|
execute:frappe.reload_doc('crm', 'doctype', 'lead')
|
||||||
execute:frappe.reload_doc('crm', 'doctype', 'opportunity')
|
execute:frappe.reload_doc('crm', 'doctype', 'opportunity')
|
||||||
erpnext.patches.v5_0.rename_customer_issue
|
erpnext.patches.v5_0.rename_customer_issue
|
||||||
|
erpnext.patches.v5_0.update_material_transfer_for_manufacture
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
frappe.db.sql("""update `tabStock Entry` set purpose='Material Transfer for Manufacture'
|
||||||
|
where ifnull(production_order, '')!='' and purpose='Material Transfer'""")
|
@ -122,7 +122,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
|||||||
clean_up: function() {
|
clean_up: function() {
|
||||||
// Clear Production Order record from locals, because it is updated via Stock Entry
|
// Clear Production Order record from locals, because it is updated via Stock Entry
|
||||||
if(this.frm.doc.production_order &&
|
if(this.frm.doc.production_order &&
|
||||||
this.frm.doc.purpose == "Manufacture") {
|
in_list(["Manufacture", "Material Transfer for Manufacture"], this.frm.doc.purpose)) {
|
||||||
frappe.model.remove_from_locals("Production Order",
|
frappe.model.remove_from_locals("Production Order",
|
||||||
this.frm.doc.production_order);
|
this.frm.doc.production_order);
|
||||||
}
|
}
|
||||||
@ -164,7 +164,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
toggle_enable_bom: function() {
|
toggle_enable_bom: function() {
|
||||||
this.frm.toggle_enable("bom_no", this.frm.doc.purpose!="Manufacture");
|
this.frm.toggle_enable("bom_no", !in_list(["Manufacture", "Material Transfer for Manufacture"], this.frm.doc.purpose));
|
||||||
},
|
},
|
||||||
|
|
||||||
get_doctype_docname: function() {
|
get_doctype_docname: function() {
|
||||||
@ -233,8 +233,10 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
|||||||
if(!row.t_warehouse) row.t_warehouse = this.frm.doc.to_warehouse;
|
if(!row.t_warehouse) row.t_warehouse = this.frm.doc.to_warehouse;
|
||||||
},
|
},
|
||||||
|
|
||||||
source_mandatory: ["Material Issue", "Material Transfer", "Purchase Return", "Subcontract"],
|
source_mandatory: ["Material Issue", "Material Transfer", "Purchase Return", "Subcontract",
|
||||||
target_mandatory: ["Material Receipt", "Material Transfer", "Sales Return", "Subcontract"],
|
"Material Transfer for Manufacture"],
|
||||||
|
target_mandatory: ["Material Receipt", "Material Transfer", "Sales Return", "Subcontract",
|
||||||
|
"Material Transfer for Manufacture"],
|
||||||
|
|
||||||
from_warehouse: function(doc) {
|
from_warehouse: function(doc) {
|
||||||
var me = this;
|
var me = this;
|
||||||
@ -251,6 +253,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
set_warehouse_if_missing: function(fieldname, value, condition) {
|
set_warehouse_if_missing: function(fieldname, value, condition) {
|
||||||
|
var changed = false;
|
||||||
for (var i=0, l=(this.frm.doc.items || []).length; i<l; i++) {
|
for (var i=0, l=(this.frm.doc.items || []).length; i<l; i++) {
|
||||||
var row = this.frm.doc.items[i];
|
var row = this.frm.doc.items[i];
|
||||||
if (!row[fieldname]) {
|
if (!row[fieldname]) {
|
||||||
@ -259,8 +262,10 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
frappe.model.set_value(row.doctype, row.name, fieldname, value, "Link");
|
frappe.model.set_value(row.doctype, row.name, fieldname, value, "Link");
|
||||||
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
refresh_field("items");
|
||||||
},
|
},
|
||||||
|
|
||||||
items_on_form_rendered: function(doc, grid_row) {
|
items_on_form_rendered: function(doc, grid_row) {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -82,7 +82,7 @@ class StockEntry(StockController):
|
|||||||
self.meta.get_label("posting_date"))
|
self.meta.get_label("posting_date"))
|
||||||
|
|
||||||
def validate_purpose(self):
|
def validate_purpose(self):
|
||||||
valid_purposes = ["Material Issue", "Material Receipt", "Material Transfer",
|
valid_purposes = ["Material Issue", "Material Receipt", "Material Transfer", "Material Transfer for Manufacture",
|
||||||
"Manufacture", "Repack", "Subcontract", "Sales Return", "Purchase Return"]
|
"Manufacture", "Repack", "Subcontract", "Sales Return", "Purchase Return"]
|
||||||
if self.purpose not in valid_purposes:
|
if self.purpose not in valid_purposes:
|
||||||
frappe.throw(_("Purpose must be one of {0}").format(comma_or(valid_purposes)))
|
frappe.throw(_("Purpose must be one of {0}").format(comma_or(valid_purposes)))
|
||||||
@ -112,7 +112,7 @@ class StockEntry(StockController):
|
|||||||
if not item.transfer_qty:
|
if not item.transfer_qty:
|
||||||
item.transfer_qty = item.qty * item.conversion_factor
|
item.transfer_qty = item.qty * item.conversion_factor
|
||||||
|
|
||||||
if (self.purpose in ("Material Transfer", "Sales Return", "Purchase Return")
|
if (self.purpose in ("Material Transfer", "Sales Return", "Purchase Return", "Material Transfer for Manufacture")
|
||||||
and not item.serial_no
|
and not item.serial_no
|
||||||
and item.item_code in serialized_items):
|
and item.item_code in serialized_items):
|
||||||
frappe.throw(_("Row #{0}: Please specify Serial No for Item {1}").format(item.idx, item.item_code),
|
frappe.throw(_("Row #{0}: Please specify Serial No for Item {1}").format(item.idx, item.item_code),
|
||||||
@ -121,8 +121,8 @@ class StockEntry(StockController):
|
|||||||
def validate_warehouse(self, pro_obj):
|
def validate_warehouse(self, pro_obj):
|
||||||
"""perform various (sometimes conditional) validations on warehouse"""
|
"""perform various (sometimes conditional) validations on warehouse"""
|
||||||
|
|
||||||
source_mandatory = ["Material Issue", "Material Transfer", "Purchase Return", "Subcontract"]
|
source_mandatory = ["Material Issue", "Material Transfer", "Purchase Return", "Subcontract", "Material Transfer for Manufacture"]
|
||||||
target_mandatory = ["Material Receipt", "Material Transfer", "Sales Return", "Subcontract"]
|
target_mandatory = ["Material Receipt", "Material Transfer", "Sales Return", "Subcontract", "Material Transfer for Manufacture"]
|
||||||
|
|
||||||
validate_for_manufacture_repack = any([d.bom_no for d in self.get("items")])
|
validate_for_manufacture_repack = any([d.bom_no for d in self.get("items")])
|
||||||
|
|
||||||
@ -169,13 +169,14 @@ class StockEntry(StockController):
|
|||||||
frappe.throw(_("Source and target warehouse cannot be same for row {0}").format(d.idx))
|
frappe.throw(_("Source and target warehouse cannot be same for row {0}").format(d.idx))
|
||||||
|
|
||||||
def validate_production_order(self):
|
def validate_production_order(self):
|
||||||
if self.purpose == "Manufacture":
|
if self.purpose in ("Manufacture", "Material Transfer for Manufacture"):
|
||||||
# check if production order is entered
|
# check if production order is entered
|
||||||
if not self.production_order:
|
if not self.production_order:
|
||||||
frappe.throw(_("Production order number is mandatory for stock entry purpose manufacture"))
|
frappe.throw(_("Production order number is mandatory for stock entry purpose manufacture"))
|
||||||
# check for double entry
|
# check for double entry
|
||||||
self.check_if_operations_completed()
|
if self.purpose=="Manufacture":
|
||||||
self.check_duplicate_entry_for_production_order()
|
self.check_if_operations_completed()
|
||||||
|
self.check_duplicate_entry_for_production_order()
|
||||||
elif self.purpose != "Material Transfer":
|
elif self.purpose != "Material Transfer":
|
||||||
self.production_order = None
|
self.production_order = None
|
||||||
|
|
||||||
@ -503,8 +504,8 @@ class StockEntry(StockController):
|
|||||||
|
|
||||||
if self.bom_no:
|
if self.bom_no:
|
||||||
if self.purpose in ["Material Issue", "Material Transfer", "Manufacture", "Repack",
|
if self.purpose in ["Material Issue", "Material Transfer", "Manufacture", "Repack",
|
||||||
"Subcontract"]:
|
"Subcontract", "Material Transfer for Manufacture"]:
|
||||||
if self.production_order and self.purpose == "Material Transfer":
|
if self.production_order and self.purpose == "Material Transfer for Manufacture":
|
||||||
item_dict = self.get_pending_raw_materials(pro_obj)
|
item_dict = self.get_pending_raw_materials(pro_obj)
|
||||||
if self.to_warehouse and pro_obj:
|
if self.to_warehouse and pro_obj:
|
||||||
for item in item_dict.values():
|
for item in item_dict.values():
|
||||||
@ -601,7 +602,7 @@ class StockEntry(StockController):
|
|||||||
result = frappe.db.sql("""select t1.item_code, sum(t1.qty)
|
result = frappe.db.sql("""select t1.item_code, sum(t1.qty)
|
||||||
from `tabStock Entry Detail` t1, `tabStock Entry` t2
|
from `tabStock Entry Detail` t1, `tabStock Entry` t2
|
||||||
where t1.parent = t2.name and t2.production_order = %s and t2.docstatus = 1
|
where t1.parent = t2.name and t2.production_order = %s and t2.docstatus = 1
|
||||||
and t2.purpose = 'Material Transfer'
|
and t2.purpose = 'Material Transfer for Manufacture'
|
||||||
group by t1.item_code""", self.production_order)
|
group by t1.item_code""", self.production_order)
|
||||||
for t in result:
|
for t in result:
|
||||||
issued_item_qty[t[0]] = flt(t[1])
|
issued_item_qty[t[0]] = flt(t[1])
|
||||||
|
@ -18,15 +18,18 @@
|
|||||||
<p>{%= doc.description %}</p>{% } %}
|
<p>{%= doc.description %}</p>{% } %}
|
||||||
{% include "templates/form_grid/includes/visible_cols.html" %}
|
{% include "templates/form_grid/includes/visible_cols.html" %}
|
||||||
<div>
|
<div>
|
||||||
{% if(doc.s_warehouse) { %}<span class="label
|
{% if(doc.s_warehouse) { %}
|
||||||
{%= (doc.actual_qty >= doc.qty) ? "label-success"
|
<span class="label label-primary">
|
||||||
: "label-danger" %}"
|
{%= doc.s_warehouse || "" %}</span>
|
||||||
title="{%= (doc.actual_qty >= doc.qty) ? __("In Stock")
|
{% } %}
|
||||||
: __("Not In Stock") %}">
|
<i class="octicon octicon-arrow-small-right"></i>
|
||||||
{%= doc.s_warehouse || "" %}</span>{% } %}
|
|
||||||
<i class="icon-long-arrow-right"></i>
|
|
||||||
{% if(doc.t_warehouse) { %}<span class="label label-primary">
|
{% if(doc.t_warehouse) { %}<span class="label label-primary">
|
||||||
{%= doc.t_warehouse || "" %}</span>{% } %}
|
{%= doc.t_warehouse || "" %}</span>{% } %}
|
||||||
|
{% if(doc.s_warehouse && doc.actual_qty < doc.qty) { %}
|
||||||
|
<span class="text-danger small" style="margin-left: 15px;">
|
||||||
|
<span class="octicon octicon-stop" style="font-size: 12px;"></span> Not in Stock
|
||||||
|
</span>
|
||||||
|
{% } %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user