mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-31 23:33:43 +00:00
* ci: add prettier to pre-commit
(cherry picked from commit 2c16036ef3)
* style: format js files
---------
Co-authored-by: barredterra <14891507+barredterra@users.noreply.github.com>
Co-authored-by: Ankush Menat <ankush@frappe.io>
This commit is contained in:
@@ -1,60 +1,72 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Blanket Order', {
|
||||
onload: function(frm) {
|
||||
frm.trigger('set_tc_name_filter');
|
||||
frappe.ui.form.on("Blanket Order", {
|
||||
onload: function (frm) {
|
||||
frm.trigger("set_tc_name_filter");
|
||||
},
|
||||
|
||||
setup: function(frm) {
|
||||
setup: function (frm) {
|
||||
frm.custom_make_buttons = {
|
||||
'Purchase Order': 'Purchase Order',
|
||||
'Sales Order': 'Sales Order',
|
||||
'Quotation': 'Quotation',
|
||||
"Purchase Order": "Purchase Order",
|
||||
"Sales Order": "Sales Order",
|
||||
Quotation: "Quotation",
|
||||
};
|
||||
|
||||
frm.add_fetch("customer", "customer_name", "customer_name");
|
||||
frm.add_fetch("supplier", "supplier_name", "supplier_name");
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
refresh: function (frm) {
|
||||
erpnext.hide_company(frm);
|
||||
if (frm.doc.customer && frm.doc.docstatus === 1 && frm.doc.to_date > frappe.datetime.get_today()) {
|
||||
frm.add_custom_button(__("Sales Order"), function() {
|
||||
frappe.model.open_mapped_doc({
|
||||
method: "erpnext.manufacturing.doctype.blanket_order.blanket_order.make_order",
|
||||
frm: frm,
|
||||
args: {
|
||||
doctype: 'Sales Order'
|
||||
}
|
||||
});
|
||||
}, __('Create'));
|
||||
frm.add_custom_button(
|
||||
__("Sales Order"),
|
||||
function () {
|
||||
frappe.model.open_mapped_doc({
|
||||
method: "erpnext.manufacturing.doctype.blanket_order.blanket_order.make_order",
|
||||
frm: frm,
|
||||
args: {
|
||||
doctype: "Sales Order",
|
||||
},
|
||||
});
|
||||
},
|
||||
__("Create")
|
||||
);
|
||||
|
||||
frm.add_custom_button(__("Quotation"), function() {
|
||||
frappe.model.open_mapped_doc({
|
||||
method: "erpnext.manufacturing.doctype.blanket_order.blanket_order.make_order",
|
||||
frm: frm,
|
||||
args: {
|
||||
doctype: 'Quotation'
|
||||
}
|
||||
});
|
||||
}, __('Create'));
|
||||
frm.add_custom_button(
|
||||
__("Quotation"),
|
||||
function () {
|
||||
frappe.model.open_mapped_doc({
|
||||
method: "erpnext.manufacturing.doctype.blanket_order.blanket_order.make_order",
|
||||
frm: frm,
|
||||
args: {
|
||||
doctype: "Quotation",
|
||||
},
|
||||
});
|
||||
},
|
||||
__("Create")
|
||||
);
|
||||
}
|
||||
|
||||
if (frm.doc.supplier && frm.doc.docstatus === 1) {
|
||||
frm.add_custom_button(__("Purchase Order"), function(){
|
||||
frappe.model.open_mapped_doc({
|
||||
method: "erpnext.manufacturing.doctype.blanket_order.blanket_order.make_order",
|
||||
frm: frm,
|
||||
args: {
|
||||
doctype: 'Purchase Order'
|
||||
}
|
||||
});
|
||||
}, __('Create'));
|
||||
frm.add_custom_button(
|
||||
__("Purchase Order"),
|
||||
function () {
|
||||
frappe.model.open_mapped_doc({
|
||||
method: "erpnext.manufacturing.doctype.blanket_order.blanket_order.make_order",
|
||||
frm: frm,
|
||||
args: {
|
||||
doctype: "Purchase Order",
|
||||
},
|
||||
});
|
||||
},
|
||||
__("Create")
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
onload_post_render: function(frm) {
|
||||
onload_post_render: function (frm) {
|
||||
frm.get_field("items").grid.set_multiple_add("item_code", "qty");
|
||||
},
|
||||
|
||||
@@ -66,28 +78,28 @@ frappe.ui.form.on('Blanket Order', {
|
||||
});
|
||||
},
|
||||
|
||||
set_tc_name_filter: function(frm) {
|
||||
if (frm.doc.blanket_order_type === 'Selling') {
|
||||
frm.set_df_property("customer","reqd", 1);
|
||||
frm.set_df_property("supplier","reqd", 0);
|
||||
set_tc_name_filter: function (frm) {
|
||||
if (frm.doc.blanket_order_type === "Selling") {
|
||||
frm.set_df_property("customer", "reqd", 1);
|
||||
frm.set_df_property("supplier", "reqd", 0);
|
||||
frm.set_value("supplier", "");
|
||||
|
||||
frm.set_query("tc_name", function() {
|
||||
frm.set_query("tc_name", function () {
|
||||
return { filters: { selling: 1 } };
|
||||
});
|
||||
}
|
||||
if (frm.doc.blanket_order_type === 'Purchasing') {
|
||||
frm.set_df_property("supplier","reqd", 1);
|
||||
frm.set_df_property("customer","reqd", 0);
|
||||
if (frm.doc.blanket_order_type === "Purchasing") {
|
||||
frm.set_df_property("supplier", "reqd", 1);
|
||||
frm.set_df_property("customer", "reqd", 0);
|
||||
frm.set_value("customer", "");
|
||||
|
||||
frm.set_query("tc_name", function() {
|
||||
frm.set_query("tc_name", function () {
|
||||
return { filters: { buying: 1 } };
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
blanket_order_type: function (frm) {
|
||||
frm.trigger('set_tc_name_filter');
|
||||
}
|
||||
frm.trigger("set_tc_name_filter");
|
||||
},
|
||||
});
|
||||
|
||||
@@ -6,139 +6,150 @@ frappe.provide("erpnext.bom");
|
||||
frappe.ui.form.on("BOM", {
|
||||
setup(frm) {
|
||||
frm.custom_make_buttons = {
|
||||
'Work Order': 'Work Order',
|
||||
'Quality Inspection': 'Quality Inspection'
|
||||
"Work Order": "Work Order",
|
||||
"Quality Inspection": "Quality Inspection",
|
||||
};
|
||||
|
||||
frm.set_query("bom_no", "items", function() {
|
||||
frm.set_query("bom_no", "items", function () {
|
||||
return {
|
||||
filters: {
|
||||
'currency': frm.doc.currency,
|
||||
'company': frm.doc.company
|
||||
}
|
||||
currency: frm.doc.currency,
|
||||
company: frm.doc.company,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("source_warehouse", "items", function() {
|
||||
frm.set_query("source_warehouse", "items", function () {
|
||||
return {
|
||||
filters: {
|
||||
'company': frm.doc.company
|
||||
}
|
||||
company: frm.doc.company,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("item", function() {
|
||||
frm.set_query("item", function () {
|
||||
return {
|
||||
query: "erpnext.manufacturing.doctype.bom.bom.item_query",
|
||||
filters: {
|
||||
"is_stock_item": 1
|
||||
}
|
||||
is_stock_item: 1,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("project", function() {
|
||||
return{
|
||||
filters:[
|
||||
['Project', 'status', 'not in', 'Completed, Cancelled']
|
||||
]
|
||||
frm.set_query("project", function () {
|
||||
return {
|
||||
filters: [["Project", "status", "not in", "Completed, Cancelled"]],
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("item_code", "items", function(doc) {
|
||||
frm.set_query("item_code", "items", function (doc) {
|
||||
return {
|
||||
query: "erpnext.manufacturing.doctype.bom.bom.item_query",
|
||||
filters: {
|
||||
"include_item_in_manufacturing": 1,
|
||||
"is_fixed_asset": 0
|
||||
}
|
||||
include_item_in_manufacturing: 1,
|
||||
is_fixed_asset: 0,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("bom_no", "items", function(doc, cdt, cdn) {
|
||||
frm.set_query("bom_no", "items", function (doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
return {
|
||||
filters: {
|
||||
'item': d.item_code,
|
||||
'is_active': 1,
|
||||
'docstatus': 1
|
||||
}
|
||||
item: d.item_code,
|
||||
is_active: 1,
|
||||
docstatus: 1,
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
validate: function(frm) {
|
||||
validate: function (frm) {
|
||||
if (frm.doc.fg_based_operating_cost && frm.doc.with_operations) {
|
||||
frappe.throw({message: __("Please check either with operations or FG Based Operating Cost."), title: __("Mandatory")});
|
||||
frappe.throw({
|
||||
message: __("Please check either with operations or FG Based Operating Cost."),
|
||||
title: __("Mandatory"),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
with_operations: function(frm) {
|
||||
with_operations: function (frm) {
|
||||
frm.set_df_property("fg_based_operating_cost", "hidden", frm.doc.with_operations ? 1 : 0);
|
||||
},
|
||||
|
||||
fg_based_operating_cost: function(frm) {
|
||||
fg_based_operating_cost: function (frm) {
|
||||
frm.set_df_property("with_operations", "hidden", frm.doc.fg_based_operating_cost ? 1 : 0);
|
||||
},
|
||||
|
||||
onload_post_render: function(frm) {
|
||||
onload_post_render: function (frm) {
|
||||
frm.get_field("items").grid.set_multiple_add("item_code", "qty");
|
||||
},
|
||||
|
||||
refresh(frm) {
|
||||
frm.toggle_enable("item", frm.doc.__islocal);
|
||||
|
||||
frm.set_indicator_formatter('item_code',
|
||||
function(doc) {
|
||||
if (doc.original_item){
|
||||
return (doc.item_code != doc.original_item) ? "orange" : ""
|
||||
}
|
||||
return ""
|
||||
frm.set_indicator_formatter("item_code", function (doc) {
|
||||
if (doc.original_item) {
|
||||
return doc.item_code != doc.original_item ? "orange" : "";
|
||||
}
|
||||
)
|
||||
return "";
|
||||
});
|
||||
|
||||
if (!frm.is_new() && frm.doc.docstatus<2) {
|
||||
frm.add_custom_button(__("Update Cost"), function() {
|
||||
if (!frm.is_new() && frm.doc.docstatus < 2) {
|
||||
frm.add_custom_button(__("Update Cost"), function () {
|
||||
frm.events.update_cost(frm, true);
|
||||
});
|
||||
frm.add_custom_button(__("Browse BOM"), function() {
|
||||
frm.add_custom_button(__("Browse BOM"), function () {
|
||||
frappe.route_options = {
|
||||
"bom": frm.doc.name
|
||||
bom: frm.doc.name,
|
||||
};
|
||||
frappe.set_route("Tree", "BOM");
|
||||
});
|
||||
}
|
||||
|
||||
if (!frm.is_new() && !frm.doc.docstatus == 0) {
|
||||
frm.add_custom_button(__("New Version"), function() {
|
||||
frm.add_custom_button(__("New Version"), function () {
|
||||
let new_bom = frappe.model.copy_doc(frm.doc);
|
||||
frappe.set_route("Form", "BOM", new_bom.name);
|
||||
});
|
||||
}
|
||||
|
||||
if(frm.doc.docstatus==1) {
|
||||
frm.add_custom_button(__("Work Order"), function() {
|
||||
frm.trigger("make_work_order");
|
||||
}, __("Create"));
|
||||
if (frm.doc.docstatus == 1) {
|
||||
frm.add_custom_button(
|
||||
__("Work Order"),
|
||||
function () {
|
||||
frm.trigger("make_work_order");
|
||||
},
|
||||
__("Create")
|
||||
);
|
||||
|
||||
if (frm.doc.has_variants) {
|
||||
frm.add_custom_button(__("Variant BOM"), function() {
|
||||
frm.trigger("make_variant_bom");
|
||||
}, __("Create"));
|
||||
frm.add_custom_button(
|
||||
__("Variant BOM"),
|
||||
function () {
|
||||
frm.trigger("make_variant_bom");
|
||||
},
|
||||
__("Create")
|
||||
);
|
||||
}
|
||||
|
||||
if (frm.doc.inspection_required) {
|
||||
frm.add_custom_button(__("Quality Inspection"), function() {
|
||||
frm.trigger("make_quality_inspection");
|
||||
}, __("Create"));
|
||||
frm.add_custom_button(
|
||||
__("Quality Inspection"),
|
||||
function () {
|
||||
frm.trigger("make_quality_inspection");
|
||||
},
|
||||
__("Create")
|
||||
);
|
||||
}
|
||||
|
||||
frm.page.set_inner_btn_group_as_primary(__('Create'));
|
||||
frm.page.set_inner_btn_group_as_primary(__("Create"));
|
||||
}
|
||||
|
||||
if(frm.doc.items && frm.doc.allow_alternative_item) {
|
||||
const has_alternative = frm.doc.items.find(i => i.allow_alternative_item === 1);
|
||||
if (frm.doc.items && frm.doc.allow_alternative_item) {
|
||||
const has_alternative = frm.doc.items.find((i) => i.allow_alternative_item === 1);
|
||||
if (frm.doc.docstatus == 0 && has_alternative) {
|
||||
frm.add_custom_button(__('Alternate Item'), () => {
|
||||
frm.add_custom_button(__("Alternate Item"), () => {
|
||||
erpnext.utils.select_alternate_items({
|
||||
frm: frm,
|
||||
child_docname: "items",
|
||||
@@ -146,23 +157,26 @@ frappe.ui.form.on("BOM", {
|
||||
child_doctype: "BOM Item",
|
||||
original_item_field: "original_item",
|
||||
condition: (d) => {
|
||||
if (d.allow_alternative_item) {return true;}
|
||||
}
|
||||
})
|
||||
if (d.allow_alternative_item) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (frm.doc.has_variants) {
|
||||
frm.set_intro(__('This is a Template BOM and will be used to make the work order for {0} of the item {1}',
|
||||
[
|
||||
frm.set_intro(
|
||||
__("This is a Template BOM and will be used to make the work order for {0} of the item {1}", [
|
||||
`<a class="variants-intro">variants</a>`,
|
||||
`<a href="/app/item/${frm.doc.item}">${frm.doc.item}</a>`,
|
||||
]), true);
|
||||
]),
|
||||
true
|
||||
);
|
||||
|
||||
frm.$wrapper.find(".variants-intro").on("click", () => {
|
||||
frappe.set_route("List", "Item", {"variant_of": frm.doc.item});
|
||||
frappe.set_route("List", "Item", { variant_of: frm.doc.item });
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -176,38 +190,43 @@ frappe.ui.form.on("BOM", {
|
||||
item: item,
|
||||
qty: data.qty || 0.0,
|
||||
project: frm.doc.project,
|
||||
variant_items: variant_items
|
||||
variant_items: variant_items,
|
||||
},
|
||||
freeze: true,
|
||||
callback(r) {
|
||||
if(r.message) {
|
||||
if (r.message) {
|
||||
let doc = frappe.model.sync(r.message)[0];
|
||||
frappe.set_route("Form", doc.doctype, doc.name);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
make_variant_bom(frm) {
|
||||
frm.events.setup_variant_prompt(frm, "Variant BOM", (frm, item, data, variant_items) => {
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.bom.bom.make_variant_bom",
|
||||
args: {
|
||||
source_name: frm.doc.name,
|
||||
bom_no: frm.doc.name,
|
||||
item: item,
|
||||
variant_items: variant_items
|
||||
},
|
||||
freeze: true,
|
||||
callback(r) {
|
||||
if(r.message) {
|
||||
let doc = frappe.model.sync(r.message)[0];
|
||||
frappe.set_route("Form", doc.doctype, doc.name);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
frm.events.setup_variant_prompt(
|
||||
frm,
|
||||
"Variant BOM",
|
||||
(frm, item, data, variant_items) => {
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.bom.bom.make_variant_bom",
|
||||
args: {
|
||||
source_name: frm.doc.name,
|
||||
bom_no: frm.doc.name,
|
||||
item: item,
|
||||
variant_items: variant_items,
|
||||
},
|
||||
freeze: true,
|
||||
callback(r) {
|
||||
if (r.message) {
|
||||
let doc = frappe.model.sync(r.message)[0];
|
||||
frappe.set_route("Form", doc.doctype, doc.name);
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
true
|
||||
);
|
||||
},
|
||||
|
||||
setup_variant_prompt(frm, title, callback, skip_qty_field) {
|
||||
@@ -215,27 +234,27 @@ frappe.ui.form.on("BOM", {
|
||||
|
||||
if (frm.doc.has_variants) {
|
||||
fields.push({
|
||||
fieldtype: 'Link',
|
||||
label: __('Variant Item'),
|
||||
fieldname: 'item',
|
||||
fieldtype: "Link",
|
||||
label: __("Variant Item"),
|
||||
fieldname: "item",
|
||||
options: "Item",
|
||||
reqd: 1,
|
||||
get_query() {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.item_query",
|
||||
filters: {
|
||||
"variant_of": frm.doc.item
|
||||
}
|
||||
variant_of: frm.doc.item,
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (!skip_qty_field) {
|
||||
fields.push({
|
||||
fieldtype: 'Float',
|
||||
label: __('Qty To Manufacture'),
|
||||
fieldname: 'qty',
|
||||
fieldtype: "Float",
|
||||
label: __("Qty To Manufacture"),
|
||||
fieldname: "qty",
|
||||
reqd: 1,
|
||||
default: 1,
|
||||
onchange: () => {
|
||||
@@ -244,29 +263,23 @@ frappe.ui.form.on("BOM", {
|
||||
acc[item.item_code] = item.qty;
|
||||
return acc;
|
||||
}, {});
|
||||
const mf_qty = cur_dialog.fields_list.filter(
|
||||
(f) => f.df.fieldname === "qty"
|
||||
)[0]?.value;
|
||||
const items = cur_dialog.fields.filter(
|
||||
(f) => f.fieldname === "items"
|
||||
)[0]?.data;
|
||||
const mf_qty = cur_dialog.fields_list.filter((f) => f.df.fieldname === "qty")[0]?.value;
|
||||
const items = cur_dialog.fields.filter((f) => f.fieldname === "items")[0]?.data;
|
||||
|
||||
if (!items) {
|
||||
return;
|
||||
}
|
||||
|
||||
items.forEach((item) => {
|
||||
item.qty =
|
||||
(variant_items_map[item.item_code] * mf_qty) /
|
||||
quantity;
|
||||
item.qty = (variant_items_map[item.item_code] * mf_qty) / quantity;
|
||||
});
|
||||
|
||||
cur_dialog.refresh();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
var has_template_rm = frm.doc.items.filter(d => d.has_variants === 1) || [];
|
||||
var has_template_rm = frm.doc.items.filter((d) => d.has_variants === 1) || [];
|
||||
if (has_template_rm && has_template_rm.length > 0) {
|
||||
fields.push({
|
||||
fieldname: "items",
|
||||
@@ -296,10 +309,10 @@ frappe.ui.form.on("BOM", {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.item_query",
|
||||
filters: {
|
||||
"variant_of": data.item_code
|
||||
}
|
||||
variant_of: data.item_code,
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldname: "qty",
|
||||
@@ -312,44 +325,48 @@ frappe.ui.form.on("BOM", {
|
||||
fieldname: "source_warehouse",
|
||||
label: __("Source Warehouse"),
|
||||
fieldtype: "Link",
|
||||
options: "Warehouse"
|
||||
options: "Warehouse",
|
||||
},
|
||||
{
|
||||
fieldname: "operation",
|
||||
label: __("Operation"),
|
||||
fieldtype: "Data",
|
||||
hidden: 1,
|
||||
}
|
||||
},
|
||||
],
|
||||
in_place_edit: true,
|
||||
data: [],
|
||||
get_data () {
|
||||
get_data() {
|
||||
return [];
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
let dialog = frappe.prompt(fields, data => {
|
||||
let item = data.item || frm.doc.item;
|
||||
let variant_items = data.items || [];
|
||||
let dialog = frappe.prompt(
|
||||
fields,
|
||||
(data) => {
|
||||
let item = data.item || frm.doc.item;
|
||||
let variant_items = data.items || [];
|
||||
|
||||
variant_items.forEach(d => {
|
||||
if (!d.variant_item_code) {
|
||||
frappe.throw(__("Select variant item code for the template item {0}", [d.item_code]));
|
||||
}
|
||||
})
|
||||
variant_items.forEach((d) => {
|
||||
if (!d.variant_item_code) {
|
||||
frappe.throw(__("Select variant item code for the template item {0}", [d.item_code]));
|
||||
}
|
||||
});
|
||||
|
||||
callback(frm, item, data, variant_items);
|
||||
callback(frm, item, data, variant_items);
|
||||
},
|
||||
__(title),
|
||||
__("Create")
|
||||
);
|
||||
|
||||
}, __(title), __("Create"));
|
||||
|
||||
has_template_rm.forEach(d => {
|
||||
has_template_rm.forEach((d) => {
|
||||
dialog.fields_dict.items.df.data.push({
|
||||
"item_code": d.item_code,
|
||||
"variant_item_code": "",
|
||||
"qty": d.qty,
|
||||
"source_warehouse": d.source_warehouse,
|
||||
"operation": d.operation
|
||||
item_code: d.item_code,
|
||||
variant_item_code: "",
|
||||
qty: d.qty,
|
||||
source_warehouse: d.source_warehouse,
|
||||
operation: d.operation,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -361,11 +378,11 @@ frappe.ui.form.on("BOM", {
|
||||
make_quality_inspection(frm) {
|
||||
frappe.model.open_mapped_doc({
|
||||
method: "erpnext.stock.doctype.quality_inspection.quality_inspection.make_quality_inspection",
|
||||
frm: frm
|
||||
})
|
||||
frm: frm,
|
||||
});
|
||||
},
|
||||
|
||||
update_cost(frm, save_doc=false) {
|
||||
update_cost(frm, save_doc = false) {
|
||||
return frappe.call({
|
||||
doc: frm.doc,
|
||||
method: "update_cost",
|
||||
@@ -373,12 +390,12 @@ frappe.ui.form.on("BOM", {
|
||||
args: {
|
||||
update_parent: true,
|
||||
save: save_doc,
|
||||
from_child_bom: false
|
||||
from_child_bom: false,
|
||||
},
|
||||
callback(r) {
|
||||
refresh_field("items");
|
||||
if(!r.exc) frm.refresh_fields();
|
||||
}
|
||||
if (!r.exc) frm.refresh_fields();
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -400,39 +417,39 @@ frappe.ui.form.on("BOM", {
|
||||
erpnext.bom.calculate_op_cost(frm.doc);
|
||||
erpnext.bom.calculate_total(frm.doc);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
process_loss_percentage(frm) {
|
||||
let qty = 0.0
|
||||
let qty = 0.0;
|
||||
if (frm.doc.process_loss_percentage) {
|
||||
qty = (frm.doc.quantity * frm.doc.process_loss_percentage) / 100;
|
||||
}
|
||||
|
||||
frm.set_value("process_loss_qty", qty);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
erpnext.bom.BomController = class BomController extends erpnext.TransactionController {
|
||||
conversion_rate(doc) {
|
||||
if(this.frm.doc.currency === this.get_company_currency()) {
|
||||
if (this.frm.doc.currency === this.get_company_currency()) {
|
||||
this.frm.set_value("conversion_rate", 1.0);
|
||||
} else {
|
||||
erpnext.bom.update_cost(doc);
|
||||
}
|
||||
}
|
||||
|
||||
item_code(doc, cdt, cdn){
|
||||
item_code(doc, cdt, cdn) {
|
||||
var scrap_items = false;
|
||||
var child = locals[cdt][cdn];
|
||||
if (child.doctype == 'BOM Scrap Item') {
|
||||
if (child.doctype == "BOM Scrap Item") {
|
||||
scrap_items = true;
|
||||
}
|
||||
|
||||
if (child.bom_no) {
|
||||
child.bom_no = '';
|
||||
child.bom_no = "";
|
||||
}
|
||||
|
||||
get_bom_material_detail(doc, cdt, cdn, scrap_items);
|
||||
@@ -460,26 +477,26 @@ erpnext.bom.BomController = class BomController extends erpnext.TransactionContr
|
||||
}
|
||||
};
|
||||
|
||||
extend_cscript(cur_frm.cscript, new erpnext.bom.BomController({frm: cur_frm}));
|
||||
extend_cscript(cur_frm.cscript, new erpnext.bom.BomController({ frm: cur_frm }));
|
||||
|
||||
cur_frm.cscript.hour_rate = function(doc) {
|
||||
cur_frm.cscript.hour_rate = function (doc) {
|
||||
erpnext.bom.calculate_op_cost(doc);
|
||||
erpnext.bom.calculate_total(doc);
|
||||
};
|
||||
|
||||
cur_frm.cscript.time_in_mins = cur_frm.cscript.hour_rate;
|
||||
|
||||
cur_frm.cscript.bom_no = function(doc, cdt, cdn) {
|
||||
cur_frm.cscript.bom_no = function (doc, cdt, cdn) {
|
||||
get_bom_material_detail(doc, cdt, cdn, false);
|
||||
};
|
||||
|
||||
cur_frm.cscript.is_default = function(doc) {
|
||||
cur_frm.cscript.is_default = function (doc) {
|
||||
if (doc.is_default) cur_frm.set_value("is_active", 1);
|
||||
};
|
||||
|
||||
var get_bom_material_detail = function(doc, cdt, cdn, scrap_items) {
|
||||
var get_bom_material_detail = function (doc, cdt, cdn, scrap_items) {
|
||||
if (!doc.company) {
|
||||
frappe.throw({message: __("Please select a Company first."), title: __("Mandatory")});
|
||||
frappe.throw({ message: __("Please select a Company first."), title: __("Mandatory") });
|
||||
}
|
||||
|
||||
var d = locals[cdt][cdn];
|
||||
@@ -488,20 +505,20 @@ var get_bom_material_detail = function(doc, cdt, cdn, scrap_items) {
|
||||
doc: doc,
|
||||
method: "get_bom_material_detail",
|
||||
args: {
|
||||
"company": doc.company,
|
||||
"item_code": d.item_code,
|
||||
"bom_no": d.bom_no != null ? d.bom_no: '',
|
||||
"scrap_items": scrap_items,
|
||||
"qty": d.qty,
|
||||
"stock_qty": d.stock_qty,
|
||||
"include_item_in_manufacturing": d.include_item_in_manufacturing,
|
||||
"uom": d.uom,
|
||||
"stock_uom": d.stock_uom,
|
||||
"conversion_factor": d.conversion_factor,
|
||||
"sourced_by_supplier": d.sourced_by_supplier,
|
||||
"do_not_explode": d.do_not_explode
|
||||
company: doc.company,
|
||||
item_code: d.item_code,
|
||||
bom_no: d.bom_no != null ? d.bom_no : "",
|
||||
scrap_items: scrap_items,
|
||||
qty: d.qty,
|
||||
stock_qty: d.stock_qty,
|
||||
include_item_in_manufacturing: d.include_item_in_manufacturing,
|
||||
uom: d.uom,
|
||||
stock_uom: d.stock_uom,
|
||||
conversion_factor: d.conversion_factor,
|
||||
sourced_by_supplier: d.sourced_by_supplier,
|
||||
do_not_explode: d.do_not_explode,
|
||||
},
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
d = locals[cdt][cdn];
|
||||
|
||||
$.extend(d, r.message);
|
||||
@@ -513,18 +530,18 @@ var get_bom_material_detail = function(doc, cdt, cdn, scrap_items) {
|
||||
erpnext.bom.calculate_scrap_materials_cost(doc);
|
||||
erpnext.bom.calculate_total(doc);
|
||||
},
|
||||
freeze: true
|
||||
freeze: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
cur_frm.cscript.qty = function(doc) {
|
||||
cur_frm.cscript.qty = function (doc) {
|
||||
erpnext.bom.calculate_rm_cost(doc);
|
||||
erpnext.bom.calculate_scrap_materials_cost(doc);
|
||||
erpnext.bom.calculate_total(doc);
|
||||
};
|
||||
|
||||
cur_frm.cscript.rate = function(doc, cdt, cdn) {
|
||||
cur_frm.cscript.rate = function (doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
const is_scrap_item = cdt == "BOM Scrap Item";
|
||||
|
||||
@@ -538,52 +555,60 @@ cur_frm.cscript.rate = function(doc, cdt, cdn) {
|
||||
}
|
||||
};
|
||||
|
||||
erpnext.bom.update_cost = function(doc) {
|
||||
erpnext.bom.update_cost = function (doc) {
|
||||
erpnext.bom.calculate_op_cost(doc);
|
||||
erpnext.bom.calculate_rm_cost(doc);
|
||||
erpnext.bom.calculate_scrap_materials_cost(doc);
|
||||
erpnext.bom.calculate_total(doc);
|
||||
};
|
||||
|
||||
erpnext.bom.calculate_op_cost = function(doc) {
|
||||
erpnext.bom.calculate_op_cost = function (doc) {
|
||||
doc.operating_cost = 0.0;
|
||||
doc.base_operating_cost = 0.0;
|
||||
|
||||
if(doc.with_operations) {
|
||||
if (doc.with_operations) {
|
||||
doc.operations.forEach((item) => {
|
||||
let operating_cost = flt(flt(item.hour_rate) * flt(item.time_in_mins) / 60, 2);
|
||||
let operating_cost = flt((flt(item.hour_rate) * flt(item.time_in_mins)) / 60, 2);
|
||||
let base_operating_cost = flt(operating_cost * doc.conversion_rate, 2);
|
||||
frappe.model.set_value('BOM Operation',item.name, {
|
||||
"operating_cost": operating_cost,
|
||||
"base_operating_cost": base_operating_cost
|
||||
frappe.model.set_value("BOM Operation", item.name, {
|
||||
operating_cost: operating_cost,
|
||||
base_operating_cost: base_operating_cost,
|
||||
});
|
||||
|
||||
doc.operating_cost += operating_cost;
|
||||
doc.base_operating_cost += base_operating_cost;
|
||||
});
|
||||
} else if(doc.fg_based_operating_cost) {
|
||||
} else if (doc.fg_based_operating_cost) {
|
||||
let total_operating_cost = doc.quantity * flt(doc.operating_cost_per_bom_quantity);
|
||||
doc.operating_cost = total_operating_cost;
|
||||
doc.base_operating_cost = flt(total_operating_cost * doc.conversion_rate, 2);
|
||||
}
|
||||
refresh_field(['operating_cost', 'base_operating_cost']);
|
||||
refresh_field(["operating_cost", "base_operating_cost"]);
|
||||
};
|
||||
|
||||
// rm : raw material
|
||||
erpnext.bom.calculate_rm_cost = function(doc) {
|
||||
erpnext.bom.calculate_rm_cost = function (doc) {
|
||||
var rm = doc.items || [];
|
||||
var total_rm_cost = 0;
|
||||
var base_total_rm_cost = 0;
|
||||
for(var i=0;i<rm.length;i++) {
|
||||
for (var i = 0; i < rm.length; i++) {
|
||||
var amount = flt(rm[i].rate) * flt(rm[i].qty);
|
||||
var base_amount = amount * flt(doc.conversion_rate);
|
||||
|
||||
frappe.model.set_value('BOM Item', rm[i].name, 'base_rate',
|
||||
flt(rm[i].rate) * flt(doc.conversion_rate));
|
||||
frappe.model.set_value('BOM Item', rm[i].name, 'amount', amount);
|
||||
frappe.model.set_value('BOM Item', rm[i].name, 'base_amount', base_amount);
|
||||
frappe.model.set_value('BOM Item', rm[i].name,
|
||||
'qty_consumed_per_unit', flt(rm[i].stock_qty)/flt(doc.quantity));
|
||||
frappe.model.set_value(
|
||||
"BOM Item",
|
||||
rm[i].name,
|
||||
"base_rate",
|
||||
flt(rm[i].rate) * flt(doc.conversion_rate)
|
||||
);
|
||||
frappe.model.set_value("BOM Item", rm[i].name, "amount", amount);
|
||||
frappe.model.set_value("BOM Item", rm[i].name, "base_amount", base_amount);
|
||||
frappe.model.set_value(
|
||||
"BOM Item",
|
||||
rm[i].name,
|
||||
"qty_consumed_per_unit",
|
||||
flt(rm[i].stock_qty) / flt(doc.quantity)
|
||||
);
|
||||
|
||||
total_rm_cost += amount;
|
||||
base_total_rm_cost += base_amount;
|
||||
@@ -593,19 +618,19 @@ erpnext.bom.calculate_rm_cost = function(doc) {
|
||||
};
|
||||
|
||||
// sm : scrap material
|
||||
erpnext.bom.calculate_scrap_materials_cost = function(doc) {
|
||||
erpnext.bom.calculate_scrap_materials_cost = function (doc) {
|
||||
var sm = doc.scrap_items || [];
|
||||
var total_sm_cost = 0;
|
||||
var base_total_sm_cost = 0;
|
||||
|
||||
for(var i=0;i<sm.length;i++) {
|
||||
for (var i = 0; i < sm.length; i++) {
|
||||
var base_rate = flt(sm[i].rate) * flt(doc.conversion_rate);
|
||||
var amount = flt(sm[i].rate) * flt(sm[i].stock_qty);
|
||||
var base_amount = amount * flt(doc.conversion_rate);
|
||||
|
||||
frappe.model.set_value('BOM Scrap Item',sm[i].name, 'base_rate', base_rate);
|
||||
frappe.model.set_value('BOM Scrap Item',sm[i].name, 'amount', amount);
|
||||
frappe.model.set_value('BOM Scrap Item',sm[i].name, 'base_amount', base_amount);
|
||||
frappe.model.set_value("BOM Scrap Item", sm[i].name, "base_rate", base_rate);
|
||||
frappe.model.set_value("BOM Scrap Item", sm[i].name, "amount", amount);
|
||||
frappe.model.set_value("BOM Scrap Item", sm[i].name, "base_amount", base_amount);
|
||||
|
||||
total_sm_cost += amount;
|
||||
base_total_sm_cost += base_amount;
|
||||
@@ -616,83 +641,87 @@ erpnext.bom.calculate_scrap_materials_cost = function(doc) {
|
||||
};
|
||||
|
||||
// Calculate Total Cost
|
||||
erpnext.bom.calculate_total = function(doc) {
|
||||
erpnext.bom.calculate_total = function (doc) {
|
||||
var total_cost = flt(doc.operating_cost) + flt(doc.raw_material_cost) - flt(doc.scrap_material_cost);
|
||||
var base_total_cost = flt(doc.base_operating_cost) + flt(doc.base_raw_material_cost)
|
||||
- flt(doc.base_scrap_material_cost);
|
||||
var base_total_cost =
|
||||
flt(doc.base_operating_cost) + flt(doc.base_raw_material_cost) - flt(doc.base_scrap_material_cost);
|
||||
|
||||
cur_frm.set_value("total_cost", total_cost);
|
||||
cur_frm.set_value("base_total_cost", base_total_cost);
|
||||
};
|
||||
|
||||
cur_frm.cscript.validate = function(doc) {
|
||||
cur_frm.cscript.validate = function (doc) {
|
||||
erpnext.bom.update_cost(doc);
|
||||
};
|
||||
|
||||
frappe.ui.form.on("BOM Operation", "operation", function(frm, cdt, cdn) {
|
||||
frappe.ui.form.on("BOM Operation", "operation", function (frm, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
|
||||
if(!d.operation) return;
|
||||
if (!d.operation) return;
|
||||
|
||||
frappe.call({
|
||||
"method": "frappe.client.get",
|
||||
method: "frappe.client.get",
|
||||
args: {
|
||||
doctype: "Operation",
|
||||
name: d.operation
|
||||
name: d.operation,
|
||||
},
|
||||
callback: function (data) {
|
||||
if(data.message.description) {
|
||||
if (data.message.description) {
|
||||
frappe.model.set_value(d.doctype, d.name, "description", data.message.description);
|
||||
}
|
||||
if(data.message.workstation) {
|
||||
if (data.message.workstation) {
|
||||
frappe.model.set_value(d.doctype, d.name, "workstation", data.message.workstation);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
frappe.ui.form.on("BOM Operation", "workstation", function(frm, cdt, cdn) {
|
||||
frappe.ui.form.on("BOM Operation", "workstation", function (frm, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if(!d.workstation) return;
|
||||
if (!d.workstation) return;
|
||||
frappe.call({
|
||||
"method": "frappe.client.get",
|
||||
method: "frappe.client.get",
|
||||
args: {
|
||||
doctype: "Workstation",
|
||||
name: d.workstation
|
||||
name: d.workstation,
|
||||
},
|
||||
callback: function (data) {
|
||||
frappe.model.set_value(d.doctype, d.name, "base_hour_rate", data.message.hour_rate);
|
||||
frappe.model.set_value(d.doctype, d.name, "hour_rate",
|
||||
flt(flt(data.message.hour_rate) / flt(frm.doc.conversion_rate)), 2);
|
||||
frappe.model.set_value(
|
||||
d.doctype,
|
||||
d.name,
|
||||
"hour_rate",
|
||||
flt(flt(data.message.hour_rate) / flt(frm.doc.conversion_rate)),
|
||||
2
|
||||
);
|
||||
|
||||
erpnext.bom.calculate_op_cost(frm.doc);
|
||||
erpnext.bom.calculate_total(frm.doc);
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
frappe.ui.form.on("BOM Item", {
|
||||
do_not_explode: function(frm, cdt, cdn) {
|
||||
do_not_explode: function (frm, cdt, cdn) {
|
||||
get_bom_material_detail(frm.doc, cdt, cdn, false);
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
frappe.ui.form.on("BOM Item", "qty", function(frm, cdt, cdn) {
|
||||
frappe.ui.form.on("BOM Item", "qty", function (frm, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
d.stock_qty = d.qty * d.conversion_factor;
|
||||
refresh_field("stock_qty", d.name, d.parentfield);
|
||||
});
|
||||
|
||||
frappe.ui.form.on("BOM Item", "item_code", function(frm, cdt, cdn) {
|
||||
frappe.ui.form.on("BOM Item", "item_code", function (frm, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
frappe.db.get_value('Item', {name: d.item_code}, 'allow_alternative_item', (r) => {
|
||||
d.allow_alternative_item = r.allow_alternative_item
|
||||
})
|
||||
frappe.db.get_value("Item", { name: d.item_code }, "allow_alternative_item", (r) => {
|
||||
d.allow_alternative_item = r.allow_alternative_item;
|
||||
});
|
||||
refresh_field("allow_alternative_item", d.name, d.parentfield);
|
||||
});
|
||||
|
||||
frappe.ui.form.on("BOM Item", "sourced_by_supplier", function(frm, cdt, cdn) {
|
||||
frappe.ui.form.on("BOM Item", "sourced_by_supplier", function (frm, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if (d.sourced_by_supplier) {
|
||||
d.rate = 0;
|
||||
@@ -700,7 +729,7 @@ frappe.ui.form.on("BOM Item", "sourced_by_supplier", function(frm, cdt, cdn) {
|
||||
}
|
||||
});
|
||||
|
||||
frappe.ui.form.on("BOM Item", "rate", function(frm, cdt, cdn) {
|
||||
frappe.ui.form.on("BOM Item", "rate", function (frm, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if (d.sourced_by_supplier) {
|
||||
d.rate = 0;
|
||||
@@ -708,37 +737,41 @@ frappe.ui.form.on("BOM Item", "rate", function(frm, cdt, cdn) {
|
||||
}
|
||||
});
|
||||
|
||||
frappe.ui.form.on("BOM Operation", "operations_remove", function(frm) {
|
||||
frappe.ui.form.on("BOM Operation", "operations_remove", function (frm) {
|
||||
erpnext.bom.calculate_op_cost(frm.doc);
|
||||
erpnext.bom.calculate_total(frm.doc);
|
||||
});
|
||||
|
||||
frappe.ui.form.on("BOM Item", "items_remove", function(frm) {
|
||||
frappe.ui.form.on("BOM Item", "items_remove", function (frm) {
|
||||
erpnext.bom.calculate_rm_cost(frm.doc);
|
||||
erpnext.bom.calculate_total(frm.doc);
|
||||
});
|
||||
|
||||
frappe.tour['BOM'] = [
|
||||
frappe.tour["BOM"] = [
|
||||
{
|
||||
fieldname: "item",
|
||||
title: "Item",
|
||||
description: __("Select the Item to be manufactured. The Item name, UoM, Company, and Currency will be fetched automatically.")
|
||||
description: __(
|
||||
"Select the Item to be manufactured. The Item name, UoM, Company, and Currency will be fetched automatically."
|
||||
),
|
||||
},
|
||||
{
|
||||
fieldname: "quantity",
|
||||
title: "Quantity",
|
||||
description: __("Enter the quantity of the Item that will be manufactured from this Bill of Materials.")
|
||||
description: __(
|
||||
"Enter the quantity of the Item that will be manufactured from this Bill of Materials."
|
||||
),
|
||||
},
|
||||
{
|
||||
fieldname: "with_operations",
|
||||
title: "With Operations",
|
||||
description: __("To add Operations tick the 'With Operations' checkbox.")
|
||||
description: __("To add Operations tick the 'With Operations' checkbox."),
|
||||
},
|
||||
{
|
||||
fieldname: "items",
|
||||
title: "Raw Materials",
|
||||
description: __("Select the raw materials (Items) required to manufacture the Item")
|
||||
}
|
||||
description: __("Select the raw materials (Items) required to manufacture the Item"),
|
||||
},
|
||||
];
|
||||
|
||||
frappe.ui.form.on("BOM Scrap Item", {
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
frappe.listview_settings['BOM'] = {
|
||||
frappe.listview_settings["BOM"] = {
|
||||
add_fields: ["is_active", "is_default", "total_cost", "has_variants"],
|
||||
get_indicator: function(doc) {
|
||||
if(doc.is_active && doc.has_variants) {
|
||||
get_indicator: function (doc) {
|
||||
if (doc.is_active && doc.has_variants) {
|
||||
return [__("Template"), "orange", "has_variants,=,Yes"];
|
||||
} else if(doc.is_default) {
|
||||
} else if (doc.is_default) {
|
||||
return [__("Default"), "green", "is_default,=,Yes"];
|
||||
} else if(doc.is_active) {
|
||||
} else if (doc.is_active) {
|
||||
return [__("Active"), "blue", "is_active,=,Yes"];
|
||||
} else if(!doc.is_active) {
|
||||
} else if (!doc.is_active) {
|
||||
return [__("Not active"), "gray", "is_active,=,No"];
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
frappe.help.youtube_id["BOM"] = "hDV0c1OeWLo";
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
frappe.treeview_settings["BOM"] = {
|
||||
get_tree_nodes: 'erpnext.manufacturing.doctype.bom.bom.get_children',
|
||||
get_tree_nodes: "erpnext.manufacturing.doctype.bom.bom.get_children",
|
||||
filters: [
|
||||
{
|
||||
fieldname: "bom",
|
||||
fieldtype:"Link",
|
||||
fieldtype: "Link",
|
||||
options: "BOM",
|
||||
label: __("BOM")
|
||||
}
|
||||
label: __("BOM"),
|
||||
},
|
||||
],
|
||||
title: "BOM",
|
||||
breadcrumb: "Manufacturing",
|
||||
@@ -14,21 +14,21 @@ frappe.treeview_settings["BOM"] = {
|
||||
root_label: "BOM", //fieldname from filters
|
||||
get_tree_root: false,
|
||||
show_expand_all: false,
|
||||
get_label: function(node) {
|
||||
if(node.data.qty) {
|
||||
get_label: function (node) {
|
||||
if (node.data.qty) {
|
||||
return node.data.qty + " x " + node.data.item_code;
|
||||
} else {
|
||||
return node.data.item_code || node.data.value;
|
||||
}
|
||||
},
|
||||
onload: function(me) {
|
||||
onload: function (me) {
|
||||
var label = frappe.get_route()[0] + "/" + frappe.get_route()[1];
|
||||
if(frappe.pages[label]) {
|
||||
if (frappe.pages[label]) {
|
||||
delete frappe.pages[label];
|
||||
}
|
||||
|
||||
var filter = me.opts.filters[0];
|
||||
if(frappe.route_options && frappe.route_options[filter.fieldname]) {
|
||||
if (frappe.route_options && frappe.route_options[filter.fieldname]) {
|
||||
var val = frappe.route_options[filter.fieldname];
|
||||
delete frappe.route_options[filter.fieldname];
|
||||
filter.default = "";
|
||||
@@ -41,28 +41,27 @@ frappe.treeview_settings["BOM"] = {
|
||||
toolbar: [
|
||||
{ toggle_btn: true },
|
||||
{
|
||||
label:__("Edit"),
|
||||
condition: function(node) {
|
||||
label: __("Edit"),
|
||||
condition: function (node) {
|
||||
return node.expandable;
|
||||
},
|
||||
click: function(node) {
|
||||
|
||||
click: function (node) {
|
||||
frappe.set_route("Form", "BOM", node.data.value);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
menu_items: [
|
||||
{
|
||||
label: __("New BOM"),
|
||||
action: function() {
|
||||
frappe.new_doc("BOM", true)
|
||||
action: function () {
|
||||
frappe.new_doc("BOM", true);
|
||||
},
|
||||
condition: 'frappe.boot.user.can_create.indexOf("BOM") !== -1'
|
||||
}
|
||||
condition: 'frappe.boot.user.can_create.indexOf("BOM") !== -1',
|
||||
},
|
||||
],
|
||||
onrender: function(node) {
|
||||
if(node.is_root && node.data.value!="BOM") {
|
||||
frappe.model.with_doc("BOM", node.data.value, function() {
|
||||
onrender: function (node) {
|
||||
if (node.is_root && node.data.value != "BOM") {
|
||||
frappe.model.with_doc("BOM", node.data.value, function () {
|
||||
var bom = frappe.model.get_doc("BOM", node.data.value);
|
||||
node.data.image = escape(bom.image) || "";
|
||||
node.data.description = bom.description || "";
|
||||
@@ -70,5 +69,5 @@ frappe.treeview_settings["BOM"] = {
|
||||
});
|
||||
}
|
||||
},
|
||||
view_template: 'bom_item_preview'
|
||||
}
|
||||
view_template: "bom_item_preview",
|
||||
};
|
||||
|
||||
@@ -11,11 +11,10 @@ frappe.ui.form.on("BOM Creator", {
|
||||
frm.dashboard.clear_comment();
|
||||
|
||||
if (!frm.is_new()) {
|
||||
if ((!frappe.bom_configurator
|
||||
|| frappe.bom_configurator.bom_configurator !== frm.doc.name)) {
|
||||
if (!frappe.bom_configurator || frappe.bom_configurator.bom_configurator !== frm.doc.name) {
|
||||
frm.trigger("build_tree");
|
||||
}
|
||||
} else if (!frm.doc.items?.length ) {
|
||||
} else if (!frm.doc.items?.length) {
|
||||
let $parent = $(frm.fields_dict["bom_creator"].wrapper);
|
||||
$parent.empty();
|
||||
frm.trigger("make_new_entry");
|
||||
@@ -27,7 +26,7 @@ frappe.ui.form.on("BOM Creator", {
|
||||
$parent.empty();
|
||||
frm.toggle_enable("item_code", false);
|
||||
|
||||
frappe.require('bom_configurator.bundle.js').then(() => {
|
||||
frappe.require("bom_configurator.bundle.js").then(() => {
|
||||
frappe.bom_configurator = new frappe.ui.BOMConfigurator({
|
||||
wrapper: $parent,
|
||||
page: $parent,
|
||||
@@ -45,7 +44,7 @@ frappe.ui.form.on("BOM Creator", {
|
||||
label: __("Name"),
|
||||
fieldtype: "Data",
|
||||
fieldname: "name",
|
||||
reqd: 1
|
||||
reqd: 1,
|
||||
},
|
||||
{ fieldtype: "Column Break" },
|
||||
{
|
||||
@@ -62,7 +61,7 @@ frappe.ui.form.on("BOM Creator", {
|
||||
fieldtype: "Link",
|
||||
fieldname: "item_code",
|
||||
options: "Item",
|
||||
reqd: 1
|
||||
reqd: 1,
|
||||
},
|
||||
{ fieldtype: "Column Break" },
|
||||
{
|
||||
@@ -70,7 +69,7 @@ frappe.ui.form.on("BOM Creator", {
|
||||
fieldtype: "Float",
|
||||
fieldname: "qty",
|
||||
reqd: 1,
|
||||
default: 1.0
|
||||
default: 1.0,
|
||||
},
|
||||
{ fieldtype: "Section Break" },
|
||||
{
|
||||
@@ -79,7 +78,7 @@ frappe.ui.form.on("BOM Creator", {
|
||||
fieldname: "currency",
|
||||
options: "Currency",
|
||||
reqd: 1,
|
||||
default: frappe.defaults.get_global_default("currency")
|
||||
default: frappe.defaults.get_global_default("currency"),
|
||||
},
|
||||
{ fieldtype: "Column Break" },
|
||||
{
|
||||
@@ -87,42 +86,40 @@ frappe.ui.form.on("BOM Creator", {
|
||||
fieldtype: "Float",
|
||||
fieldname: "conversion_rate",
|
||||
reqd: 1,
|
||||
default: 1.0
|
||||
default: 1.0,
|
||||
},
|
||||
],
|
||||
primary_action_label: __("Create"),
|
||||
primary_action: (values) => {
|
||||
values.doctype = frm.doc.doctype;
|
||||
frappe.db
|
||||
.insert(values)
|
||||
.then((doc) => {
|
||||
frappe.set_route("Form", doc.doctype, doc.name);
|
||||
});
|
||||
}
|
||||
})
|
||||
frappe.db.insert(values).then((doc) => {
|
||||
frappe.set_route("Form", doc.doctype, doc.name);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
dialog.fields_dict.item_code.get_query = "erpnext.controllers.queries.item_query";
|
||||
dialog.show();
|
||||
},
|
||||
|
||||
set_queries(frm) {
|
||||
frm.set_query("bom_no", "items", function(doc, cdt, cdn) {
|
||||
frm.set_query("bom_no", "items", function (doc, cdt, cdn) {
|
||||
let item = frappe.get_doc(cdt, cdn);
|
||||
return {
|
||||
filters: {
|
||||
item: item.item_code,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
frm.set_query("item_code", "items", function() {
|
||||
frm.set_query("item_code", "items", function () {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.item_query",
|
||||
}
|
||||
};
|
||||
});
|
||||
frm.set_query("fg_item", "items", function() {
|
||||
frm.set_query("fg_item", "items", function () {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.item_query",
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
@@ -134,8 +131,7 @@ frappe.ui.form.on("BOM Creator", {
|
||||
|
||||
set_root_item(frm) {
|
||||
if (frm.is_new() && frm.doc.items?.length) {
|
||||
frappe.model.set_value(frm.doc.items[0].doctype,
|
||||
frm.doc.items[0].name, "is_root", 1);
|
||||
frappe.model.set_value(frm.doc.items[0].doctype, frm.doc.items[0].name, "is_root", 1);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -157,8 +153,8 @@ frappe.ui.form.on("BOM Creator", {
|
||||
frm.call({
|
||||
method: "enqueue_create_boms",
|
||||
doc: frm.doc,
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
frappe.ui.form.on("BOM Creator Item", {
|
||||
@@ -176,24 +172,23 @@ frappe.ui.form.on("BOM Creator Item", {
|
||||
method: "get_default_bom",
|
||||
doc: frm.doc,
|
||||
args: {
|
||||
item_code: item.item_code
|
||||
item_code: item.item_code,
|
||||
},
|
||||
callback(r) {
|
||||
if (r.message) {
|
||||
frappe.model.set_value(cdt, cdn, "bom_no", r.message);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
} else {
|
||||
frappe.model.set_value(cdt, cdn, "bom_no", "");
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
erpnext.bom.BomConfigurator = class BomConfigurator extends erpnext.TransactionController {
|
||||
conversion_rate(doc) {
|
||||
if(this.frm.doc.currency === this.get_company_currency()) {
|
||||
if (this.frm.doc.currency === this.get_company_currency()) {
|
||||
this.frm.set_value("conversion_rate", 1.0);
|
||||
} else {
|
||||
erpnext.bom.update_cost(doc);
|
||||
@@ -222,4 +217,4 @@ erpnext.bom.BomConfigurator = class BomConfigurator extends erpnext.TransactionC
|
||||
}
|
||||
};
|
||||
|
||||
extend_cscript(cur_frm.cscript, new erpnext.bom.BomConfigurator({frm: cur_frm}));
|
||||
extend_cscript(cur_frm.cscript, new erpnext.bom.BomConfigurator({ frm: cur_frm }));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
frappe.listview_settings['BOM Creator'] = {
|
||||
frappe.listview_settings["BOM Creator"] = {
|
||||
add_fields: ["status"],
|
||||
get_indicator: function (doc) {
|
||||
if (doc.status === "Draft") {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('BOM Update Log', {
|
||||
frappe.ui.form.on("BOM Update Log", {
|
||||
// refresh: function(frm) {
|
||||
|
||||
// }
|
||||
});
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
frappe.listview_settings['BOM Update Log'] = {
|
||||
frappe.listview_settings["BOM Update Log"] = {
|
||||
add_fields: ["status"],
|
||||
get_indicator: (doc) => {
|
||||
let status_map = {
|
||||
"Queued": "orange",
|
||||
Queued: "orange",
|
||||
"In Progress": "blue",
|
||||
"Completed": "green",
|
||||
"Failed": "red"
|
||||
Completed: "green",
|
||||
Failed: "red",
|
||||
};
|
||||
|
||||
return [__(doc.status), status_map[doc.status], "status,=," + doc.status];
|
||||
@@ -15,16 +15,14 @@ frappe.listview_settings['BOM Update Log'] = {
|
||||
return;
|
||||
}
|
||||
|
||||
let sidebar_entry = $(
|
||||
'<ul class="list-unstyled sidebar-menu log-retention-note"></ul>'
|
||||
).appendTo(cur_list.page.sidebar);
|
||||
let sidebar_entry = $('<ul class="list-unstyled sidebar-menu log-retention-note"></ul>').appendTo(
|
||||
cur_list.page.sidebar
|
||||
);
|
||||
let message = __("Note: Automatic log deletion only applies to logs of type <i>Update Cost</i>");
|
||||
$(`<hr><div class='text-muted'>${message}</div>`).appendTo(sidebar_entry);
|
||||
|
||||
frappe.require("logtypes.bundle.js", () => {
|
||||
frappe.utils.logtypes.show_log_retention_message(cur_list.doctype);
|
||||
});
|
||||
|
||||
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('BOM Update Tool', {
|
||||
setup: function(frm) {
|
||||
frm.set_query("current_bom", function() {
|
||||
frappe.ui.form.on("BOM Update Tool", {
|
||||
setup: function (frm) {
|
||||
frm.set_query("current_bom", function () {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.bom",
|
||||
filters: {name: "!" + frm.doc.new_bom}
|
||||
filters: { name: "!" + frm.doc.new_bom },
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("new_bom", function() {
|
||||
frm.set_query("new_bom", function () {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.bom",
|
||||
filters: {name: "!" + frm.doc.current_bom}
|
||||
filters: { name: "!" + frm.doc.current_bom },
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
refresh: function (frm) {
|
||||
frm.disable_save();
|
||||
frm.events.disable_button(frm, "replace");
|
||||
|
||||
@@ -27,7 +27,7 @@ frappe.ui.form.on('BOM Update Tool', {
|
||||
});
|
||||
},
|
||||
|
||||
disable_button: (frm, field, disable=true) => {
|
||||
disable_button: (frm, field, disable = true) => {
|
||||
frm.get_field(field).input.disabled = disable;
|
||||
},
|
||||
|
||||
@@ -50,15 +50,15 @@ frappe.ui.form.on('BOM Update Tool', {
|
||||
freeze: true,
|
||||
args: {
|
||||
boms: {
|
||||
"current_bom": frm.doc.current_bom,
|
||||
"new_bom": frm.doc.new_bom
|
||||
}
|
||||
current_bom: frm.doc.current_bom,
|
||||
new_bom: frm.doc.new_bom,
|
||||
},
|
||||
},
|
||||
callback: result => {
|
||||
callback: (result) => {
|
||||
if (result && result.message && !result.exc) {
|
||||
frm.events.confirm_job_start(frm, result.message);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -67,20 +67,22 @@ frappe.ui.form.on('BOM Update Tool', {
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.enqueue_update_cost",
|
||||
freeze: true,
|
||||
callback: result => {
|
||||
callback: (result) => {
|
||||
if (result && result.message && !result.exc) {
|
||||
frm.events.confirm_job_start(frm, result.message);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
confirm_job_start: (frm, log_data) => {
|
||||
let log_link = frappe.utils.get_form_link("BOM Update Log", log_data.name, true);
|
||||
frappe.msgprint({
|
||||
"message": __("BOM Updation is queued and may take a few minutes. Check {0} for progress.", [log_link]),
|
||||
"title": __("BOM Update Initiated"),
|
||||
"indicator": "blue"
|
||||
message: __("BOM Updation is queued and may take a few minutes. Check {0} for progress.", [
|
||||
log_link,
|
||||
]),
|
||||
title: __("BOM Update Initiated"),
|
||||
indicator: "blue",
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Downtime Entry', {
|
||||
frappe.ui.form.on("Downtime Entry", {
|
||||
// refresh: function(frm) {
|
||||
|
||||
// }
|
||||
});
|
||||
|
||||
@@ -1,40 +1,38 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Job Card', {
|
||||
setup: function(frm) {
|
||||
frm.set_query('operation', function() {
|
||||
frappe.ui.form.on("Job Card", {
|
||||
setup: function (frm) {
|
||||
frm.set_query("operation", function () {
|
||||
return {
|
||||
query: 'erpnext.manufacturing.doctype.job_card.job_card.get_operations',
|
||||
query: "erpnext.manufacturing.doctype.job_card.job_card.get_operations",
|
||||
filters: {
|
||||
'work_order': frm.doc.work_order
|
||||
}
|
||||
work_order: frm.doc.work_order,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("serial_and_batch_bundle", () => {
|
||||
return {
|
||||
filters: {
|
||||
'item_code': frm.doc.production_item,
|
||||
'voucher_type': frm.doc.doctype,
|
||||
'voucher_no': ["in", [frm.doc.name, ""]],
|
||||
'is_cancelled': 0,
|
||||
}
|
||||
}
|
||||
item_code: frm.doc.production_item,
|
||||
voucher_type: frm.doc.doctype,
|
||||
voucher_no: ["in", [frm.doc.name, ""]],
|
||||
is_cancelled: 0,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_indicator_formatter('sub_operation',
|
||||
function(doc) {
|
||||
if (doc.status == "Pending") {
|
||||
return "red";
|
||||
} else {
|
||||
return doc.status === "Complete" ? "green" : "orange";
|
||||
}
|
||||
frm.set_indicator_formatter("sub_operation", function (doc) {
|
||||
if (doc.status == "Pending") {
|
||||
return "red";
|
||||
} else {
|
||||
return doc.status === "Complete" ? "green" : "orange";
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
refresh: function (frm) {
|
||||
frappe.flags.pause_job = 0;
|
||||
frappe.flags.resume_job = 0;
|
||||
let has_items = frm.doc.items && frm.doc.items.length;
|
||||
@@ -44,8 +42,7 @@ frappe.ui.form.on('Job Card', {
|
||||
return;
|
||||
}
|
||||
|
||||
let has_stock_entry = frm.doc.__onload &&
|
||||
frm.doc.__onload.has_stock_entry ? true : false;
|
||||
let has_stock_entry = frm.doc.__onload && frm.doc.__onload.has_stock_entry ? true : false;
|
||||
|
||||
frm.toggle_enable("for_quantity", !has_stock_entry);
|
||||
|
||||
@@ -71,33 +68,45 @@ frappe.ui.form.on('Job Card', {
|
||||
}
|
||||
|
||||
if (frm.doc.docstatus == 1 && !frm.doc.is_corrective_job_card) {
|
||||
frm.trigger('setup_corrective_job_card');
|
||||
frm.trigger("setup_corrective_job_card");
|
||||
}
|
||||
|
||||
frm.set_query("quality_inspection", function() {
|
||||
frm.set_query("quality_inspection", function () {
|
||||
return {
|
||||
query: "erpnext.stock.doctype.quality_inspection.quality_inspection.quality_inspection_query",
|
||||
filters: {
|
||||
"item_code": frm.doc.production_item,
|
||||
"reference_name": frm.doc.name
|
||||
}
|
||||
item_code: frm.doc.production_item,
|
||||
reference_name: frm.doc.name,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
frm.trigger("toggle_operation_number");
|
||||
|
||||
if (frm.doc.docstatus == 0 && !frm.is_new() &&
|
||||
(frm.doc.for_quantity > frm.doc.total_completed_qty || !frm.doc.for_quantity)
|
||||
&& (frm.doc.items || !frm.doc.items.length || frm.doc.for_quantity == frm.doc.transferred_qty)) {
|
||||
|
||||
if (
|
||||
frm.doc.docstatus == 0 &&
|
||||
!frm.is_new() &&
|
||||
(frm.doc.for_quantity > frm.doc.total_completed_qty || !frm.doc.for_quantity) &&
|
||||
(frm.doc.items || !frm.doc.items.length || frm.doc.for_quantity == frm.doc.transferred_qty)
|
||||
) {
|
||||
// if Job Card is link to Work Order, the job card must not be able to start if Work Order not "Started"
|
||||
// and if stock mvt for WIP is required
|
||||
if (frm.doc.work_order) {
|
||||
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 || !frm.doc.items.length) {
|
||||
frm.trigger("prepare_timer_buttons");
|
||||
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 ||
|
||||
!frm.doc.items.length
|
||||
) {
|
||||
frm.trigger("prepare_timer_buttons");
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
} else {
|
||||
frm.trigger("prepare_timer_buttons");
|
||||
}
|
||||
@@ -106,100 +115,114 @@ frappe.ui.form.on('Job Card', {
|
||||
frm.trigger("setup_quality_inspection");
|
||||
|
||||
if (frm.doc.work_order) {
|
||||
frappe.db.get_value('Work Order', frm.doc.work_order,
|
||||
'transfer_material_against').then((r) => {
|
||||
if (r.message.transfer_material_against == 'Work Order') {
|
||||
frm.set_df_property('items', 'hidden', 1);
|
||||
frappe.db.get_value("Work Order", frm.doc.work_order, "transfer_material_against").then((r) => {
|
||||
if (r.message.transfer_material_against == "Work Order") {
|
||||
frm.set_df_property("items", "hidden", 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let sbb_field = frm.get_docfield('serial_and_batch_bundle');
|
||||
let sbb_field = frm.get_docfield("serial_and_batch_bundle");
|
||||
if (sbb_field) {
|
||||
sbb_field.get_route_options_for_new_doc = () => {
|
||||
return {
|
||||
'item_code': frm.doc.production_item,
|
||||
'warehouse': frm.doc.wip_warehouse,
|
||||
'voucher_type': frm.doc.doctype,
|
||||
}
|
||||
item_code: frm.doc.production_item,
|
||||
warehouse: frm.doc.wip_warehouse,
|
||||
voucher_type: frm.doc.doctype,
|
||||
};
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
setup_quality_inspection: function(frm) {
|
||||
setup_quality_inspection: function (frm) {
|
||||
let quality_inspection_field = frm.get_docfield("quality_inspection");
|
||||
quality_inspection_field.get_route_options_for_new_doc = function(frm) {
|
||||
return {
|
||||
"inspection_type": "In Process",
|
||||
"reference_type": "Job Card",
|
||||
"reference_name": frm.doc.name,
|
||||
"item_code": frm.doc.production_item,
|
||||
"item_name": frm.doc.item_name,
|
||||
"item_serial_no": frm.doc.serial_no,
|
||||
"batch_no": frm.doc.batch_no,
|
||||
"quality_inspection_template": frm.doc.quality_inspection_template,
|
||||
quality_inspection_field.get_route_options_for_new_doc = function (frm) {
|
||||
return {
|
||||
inspection_type: "In Process",
|
||||
reference_type: "Job Card",
|
||||
reference_name: frm.doc.name,
|
||||
item_code: frm.doc.production_item,
|
||||
item_name: frm.doc.item_name,
|
||||
item_serial_no: frm.doc.serial_no,
|
||||
batch_no: frm.doc.batch_no,
|
||||
quality_inspection_template: frm.doc.quality_inspection_template,
|
||||
};
|
||||
};
|
||||
},
|
||||
|
||||
setup_corrective_job_card: function(frm) {
|
||||
frm.add_custom_button(__('Corrective Job Card'), () => {
|
||||
let operations = frm.doc.sub_operations.map(d => d.sub_operation).concat(frm.doc.operation);
|
||||
setup_corrective_job_card: function (frm) {
|
||||
frm.add_custom_button(
|
||||
__("Corrective Job Card"),
|
||||
() => {
|
||||
let operations = frm.doc.sub_operations.map((d) => d.sub_operation).concat(frm.doc.operation);
|
||||
|
||||
let fields = [
|
||||
{
|
||||
fieldtype: 'Link', label: __('Corrective Operation'), options: 'Operation',
|
||||
fieldname: 'operation', get_query() {
|
||||
return {
|
||||
filters: {
|
||||
"is_corrective_operation": 1
|
||||
}
|
||||
};
|
||||
}
|
||||
}, {
|
||||
fieldtype: 'Link', label: __('For Operation'), options: 'Operation',
|
||||
fieldname: 'for_operation', get_query() {
|
||||
return {
|
||||
filters: {
|
||||
"name": ["in", operations]
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
];
|
||||
let fields = [
|
||||
{
|
||||
fieldtype: "Link",
|
||||
label: __("Corrective Operation"),
|
||||
options: "Operation",
|
||||
fieldname: "operation",
|
||||
get_query() {
|
||||
return {
|
||||
filters: {
|
||||
is_corrective_operation: 1,
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldtype: "Link",
|
||||
label: __("For Operation"),
|
||||
options: "Operation",
|
||||
fieldname: "for_operation",
|
||||
get_query() {
|
||||
return {
|
||||
filters: {
|
||||
name: ["in", operations],
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
frappe.prompt(fields, d => {
|
||||
frm.events.make_corrective_job_card(frm, d.operation, d.for_operation);
|
||||
}, __("Select Corrective Operation"));
|
||||
}, __('Make'));
|
||||
frappe.prompt(
|
||||
fields,
|
||||
(d) => {
|
||||
frm.events.make_corrective_job_card(frm, d.operation, d.for_operation);
|
||||
},
|
||||
__("Select Corrective Operation")
|
||||
);
|
||||
},
|
||||
__("Make")
|
||||
);
|
||||
},
|
||||
|
||||
make_corrective_job_card: function(frm, operation, for_operation) {
|
||||
make_corrective_job_card: function (frm, operation, for_operation) {
|
||||
frappe.call({
|
||||
method: 'erpnext.manufacturing.doctype.job_card.job_card.make_corrective_job_card',
|
||||
method: "erpnext.manufacturing.doctype.job_card.job_card.make_corrective_job_card",
|
||||
args: {
|
||||
source_name: frm.doc.name,
|
||||
operation: operation,
|
||||
for_operation: for_operation
|
||||
for_operation: for_operation,
|
||||
},
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
frappe.model.sync(r.message);
|
||||
frappe.set_route("Form", r.message.doctype, r.message.name);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
operation: function(frm) {
|
||||
operation: function (frm) {
|
||||
frm.trigger("toggle_operation_number");
|
||||
|
||||
if (frm.doc.operation && frm.doc.work_order) {
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.job_card.job_card.get_operation_details",
|
||||
args: {
|
||||
"work_order":frm.doc.work_order,
|
||||
"operation":frm.doc.operation
|
||||
work_order: frm.doc.work_order,
|
||||
operation: frm.doc.operation,
|
||||
},
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
@@ -209,11 +232,13 @@ frappe.ui.form.on('Job Card', {
|
||||
let args = [];
|
||||
|
||||
r.message.forEach((row) => {
|
||||
args.push({ "label": row.idx, "value": row.name });
|
||||
args.push({ label: row.idx, value: row.name });
|
||||
});
|
||||
|
||||
let description = __("Operation {0} added multiple times in the work order {1}",
|
||||
[frm.doc.operation, frm.doc.work_order]);
|
||||
let description = __("Operation {0} added multiple times in the work order {1}", [
|
||||
frm.doc.operation,
|
||||
frm.doc.work_order,
|
||||
]);
|
||||
|
||||
frm.set_df_property("operation_row_number", "options", args);
|
||||
frm.set_df_property("operation_row_number", "description", description);
|
||||
@@ -221,8 +246,8 @@ frappe.ui.form.on('Job Card', {
|
||||
|
||||
frm.trigger("toggle_operation_number");
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -237,16 +262,24 @@ frappe.ui.form.on('Job Card', {
|
||||
frm.toggle_reqd("operation_row_number", !frm.doc.operation_id && frm.doc.operation);
|
||||
},
|
||||
|
||||
prepare_timer_buttons: function(frm) {
|
||||
prepare_timer_buttons: function (frm) {
|
||||
frm.trigger("make_dashboard");
|
||||
|
||||
if (!frm.doc.started_time && !frm.doc.current_time) {
|
||||
frm.add_custom_button(__("Start Job"), () => {
|
||||
if ((frm.doc.employee && !frm.doc.employee.length) || !frm.doc.employee) {
|
||||
frappe.prompt({fieldtype: 'Table MultiSelect', label: __('Select Employees'),
|
||||
options: "Job Card Time Log", fieldname: 'employees'}, d => {
|
||||
frm.events.start_job(frm, "Work In Progress", d.employees);
|
||||
}, __("Assign Job to Employee"));
|
||||
frappe.prompt(
|
||||
{
|
||||
fieldtype: "Table MultiSelect",
|
||||
label: __("Select Employees"),
|
||||
options: "Job Card Time Log",
|
||||
fieldname: "employees",
|
||||
},
|
||||
(d) => {
|
||||
frm.events.start_job(frm, "Work In Progress", d.employees);
|
||||
},
|
||||
__("Assign Job to Employee")
|
||||
);
|
||||
} else {
|
||||
frm.events.start_job(frm, "Work In Progress", frm.doc.employee);
|
||||
}
|
||||
@@ -268,16 +301,24 @@ frappe.ui.form.on('Job Card', {
|
||||
set_qty = false;
|
||||
let last_op_row = sub_operations[sub_operations.length - 2];
|
||||
|
||||
if (last_op_row.status == 'Complete') {
|
||||
if (last_op_row.status == "Complete") {
|
||||
set_qty = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (set_qty) {
|
||||
frappe.prompt({fieldtype: 'Float', label: __('Completed Quantity'),
|
||||
fieldname: 'qty', default: frm.doc.for_quantity}, data => {
|
||||
frm.events.complete_job(frm, "Complete", data.qty);
|
||||
}, __("Enter Value"));
|
||||
frappe.prompt(
|
||||
{
|
||||
fieldtype: "Float",
|
||||
label: __("Completed Quantity"),
|
||||
fieldname: "qty",
|
||||
default: frm.doc.for_quantity,
|
||||
},
|
||||
(data) => {
|
||||
frm.events.complete_job(frm, "Complete", data.qty);
|
||||
},
|
||||
__("Enter Value")
|
||||
);
|
||||
} else {
|
||||
frm.events.complete_job(frm, "Complete", 0.0);
|
||||
}
|
||||
@@ -285,64 +326,63 @@ frappe.ui.form.on('Job Card', {
|
||||
}
|
||||
},
|
||||
|
||||
start_job: function(frm, status, employee) {
|
||||
start_job: function (frm, status, employee) {
|
||||
const args = {
|
||||
job_card_id: frm.doc.name,
|
||||
start_time: frappe.datetime.now_datetime(),
|
||||
employees: employee,
|
||||
status: status
|
||||
status: status,
|
||||
};
|
||||
frm.events.make_time_log(frm, args);
|
||||
},
|
||||
|
||||
complete_job: function(frm, status, completed_qty) {
|
||||
complete_job: function (frm, status, completed_qty) {
|
||||
const args = {
|
||||
job_card_id: frm.doc.name,
|
||||
complete_time: frappe.datetime.now_datetime(),
|
||||
status: status,
|
||||
completed_qty: completed_qty
|
||||
completed_qty: completed_qty,
|
||||
};
|
||||
frm.events.make_time_log(frm, args);
|
||||
},
|
||||
|
||||
make_time_log: function(frm, args) {
|
||||
make_time_log: function (frm, args) {
|
||||
frm.events.update_sub_operation(frm, args);
|
||||
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.job_card.job_card.make_time_log",
|
||||
args: {
|
||||
args: args
|
||||
args: args,
|
||||
},
|
||||
freeze: true,
|
||||
callback: function () {
|
||||
frm.reload_doc();
|
||||
frm.trigger("make_dashboard");
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
update_sub_operation: function(frm, args) {
|
||||
update_sub_operation: function (frm, args) {
|
||||
if (frm.doc.sub_operations && frm.doc.sub_operations.length) {
|
||||
let sub_operations = frm.doc.sub_operations.filter(d => d.status != 'Complete');
|
||||
let sub_operations = frm.doc.sub_operations.filter((d) => d.status != "Complete");
|
||||
if (sub_operations && sub_operations.length) {
|
||||
args["sub_operation"] = sub_operations[0].sub_operation;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
validate: function(frm) {
|
||||
validate: function (frm) {
|
||||
if ((!frm.doc.time_logs || !frm.doc.time_logs.length) && frm.doc.started_time) {
|
||||
frm.trigger("reset_timer");
|
||||
}
|
||||
},
|
||||
|
||||
reset_timer: function(frm) {
|
||||
frm.set_value('started_time' , '');
|
||||
reset_timer: function (frm) {
|
||||
frm.set_value("started_time", "");
|
||||
},
|
||||
|
||||
make_dashboard: function(frm) {
|
||||
if(frm.doc.__islocal)
|
||||
return;
|
||||
make_dashboard: function (frm) {
|
||||
if (frm.doc.__islocal) return;
|
||||
|
||||
function setCurrentIncrement() {
|
||||
currentIncrement += 1;
|
||||
@@ -351,16 +391,22 @@ frappe.ui.form.on('Job Card', {
|
||||
|
||||
function updateStopwatch(increment) {
|
||||
var hours = Math.floor(increment / 3600);
|
||||
var minutes = Math.floor((increment - (hours * 3600)) / 60);
|
||||
var seconds = increment - (hours * 3600) - (minutes * 60);
|
||||
var minutes = Math.floor((increment - hours * 3600) / 60);
|
||||
var seconds = increment - hours * 3600 - minutes * 60;
|
||||
|
||||
$(section).find(".hours").text(hours < 10 ? ("0" + hours.toString()) : hours.toString());
|
||||
$(section).find(".minutes").text(minutes < 10 ? ("0" + minutes.toString()) : minutes.toString());
|
||||
$(section).find(".seconds").text(seconds < 10 ? ("0" + seconds.toString()) : seconds.toString());
|
||||
$(section)
|
||||
.find(".hours")
|
||||
.text(hours < 10 ? "0" + hours.toString() : hours.toString());
|
||||
$(section)
|
||||
.find(".minutes")
|
||||
.text(minutes < 10 ? "0" + minutes.toString() : minutes.toString());
|
||||
$(section)
|
||||
.find(".seconds")
|
||||
.text(seconds < 10 ? "0" + seconds.toString() : seconds.toString());
|
||||
}
|
||||
|
||||
function initialiseTimer() {
|
||||
const interval = setInterval(function() {
|
||||
const interval = setInterval(function () {
|
||||
var current = setCurrentIncrement();
|
||||
updateStopwatch(current);
|
||||
}, 1000);
|
||||
@@ -384,75 +430,76 @@ frappe.ui.form.on('Job Card', {
|
||||
if (frm.doc.status == "On Hold") {
|
||||
updateStopwatch(currentIncrement);
|
||||
} else {
|
||||
currentIncrement += moment(frappe.datetime.now_datetime()).diff(moment(frm.doc.started_time),"seconds");
|
||||
currentIncrement += moment(frappe.datetime.now_datetime()).diff(
|
||||
moment(frm.doc.started_time),
|
||||
"seconds"
|
||||
);
|
||||
initialiseTimer();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
hide_timer: function(frm) {
|
||||
hide_timer: function (frm) {
|
||||
frm.toolbar.page.inner_toolbar.find(".stopwatch").remove();
|
||||
},
|
||||
|
||||
for_quantity: function(frm) {
|
||||
for_quantity: function (frm) {
|
||||
frm.doc.items = [];
|
||||
frm.call({
|
||||
method: "get_required_items",
|
||||
doc: frm.doc,
|
||||
callback: function() {
|
||||
callback: function () {
|
||||
refresh_field("items");
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
make_material_request: function(frm) {
|
||||
make_material_request: function (frm) {
|
||||
frappe.model.open_mapped_doc({
|
||||
method: "erpnext.manufacturing.doctype.job_card.job_card.make_material_request",
|
||||
frm: frm,
|
||||
run_link_triggers: true
|
||||
run_link_triggers: true,
|
||||
});
|
||||
},
|
||||
|
||||
make_stock_entry: function(frm) {
|
||||
make_stock_entry: function (frm) {
|
||||
frappe.model.open_mapped_doc({
|
||||
method: "erpnext.manufacturing.doctype.job_card.job_card.make_stock_entry",
|
||||
frm: frm,
|
||||
run_link_triggers: true
|
||||
run_link_triggers: true,
|
||||
});
|
||||
},
|
||||
|
||||
timer: function(frm) {
|
||||
return `<button> Start </button>`
|
||||
timer: function (frm) {
|
||||
return `<button> Start </button>`;
|
||||
},
|
||||
|
||||
set_total_completed_qty: function(frm) {
|
||||
set_total_completed_qty: function (frm) {
|
||||
frm.doc.total_completed_qty = 0;
|
||||
frm.doc.time_logs.forEach(d => {
|
||||
frm.doc.time_logs.forEach((d) => {
|
||||
if (d.completed_qty) {
|
||||
frm.doc.total_completed_qty += d.completed_qty;
|
||||
}
|
||||
});
|
||||
|
||||
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)
|
||||
);
|
||||
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);
|
||||
frm.set_value("process_loss_qty", process_loss_qty);
|
||||
}
|
||||
|
||||
refresh_field("total_completed_qty");
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
frappe.ui.form.on('Job Card Time Log', {
|
||||
completed_qty: function(frm) {
|
||||
frappe.ui.form.on("Job Card Time Log", {
|
||||
completed_qty: function (frm) {
|
||||
frm.events.set_total_completed_qty(frm);
|
||||
},
|
||||
|
||||
to_time: function(frm) {
|
||||
frm.set_value('started_time', '');
|
||||
}
|
||||
})
|
||||
to_time: function (frm) {
|
||||
frm.set_value("started_time", "");
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
frappe.views.calendar["Job Card"] = {
|
||||
field_map: {
|
||||
"start": "from_time",
|
||||
"end": "to_time",
|
||||
"id": "name",
|
||||
"title": "subject",
|
||||
"color": "color",
|
||||
"allDay": "allDay",
|
||||
"progress": "progress"
|
||||
start: "from_time",
|
||||
end: "to_time",
|
||||
id: "name",
|
||||
title: "subject",
|
||||
color: "color",
|
||||
allDay: "allDay",
|
||||
progress: "progress",
|
||||
},
|
||||
gantt: {
|
||||
field_map: {
|
||||
"start": "expected_start_date",
|
||||
"end": "expected_end_date",
|
||||
"id": "name",
|
||||
"title": "subject",
|
||||
"color": "color",
|
||||
"allDay": "allDay",
|
||||
"progress": "progress"
|
||||
}
|
||||
start: "expected_start_date",
|
||||
end: "expected_end_date",
|
||||
id: "name",
|
||||
title: "subject",
|
||||
color: "color",
|
||||
allDay: "allDay",
|
||||
progress: "progress",
|
||||
},
|
||||
},
|
||||
filters: [
|
||||
{
|
||||
"fieldtype": "Link",
|
||||
"fieldname": "employee",
|
||||
"options": "Employee",
|
||||
"label": __("Employee")
|
||||
}
|
||||
fieldtype: "Link",
|
||||
fieldname: "employee",
|
||||
options: "Employee",
|
||||
label: __("Employee"),
|
||||
},
|
||||
],
|
||||
get_events_method: "erpnext.manufacturing.doctype.job_card.job_card.get_job_details"
|
||||
get_events_method: "erpnext.manufacturing.doctype.job_card.job_card.get_job_details",
|
||||
};
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
frappe.listview_settings['Job Card'] = {
|
||||
frappe.listview_settings["Job Card"] = {
|
||||
has_indicator_for_draft: true,
|
||||
add_fields: ["expected_start_date", "expected_end_date"],
|
||||
get_indicator: function(doc) {
|
||||
get_indicator: function (doc) {
|
||||
const status_colors = {
|
||||
"Work In Progress": "orange",
|
||||
"Completed": "green",
|
||||
"Cancelled": "red",
|
||||
Completed: "green",
|
||||
Cancelled: "red",
|
||||
"Material Transferred": "blue",
|
||||
"Open": "red",
|
||||
Open: "red",
|
||||
};
|
||||
const status = doc.status || "Open";
|
||||
const color = status_colors[status] || "blue";
|
||||
|
||||
return [__(status), color, `status,=,${status}`];
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,33 +1,40 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Manufacturing Settings', {
|
||||
});
|
||||
frappe.ui.form.on("Manufacturing Settings", {});
|
||||
|
||||
frappe.tour["Manufacturing Settings"] = [
|
||||
{
|
||||
fieldname: "material_consumption",
|
||||
title: __("Allow Multiple Material Consumption"),
|
||||
description: __("If ticked, multiple materials can be used for a single Work Order. This is useful if one or more time consuming products are being manufactured.")
|
||||
description: __(
|
||||
"If ticked, multiple materials can be used for a single Work Order. This is useful if one or more time consuming products are being manufactured."
|
||||
),
|
||||
},
|
||||
{
|
||||
fieldname: "backflush_raw_materials_based_on",
|
||||
title: __("Backflush Raw Materials"),
|
||||
description: __("The Stock Entry of type 'Manufacture' is known as backflush. Raw materials being consumed to manufacture finished goods is known as backflushing. <br><br> When creating Manufacture Entry, raw-material items are backflushed based on BOM of production item. If you want raw-material items to be backflushed based on Material Transfer entry made against that Work Order instead, then you can set it under this field.")
|
||||
description: __(
|
||||
"The Stock Entry of type 'Manufacture' is known as backflush. Raw materials being consumed to manufacture finished goods is known as backflushing. <br><br> When creating Manufacture Entry, raw-material items are backflushed based on BOM of production item. If you want raw-material items to be backflushed based on Material Transfer entry made against that Work Order instead, then you can set it under this field."
|
||||
),
|
||||
},
|
||||
{
|
||||
fieldname: "default_wip_warehouse",
|
||||
title: __("Work In Progress Warehouse"),
|
||||
description: __("This Warehouse will be auto-updated in the Work In Progress Warehouse field of Work Orders.")
|
||||
description: __(
|
||||
"This Warehouse will be auto-updated in the Work In Progress Warehouse field of Work Orders."
|
||||
),
|
||||
},
|
||||
{
|
||||
fieldname: "default_fg_warehouse",
|
||||
title: __("Finished Goods Warehouse"),
|
||||
description: __("This Warehouse will be auto-updated in the Target Warehouse field of Work Order.")
|
||||
description: __("This Warehouse will be auto-updated in the Target Warehouse field of Work Order."),
|
||||
},
|
||||
{
|
||||
fieldname: "update_bom_costs_automatically",
|
||||
title: __("Update BOM Cost Automatically"),
|
||||
description: __("If ticked, the BOM cost will be automatically updated based on Valuation Rate / Price List Rate / last purchase rate of raw materials.")
|
||||
}
|
||||
description: __(
|
||||
"If ticked, the BOM cost will be automatically updated based on Valuation Rate / Price List Rate / last purchase rate of raw materials."
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Material Request Plan Item', {
|
||||
refresh: function() {
|
||||
|
||||
}
|
||||
frappe.ui.form.on("Material Request Plan Item", {
|
||||
refresh: function () {},
|
||||
});
|
||||
|
||||
@@ -1,32 +1,34 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Operation', {
|
||||
setup: function(frm) {
|
||||
frm.set_query('operation', 'sub_operations', function() {
|
||||
frappe.ui.form.on("Operation", {
|
||||
setup: function (frm) {
|
||||
frm.set_query("operation", "sub_operations", function () {
|
||||
return {
|
||||
filters: {
|
||||
'name': ['not in', [frm.doc.name]]
|
||||
}
|
||||
name: ["not in", [frm.doc.name]],
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
frappe.tour['Operation'] = [
|
||||
frappe.tour["Operation"] = [
|
||||
{
|
||||
fieldname: "__newname",
|
||||
title: "Operation Name",
|
||||
description: __("Enter a name for the Operation, for example, Cutting.")
|
||||
description: __("Enter a name for the Operation, for example, Cutting."),
|
||||
},
|
||||
{
|
||||
fieldname: "workstation",
|
||||
title: "Default Workstation",
|
||||
description: __("Select the Default Workstation where the Operation will be performed. This will be fetched in BOMs and Work Orders.")
|
||||
description: __(
|
||||
"Select the Default Workstation where the Operation will be performed. This will be fetched in BOMs and Work Orders."
|
||||
),
|
||||
},
|
||||
{
|
||||
fieldname: "sub_operations",
|
||||
title: "Sub Operations",
|
||||
description: __("If an operation is divided into sub operations, they can be added here.")
|
||||
}
|
||||
description: __("If an operation is divided into sub operations, they can be added here."),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -14,16 +14,16 @@ frappe.ui.form.on("Plant Floor", {
|
||||
|
||||
return {
|
||||
filters: {
|
||||
"is_group": 0,
|
||||
"company": doc.company
|
||||
}
|
||||
}
|
||||
is_group: 0,
|
||||
company: doc.company,
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
refresh(frm) {
|
||||
frm.trigger('prepare_stock_dashboard')
|
||||
frm.trigger('prepare_workstation_dashboard')
|
||||
frm.trigger("prepare_stock_dashboard");
|
||||
frm.trigger("prepare_workstation_dashboard");
|
||||
},
|
||||
|
||||
prepare_workstation_dashboard(frm) {
|
||||
@@ -52,7 +52,6 @@ frappe.ui.form.on("Plant Floor", {
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
class VisualStock {
|
||||
constructor(opts) {
|
||||
Object.assign(this, opts);
|
||||
@@ -62,7 +61,7 @@ class VisualStock {
|
||||
make() {
|
||||
this.prepare_filters();
|
||||
this.prepare_stock_summary({
|
||||
start:0
|
||||
start: 0,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -81,17 +80,18 @@ class VisualStock {
|
||||
fieldname: "item_code",
|
||||
placeholder: __("Item"),
|
||||
options: "Item",
|
||||
onchange: () => this.prepare_stock_summary({
|
||||
start:0,
|
||||
item_code: this.item_filter.value
|
||||
})
|
||||
onchange: () =>
|
||||
this.prepare_stock_summary({
|
||||
start: 0,
|
||||
item_code: this.item_filter.value,
|
||||
}),
|
||||
},
|
||||
parent: this.wrapper.find('.filter-section'),
|
||||
parent: this.wrapper.find(".filter-section"),
|
||||
render_input: true,
|
||||
});
|
||||
|
||||
this.item_filter.$wrapper.addClass('form-column col-sm-3');
|
||||
this.item_filter.$wrapper.find('.clearfix').hide();
|
||||
this.item_filter.$wrapper.addClass("form-column col-sm-3");
|
||||
this.item_filter.$wrapper.find(".clearfix").hide();
|
||||
|
||||
this.item_group_filter = frappe.ui.form.make_control({
|
||||
df: {
|
||||
@@ -99,25 +99,28 @@ class VisualStock {
|
||||
fieldname: "item_group",
|
||||
placeholder: __("Item Group"),
|
||||
options: "Item Group",
|
||||
change: () => this.prepare_stock_summary({
|
||||
start:0,
|
||||
item_group: this.item_group_filter.value
|
||||
})
|
||||
change: () =>
|
||||
this.prepare_stock_summary({
|
||||
start: 0,
|
||||
item_group: this.item_group_filter.value,
|
||||
}),
|
||||
},
|
||||
parent: this.wrapper.find('.filter-section'),
|
||||
parent: this.wrapper.find(".filter-section"),
|
||||
render_input: true,
|
||||
});
|
||||
|
||||
this.item_group_filter.$wrapper.addClass('form-column col-sm-3');
|
||||
this.item_group_filter.$wrapper.find('.clearfix').hide();
|
||||
this.item_group_filter.$wrapper.addClass("form-column col-sm-3");
|
||||
this.item_group_filter.$wrapper.find(".clearfix").hide();
|
||||
}
|
||||
|
||||
prepare_stock_summary(args) {
|
||||
let {start, item_code, item_group} = args;
|
||||
let { start, item_code, item_group } = args;
|
||||
|
||||
this.get_stock_summary(start, item_code, item_group).then(stock_summary => {
|
||||
this.wrapper.find('.stock-summary-container').remove();
|
||||
this.wrapper.append(`<div class="col-sm-12 stock-summary-container" style="margin-bottom:20px"></div>`);
|
||||
this.get_stock_summary(start, item_code, item_group).then((stock_summary) => {
|
||||
this.wrapper.find(".stock-summary-container").remove();
|
||||
this.wrapper.append(
|
||||
`<div class="col-sm-12 stock-summary-container" style="margin-bottom:20px"></div>`
|
||||
);
|
||||
this.stock_summary = stock_summary.message;
|
||||
this.render_stock_summary();
|
||||
this.bind_events();
|
||||
@@ -131,8 +134,8 @@ class VisualStock {
|
||||
warehouse: this.frm.doc.warehouse,
|
||||
start: start,
|
||||
item_code: item_code,
|
||||
item_group: item_group
|
||||
}
|
||||
item_group: item_group,
|
||||
},
|
||||
});
|
||||
|
||||
return stock_summary;
|
||||
@@ -140,71 +143,80 @@ class VisualStock {
|
||||
|
||||
render_stock_summary() {
|
||||
let template = frappe.render_template("stock_summary_template", {
|
||||
stock_summary: this.stock_summary
|
||||
stock_summary: this.stock_summary,
|
||||
});
|
||||
|
||||
this.wrapper.find('.stock-summary-container').append(template);
|
||||
this.wrapper.find(".stock-summary-container").append(template);
|
||||
}
|
||||
|
||||
bind_events() {
|
||||
this.wrapper.find('.btn-add').click((e) => {
|
||||
this.item_code = decodeURI($(e.currentTarget).attr('data-item-code'));
|
||||
this.wrapper.find(".btn-add").click((e) => {
|
||||
this.item_code = decodeURI($(e.currentTarget).attr("data-item-code"));
|
||||
|
||||
this.make_stock_entry([
|
||||
{
|
||||
label: __("For Item"),
|
||||
fieldname: "item_code",
|
||||
fieldtype: "Data",
|
||||
read_only: 1,
|
||||
default: this.item_code
|
||||
},
|
||||
{
|
||||
label: __("Quantity"),
|
||||
fieldname: "qty",
|
||||
fieldtype: "Float",
|
||||
reqd: 1
|
||||
}
|
||||
], __("Add Stock"), "Material Receipt")
|
||||
this.make_stock_entry(
|
||||
[
|
||||
{
|
||||
label: __("For Item"),
|
||||
fieldname: "item_code",
|
||||
fieldtype: "Data",
|
||||
read_only: 1,
|
||||
default: this.item_code,
|
||||
},
|
||||
{
|
||||
label: __("Quantity"),
|
||||
fieldname: "qty",
|
||||
fieldtype: "Float",
|
||||
reqd: 1,
|
||||
},
|
||||
],
|
||||
__("Add Stock"),
|
||||
"Material Receipt"
|
||||
);
|
||||
});
|
||||
|
||||
this.wrapper.find('.btn-move').click((e) => {
|
||||
this.item_code = decodeURI($(e.currentTarget).attr('data-item-code'));
|
||||
this.wrapper.find(".btn-move").click((e) => {
|
||||
this.item_code = decodeURI($(e.currentTarget).attr("data-item-code"));
|
||||
|
||||
this.make_stock_entry([
|
||||
{
|
||||
label: __("For Item"),
|
||||
fieldname: "item_code",
|
||||
fieldtype: "Data",
|
||||
read_only: 1,
|
||||
default: this.item_code
|
||||
},
|
||||
{
|
||||
label: __("Quantity"),
|
||||
fieldname: "qty",
|
||||
fieldtype: "Float",
|
||||
reqd: 1
|
||||
},
|
||||
{
|
||||
label: __("To Warehouse"),
|
||||
fieldname: "to_warehouse",
|
||||
fieldtype: "Link",
|
||||
options: "Warehouse",
|
||||
reqd: 1,
|
||||
get_query: () => {
|
||||
return {
|
||||
filters: {
|
||||
"is_group": 0,
|
||||
"company": this.frm.doc.company
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
], __("Move Stock"), "Material Transfer")
|
||||
this.make_stock_entry(
|
||||
[
|
||||
{
|
||||
label: __("For Item"),
|
||||
fieldname: "item_code",
|
||||
fieldtype: "Data",
|
||||
read_only: 1,
|
||||
default: this.item_code,
|
||||
},
|
||||
{
|
||||
label: __("Quantity"),
|
||||
fieldname: "qty",
|
||||
fieldtype: "Float",
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
label: __("To Warehouse"),
|
||||
fieldname: "to_warehouse",
|
||||
fieldtype: "Link",
|
||||
options: "Warehouse",
|
||||
reqd: 1,
|
||||
get_query: () => {
|
||||
return {
|
||||
filters: {
|
||||
is_group: 0,
|
||||
company: this.frm.doc.company,
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
],
|
||||
__("Move Stock"),
|
||||
"Material Transfer"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
make_stock_entry(fields, title, stock_entry_type) {
|
||||
frappe.prompt(fields,
|
||||
frappe.prompt(
|
||||
fields,
|
||||
(values) => {
|
||||
this.values = values;
|
||||
this.stock_entry_type = stock_entry_type;
|
||||
@@ -221,9 +233,11 @@ class VisualStock {
|
||||
var doc = frappe.model.sync(r.message);
|
||||
frappe.set_route("Form", r.message.doctype, r.message.name);
|
||||
}
|
||||
}
|
||||
})
|
||||
}, __(title), __("Create")
|
||||
},
|
||||
});
|
||||
},
|
||||
__(title),
|
||||
__("Create")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -245,12 +259,12 @@ class VisualStock {
|
||||
this.values = {
|
||||
...this.values,
|
||||
...{
|
||||
"company": this.frm.doc.company,
|
||||
"item_code": this.item_code,
|
||||
"from_warehouse": from_warehouse,
|
||||
"to_warehouse": to_warehouse,
|
||||
"purpose": this.stock_entry_type,
|
||||
}
|
||||
}
|
||||
company: this.frm.doc.company,
|
||||
item_code: this.item_code,
|
||||
from_warehouse: from_warehouse,
|
||||
to_warehouse: to_warehouse,
|
||||
purpose: this.stock_entry_type,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Production Plan', {
|
||||
|
||||
frappe.ui.form.on("Production Plan", {
|
||||
before_save(frm) {
|
||||
// preserve temporary names on production plan item to re-link sub-assembly items
|
||||
frm.doc.po_items.forEach(item => {
|
||||
frm.doc.po_items.forEach((item) => {
|
||||
item.temporary_name = item.name;
|
||||
});
|
||||
},
|
||||
@@ -14,8 +13,8 @@ frappe.ui.form.on('Production Plan', {
|
||||
frm.trigger("setup_queries");
|
||||
|
||||
frm.custom_make_buttons = {
|
||||
'Work Order': 'Work Order / Subcontract PO',
|
||||
'Material Request': 'Material Request',
|
||||
"Work Order": "Work Order / Subcontract PO",
|
||||
"Material Request": "Material Request",
|
||||
};
|
||||
},
|
||||
|
||||
@@ -25,36 +24,36 @@ frappe.ui.form.on('Production Plan', {
|
||||
query: "erpnext.manufacturing.doctype.production_plan.production_plan.sales_order_query",
|
||||
filters: {
|
||||
company: frm.doc.company,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query('for_warehouse', function(doc) {
|
||||
frm.set_query("for_warehouse", function (doc) {
|
||||
return {
|
||||
filters: {
|
||||
company: doc.company,
|
||||
is_group: 0
|
||||
}
|
||||
}
|
||||
is_group: 0,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query('material_request', 'material_requests', function() {
|
||||
frm.set_query("material_request", "material_requests", function () {
|
||||
return {
|
||||
filters: {
|
||||
material_request_type: "Manufacture",
|
||||
docstatus: 1,
|
||||
status: ["!=", "Stopped"],
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("item_code", "po_items", (doc, cdt, cdn) => {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.item_query",
|
||||
filters:{
|
||||
'is_stock_item': 1,
|
||||
}
|
||||
}
|
||||
filters: {
|
||||
is_stock_item: 1,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("bom_no", "po_items", (doc, cdt, cdn) => {
|
||||
@@ -62,25 +61,25 @@ frappe.ui.form.on('Production Plan', {
|
||||
if (d.item_code) {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.bom",
|
||||
filters:{'item': d.item_code, 'docstatus': 1}
|
||||
}
|
||||
filters: { item: d.item_code, docstatus: 1 },
|
||||
};
|
||||
} else frappe.msgprint(__("Please enter Item first"));
|
||||
});
|
||||
|
||||
frm.set_query("warehouse", "mr_items", (doc) => {
|
||||
return {
|
||||
filters: {
|
||||
company: doc.company
|
||||
}
|
||||
}
|
||||
company: doc.company,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("warehouse", "po_items", (doc) => {
|
||||
return {
|
||||
filters: {
|
||||
company: doc.company
|
||||
}
|
||||
}
|
||||
company: doc.company,
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
@@ -89,36 +88,62 @@ frappe.ui.form.on('Production Plan', {
|
||||
frm.trigger("show_progress");
|
||||
|
||||
if (frm.doc.status !== "Completed") {
|
||||
frm.add_custom_button(__("Production Plan Summary"), ()=> {
|
||||
frappe.set_route('query-report', 'Production Plan Summary', {production_plan: frm.doc.name});
|
||||
}, __('View'));
|
||||
frm.add_custom_button(
|
||||
__("Production Plan Summary"),
|
||||
() => {
|
||||
frappe.set_route("query-report", "Production Plan Summary", {
|
||||
production_plan: frm.doc.name,
|
||||
});
|
||||
},
|
||||
__("View")
|
||||
);
|
||||
|
||||
if (frm.doc.status === "Closed") {
|
||||
frm.add_custom_button(__("Re-open"), function() {
|
||||
frm.events.close_open_production_plan(frm, false);
|
||||
}, __("Status"));
|
||||
if (frm.doc.status === "Closed") {
|
||||
frm.add_custom_button(
|
||||
__("Re-open"),
|
||||
function () {
|
||||
frm.events.close_open_production_plan(frm, false);
|
||||
},
|
||||
__("Status")
|
||||
);
|
||||
} else {
|
||||
frm.add_custom_button(__("Close"), function() {
|
||||
frm.events.close_open_production_plan(frm, true);
|
||||
}, __("Status"));
|
||||
frm.add_custom_button(
|
||||
__("Close"),
|
||||
function () {
|
||||
frm.events.close_open_production_plan(frm, true);
|
||||
},
|
||||
__("Status")
|
||||
);
|
||||
}
|
||||
|
||||
if (frm.doc.po_items && frm.doc.status !== "Closed") {
|
||||
frm.add_custom_button(__("Work Order / Subcontract PO"), ()=> {
|
||||
frm.trigger("make_work_order");
|
||||
}, __('Create'));
|
||||
frm.add_custom_button(
|
||||
__("Work Order / Subcontract PO"),
|
||||
() => {
|
||||
frm.trigger("make_work_order");
|
||||
},
|
||||
__("Create")
|
||||
);
|
||||
}
|
||||
|
||||
if (frm.doc.mr_items && frm.doc.mr_items.length && !in_list(['Material Requested', 'Closed'], frm.doc.status)) {
|
||||
frm.add_custom_button(__("Material Request"), ()=> {
|
||||
frm.trigger("make_material_request");
|
||||
}, __('Create'));
|
||||
if (
|
||||
frm.doc.mr_items &&
|
||||
frm.doc.mr_items.length &&
|
||||
!in_list(["Material Requested", "Closed"], frm.doc.status)
|
||||
) {
|
||||
frm.add_custom_button(
|
||||
__("Material Request"),
|
||||
() => {
|
||||
frm.trigger("make_material_request");
|
||||
},
|
||||
__("Create")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (frm.doc.status !== "Closed") {
|
||||
frm.page.set_inner_btn_group_as_primary(__('Create'));
|
||||
frm.page.set_inner_btn_group_as_primary(__("Create"));
|
||||
}
|
||||
frm.trigger("material_requirement");
|
||||
|
||||
@@ -145,19 +170,19 @@ frappe.ui.form.on('Production Plan', {
|
||||
${__("Planned Qty: Quantity, for which, Work Order has been raised, but is pending to be manufactured.")}
|
||||
</li>
|
||||
<li>
|
||||
${__('Requested Qty: Quantity requested for purchase, but not ordered.')}
|
||||
${__("Requested Qty: Quantity requested for purchase, but not ordered.")}
|
||||
</li>
|
||||
<li>
|
||||
${__('Ordered Qty: Quantity ordered for purchase, but not received.')}
|
||||
${__("Ordered Qty: Quantity ordered for purchase, but not received.")}
|
||||
</li>
|
||||
<li>
|
||||
${__("Reserved Qty: Quantity ordered for sale, but not delivered.")}
|
||||
</li>
|
||||
<li>
|
||||
${__('Reserved Qty for Production: Raw materials quantity to make manufacturing items.')}
|
||||
${__("Reserved Qty for Production: Raw materials quantity to make manufacturing items.")}
|
||||
</li>
|
||||
<li>
|
||||
${__('Reserved Qty for Subcontract: Raw materials quantity to make subcontracted items.')}
|
||||
${__("Reserved Qty for Subcontract: Raw materials quantity to make subcontracted items.")}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -168,15 +193,15 @@ frappe.ui.form.on('Production Plan', {
|
||||
set_field_options("projected_qty_formula", projected_qty_formula);
|
||||
},
|
||||
|
||||
close_open_production_plan(frm, close=false) {
|
||||
close_open_production_plan(frm, close = false) {
|
||||
frappe.call({
|
||||
method: "set_status",
|
||||
freeze: true,
|
||||
doc: frm.doc,
|
||||
args: {close : close, update_bin: true},
|
||||
callback: function() {
|
||||
args: { close: close, update_bin: true },
|
||||
callback: function () {
|
||||
frm.reload_doc();
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -185,19 +210,19 @@ frappe.ui.form.on('Production Plan', {
|
||||
method: "make_work_order",
|
||||
freeze: true,
|
||||
doc: frm.doc,
|
||||
callback: function() {
|
||||
callback: function () {
|
||||
frm.reload_doc();
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
make_material_request(frm) {
|
||||
|
||||
frappe.confirm(__("Do you want to submit the material request"),
|
||||
function() {
|
||||
frappe.confirm(
|
||||
__("Do you want to submit the material request"),
|
||||
function () {
|
||||
frm.events.create_material_request(frm, 1);
|
||||
},
|
||||
function() {
|
||||
function () {
|
||||
frm.events.create_material_request(frm, 0);
|
||||
}
|
||||
);
|
||||
@@ -210,9 +235,9 @@ frappe.ui.form.on('Production Plan', {
|
||||
method: "make_material_request",
|
||||
freeze: true,
|
||||
doc: frm.doc,
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
frm.reload_doc();
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -220,9 +245,9 @@ frappe.ui.form.on('Production Plan', {
|
||||
frappe.call({
|
||||
method: "get_open_sales_orders",
|
||||
doc: frm.doc,
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
refresh_field("sales_orders");
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -230,22 +255,22 @@ frappe.ui.form.on('Production Plan', {
|
||||
frappe.call({
|
||||
method: "get_pending_material_requests",
|
||||
doc: frm.doc,
|
||||
callback: function() {
|
||||
refresh_field('material_requests');
|
||||
}
|
||||
callback: function () {
|
||||
refresh_field("material_requests");
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
get_items(frm) {
|
||||
frm.clear_table('prod_plan_references');
|
||||
frm.clear_table("prod_plan_references");
|
||||
|
||||
frappe.call({
|
||||
method: "get_items",
|
||||
freeze: true,
|
||||
doc: frm.doc,
|
||||
callback: function () {
|
||||
refresh_field('po_items');
|
||||
}
|
||||
refresh_field("po_items");
|
||||
},
|
||||
});
|
||||
},
|
||||
combine_items(frm) {
|
||||
@@ -255,12 +280,12 @@ frappe.ui.form.on('Production Plan', {
|
||||
method: "get_items",
|
||||
freeze: true,
|
||||
doc: frm.doc,
|
||||
callback: function() {
|
||||
callback: function () {
|
||||
frm.refresh_field("po_items");
|
||||
if (frm.doc.sub_assembly_items.length > 0) {
|
||||
frm.trigger("get_sub_assembly_items");
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -278,9 +303,9 @@ frappe.ui.form.on('Production Plan', {
|
||||
method: "get_sub_assembly_items",
|
||||
freeze: true,
|
||||
doc: frm.doc,
|
||||
callback: function() {
|
||||
callback: function () {
|
||||
refresh_field("sub_assembly_items");
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -294,9 +319,11 @@ frappe.ui.form.on('Production Plan', {
|
||||
frappe.throw(__("Select the Warehouse"));
|
||||
}
|
||||
|
||||
frm.events.get_items_for_material_requests(frm, [{
|
||||
warehouse: frm.doc.for_warehouse
|
||||
}]);
|
||||
frm.events.get_items_for_material_requests(frm, [
|
||||
{
|
||||
warehouse: frm.doc.for_warehouse,
|
||||
},
|
||||
]);
|
||||
},
|
||||
|
||||
transfer_materials(frm) {
|
||||
@@ -315,26 +342,26 @@ frappe.ui.form.on('Production Plan', {
|
||||
title: title,
|
||||
fields: [
|
||||
{
|
||||
'label': __('Transfer From Warehouses'),
|
||||
'fieldtype': 'Table MultiSelect',
|
||||
'fieldname': 'warehouses',
|
||||
'options': 'Production Plan Material Request Warehouse',
|
||||
label: __("Transfer From Warehouses"),
|
||||
fieldtype: "Table MultiSelect",
|
||||
fieldname: "warehouses",
|
||||
options: "Production Plan Material Request Warehouse",
|
||||
get_query: function () {
|
||||
return {
|
||||
filters: {
|
||||
company: frm.doc.company
|
||||
}
|
||||
company: frm.doc.company,
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
'label': __('For Warehouse'),
|
||||
'fieldtype': 'Link',
|
||||
'fieldname': 'target_warehouse',
|
||||
'read_only': true,
|
||||
'default': frm.doc.for_warehouse
|
||||
}
|
||||
]
|
||||
label: __("For Warehouse"),
|
||||
fieldtype: "Link",
|
||||
fieldname: "target_warehouse",
|
||||
read_only: true,
|
||||
default: frm.doc.for_warehouse,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
@@ -353,82 +380,90 @@ frappe.ui.form.on('Production Plan', {
|
||||
freeze: true,
|
||||
args: {
|
||||
doc: frm.doc,
|
||||
warehouses: warehouses || []
|
||||
warehouses: warehouses || [],
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
frm.set_value('mr_items', []);
|
||||
r.message.forEach(row => {
|
||||
let d = frm.add_child('mr_items');
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
frm.set_value("mr_items", []);
|
||||
r.message.forEach((row) => {
|
||||
let d = frm.add_child("mr_items");
|
||||
for (let field in row) {
|
||||
if (field !== 'name') {
|
||||
if (field !== "name") {
|
||||
d[field] = row[field];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
refresh_field('mr_items');
|
||||
}
|
||||
refresh_field("mr_items");
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
download_materials_required(frm) {
|
||||
const fields = [{
|
||||
fieldname: 'warehouses',
|
||||
fieldtype: 'Table MultiSelect',
|
||||
label: __('Warehouses'),
|
||||
default: frm.doc.from_warehouse,
|
||||
options: "Production Plan Material Request Warehouse",
|
||||
get_query: function () {
|
||||
return {
|
||||
filters: {
|
||||
company: frm.doc.company
|
||||
}
|
||||
};
|
||||
const fields = [
|
||||
{
|
||||
fieldname: "warehouses",
|
||||
fieldtype: "Table MultiSelect",
|
||||
label: __("Warehouses"),
|
||||
default: frm.doc.from_warehouse,
|
||||
options: "Production Plan Material Request Warehouse",
|
||||
get_query: function () {
|
||||
return {
|
||||
filters: {
|
||||
company: frm.doc.company,
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
}];
|
||||
];
|
||||
|
||||
frappe.prompt(fields, (row) => {
|
||||
let get_template_url = 'erpnext.manufacturing.doctype.production_plan.production_plan.download_raw_materials';
|
||||
open_url_post(frappe.request.url, {
|
||||
cmd: get_template_url,
|
||||
doc: frm.doc,
|
||||
warehouses: row.warehouses
|
||||
});
|
||||
}, __('Select Warehouses to get Stock for Materials Planning'), __('Get Stock'));
|
||||
frappe.prompt(
|
||||
fields,
|
||||
(row) => {
|
||||
let get_template_url =
|
||||
"erpnext.manufacturing.doctype.production_plan.production_plan.download_raw_materials";
|
||||
open_url_post(frappe.request.url, {
|
||||
cmd: get_template_url,
|
||||
doc: frm.doc,
|
||||
warehouses: row.warehouses,
|
||||
});
|
||||
},
|
||||
__("Select Warehouses to get Stock for Materials Planning"),
|
||||
__("Get Stock")
|
||||
);
|
||||
},
|
||||
|
||||
show_progress(frm) {
|
||||
var bars = [];
|
||||
var message = '';
|
||||
var title = '';
|
||||
var message = "";
|
||||
var title = "";
|
||||
|
||||
// produced qty
|
||||
let item_wise_qty = {};
|
||||
frm.doc.po_items.forEach((data) => {
|
||||
if(!item_wise_qty[data.item_code]) {
|
||||
if (!item_wise_qty[data.item_code]) {
|
||||
item_wise_qty[data.item_code] = data.produced_qty;
|
||||
} else {
|
||||
item_wise_qty[data.item_code] += data.produced_qty;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
if (item_wise_qty) {
|
||||
for (var key in item_wise_qty) {
|
||||
title += __('Item {0}: {1} qty produced. ', [key, item_wise_qty[key]]);
|
||||
title += __("Item {0}: {1} qty produced. ", [key, item_wise_qty[key]]);
|
||||
}
|
||||
}
|
||||
|
||||
bars.push({
|
||||
'title': title,
|
||||
'width': (frm.doc.total_produced_qty / frm.doc.total_planned_qty * 100) + '%',
|
||||
'progress_class': 'progress-bar-success'
|
||||
title: title,
|
||||
width: (frm.doc.total_produced_qty / frm.doc.total_planned_qty) * 100 + "%",
|
||||
progress_class: "progress-bar-success",
|
||||
});
|
||||
if (bars[0].width == '0%') {
|
||||
bars[0].width = '0.5%';
|
||||
if (bars[0].width == "0%") {
|
||||
bars[0].width = "0.5%";
|
||||
}
|
||||
message = title;
|
||||
frm.dashboard.add_progress(__('Status'), bars, message);
|
||||
frm.dashboard.add_progress(__("Status"), bars, message);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -439,13 +474,13 @@ frappe.ui.form.on("Production Plan Item", {
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_item_data",
|
||||
args: {
|
||||
item_code: row.item_code
|
||||
item_code: row.item_code,
|
||||
},
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
for (let key in r.message) {
|
||||
frappe.model.set_value(cdt, cdn, key, r.message[key]);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -460,30 +495,29 @@ frappe.ui.form.on("Material Request Plan Item", {
|
||||
args: {
|
||||
row: row,
|
||||
company: frm.doc.company,
|
||||
for_warehouse: row.warehouse
|
||||
for_warehouse: row.warehouse,
|
||||
},
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
let {projected_qty, actual_qty} = r.message[0];
|
||||
let { projected_qty, actual_qty } = r.message[0];
|
||||
|
||||
frappe.model.set_value(cdt, cdn, {
|
||||
'projected_qty': projected_qty,
|
||||
'actual_qty': actual_qty
|
||||
projected_qty: projected_qty,
|
||||
actual_qty: actual_qty,
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
material_request_type(frm, cdt, cdn) {
|
||||
let row = locals[cdt][cdn];
|
||||
|
||||
if (row.from_warehouse &&
|
||||
row.material_request_type !== "Material Transfer") {
|
||||
frappe.model.set_value(cdt, cdn, 'from_warehouse', '');
|
||||
if (row.from_warehouse && row.material_request_type !== "Material Transfer") {
|
||||
frappe.model.set_value(cdt, cdn, "from_warehouse", "");
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Production Plan Sales Order", {
|
||||
@@ -506,53 +540,61 @@ frappe.ui.form.on("Production Plan Sales Order", {
|
||||
method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_so_details",
|
||||
args: { sales_order },
|
||||
callback(r) {
|
||||
const {transaction_date, customer, grand_total} = r.message;
|
||||
frappe.model.set_value(cdt, cdn, 'sales_order_date', transaction_date);
|
||||
frappe.model.set_value(cdt, cdn, 'customer', customer);
|
||||
frappe.model.set_value(cdt, cdn, 'grand_total', grand_total);
|
||||
}
|
||||
const { transaction_date, customer, grand_total } = r.message;
|
||||
frappe.model.set_value(cdt, cdn, "sales_order_date", transaction_date);
|
||||
frappe.model.set_value(cdt, cdn, "customer", customer);
|
||||
frappe.model.set_value(cdt, cdn, "grand_total", grand_total);
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Production Plan Sub Assembly Item", {
|
||||
fg_warehouse(frm, cdt, cdn) {
|
||||
erpnext.utils.copy_value_in_all_rows(frm.doc, cdt, cdn, "sub_assembly_items", "fg_warehouse");
|
||||
},
|
||||
})
|
||||
});
|
||||
|
||||
frappe.tour['Production Plan'] = [
|
||||
frappe.tour["Production Plan"] = [
|
||||
{
|
||||
fieldname: "get_items_from",
|
||||
title: "Get Items From",
|
||||
description: __("Select whether to get items from a Sales Order or a Material Request. For now select <b>Sales Order</b>.\n A Production Plan can also be created manually where you can select the Items to manufacture.")
|
||||
description: __(
|
||||
"Select whether to get items from a Sales Order or a Material Request. For now select <b>Sales Order</b>.\n A Production Plan can also be created manually where you can select the Items to manufacture."
|
||||
),
|
||||
},
|
||||
{
|
||||
fieldname: "get_sales_orders",
|
||||
title: "Get Sales Orders",
|
||||
description: __("Click on Get Sales Orders to fetch sales orders based on the above filters.")
|
||||
description: __("Click on Get Sales Orders to fetch sales orders based on the above filters."),
|
||||
},
|
||||
{
|
||||
fieldname: "get_items",
|
||||
title: "Get Finished Goods for Manufacture",
|
||||
description: __("Click on 'Get Finished Goods for Manufacture' to fetch the items from the above Sales Orders. Items only for which a BOM is present will be fetched.")
|
||||
description: __(
|
||||
"Click on 'Get Finished Goods for Manufacture' to fetch the items from the above Sales Orders. Items only for which a BOM is present will be fetched."
|
||||
),
|
||||
},
|
||||
{
|
||||
fieldname: "po_items",
|
||||
title: "Finished Goods",
|
||||
description: __("On expanding a row in the Items to Manufacture table, you'll see an option to 'Include Exploded Items'. Ticking this includes raw materials of the sub-assembly items in the production process.")
|
||||
description: __(
|
||||
"On expanding a row in the Items to Manufacture table, you'll see an option to 'Include Exploded Items'. Ticking this includes raw materials of the sub-assembly items in the production process."
|
||||
),
|
||||
},
|
||||
{
|
||||
fieldname: "include_non_stock_items",
|
||||
title: "Include Non Stock Items",
|
||||
description: __("To include non-stock items in the material request planning. i.e. Items for which 'Maintain Stock' checkbox is unticked.")
|
||||
description: __(
|
||||
"To include non-stock items in the material request planning. i.e. Items for which 'Maintain Stock' checkbox is unticked."
|
||||
),
|
||||
},
|
||||
{
|
||||
fieldname: "include_subcontracted_items",
|
||||
title: "Include Subcontracted Items",
|
||||
description: __("To add subcontracted Item's raw materials if include exploded items is disabled.")
|
||||
}
|
||||
description: __("To add subcontracted Item's raw materials if include exploded items is disabled."),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
frappe.listview_settings['Production Plan'] = {
|
||||
frappe.listview_settings["Production Plan"] = {
|
||||
hide_name_column: true,
|
||||
add_fields: ["status"],
|
||||
filters: [["status", "!=", "Closed"]],
|
||||
@@ -6,14 +6,18 @@ frappe.listview_settings['Production Plan'] = {
|
||||
if (doc.status === "Submitted") {
|
||||
return [__("Not Started"), "orange", "status,=,Submitted"];
|
||||
} else {
|
||||
return [__(doc.status), {
|
||||
"Draft": "red",
|
||||
"In Process": "orange",
|
||||
"Completed": "green",
|
||||
"Material Requested": "yellow",
|
||||
"Cancelled": "gray",
|
||||
"Closed": "grey"
|
||||
}[doc.status], "status,=," + doc.status];
|
||||
return [
|
||||
__(doc.status),
|
||||
{
|
||||
Draft: "red",
|
||||
"In Process": "orange",
|
||||
Completed: "green",
|
||||
"Material Requested": "yellow",
|
||||
Cancelled: "gray",
|
||||
Closed: "grey",
|
||||
}[doc.status],
|
||||
"status,=," + doc.status,
|
||||
];
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Production Plan Material Request Warehouse', {
|
||||
frappe.ui.form.on("Production Plan Material Request Warehouse", {
|
||||
// refresh: function(frm) {
|
||||
|
||||
// }
|
||||
});
|
||||
|
||||
@@ -1,38 +1,39 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Routing', {
|
||||
refresh: function(frm) {
|
||||
frappe.ui.form.on("Routing", {
|
||||
refresh: function (frm) {
|
||||
frm.trigger("display_sequence_id_column");
|
||||
},
|
||||
|
||||
onload: function(frm) {
|
||||
onload: function (frm) {
|
||||
frm.trigger("display_sequence_id_column");
|
||||
},
|
||||
|
||||
display_sequence_id_column: function(frm) {
|
||||
frm.fields_dict.operations.grid.update_docfield_property(
|
||||
'sequence_id', 'in_list_view', 1
|
||||
display_sequence_id_column: function (frm) {
|
||||
frm.fields_dict.operations.grid.update_docfield_property("sequence_id", "in_list_view", 1);
|
||||
},
|
||||
|
||||
calculate_operating_cost: function (frm, child) {
|
||||
const operating_cost = flt(
|
||||
(flt(child.hour_rate) * flt(child.time_in_mins)) / 60,
|
||||
precision("operating_cost", child)
|
||||
);
|
||||
},
|
||||
|
||||
calculate_operating_cost: function(frm, child) {
|
||||
const operating_cost = flt(flt(child.hour_rate) * flt(child.time_in_mins) / 60, precision("operating_cost", child));
|
||||
frappe.model.set_value(child.doctype, child.name, "operating_cost", operating_cost);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
frappe.ui.form.on('BOM Operation', {
|
||||
operation: function(frm, cdt, cdn) {
|
||||
frappe.ui.form.on("BOM Operation", {
|
||||
operation: function (frm, cdt, cdn) {
|
||||
const d = locals[cdt][cdn];
|
||||
|
||||
if(!d.operation) return;
|
||||
if (!d.operation) return;
|
||||
|
||||
frappe.call({
|
||||
"method": "frappe.client.get",
|
||||
method: "frappe.client.get",
|
||||
args: {
|
||||
doctype: "Operation",
|
||||
name: d.operation
|
||||
name: d.operation,
|
||||
},
|
||||
callback: function (data) {
|
||||
if (data.message.description) {
|
||||
@@ -44,41 +45,43 @@ frappe.ui.form.on('BOM Operation', {
|
||||
}
|
||||
|
||||
frm.events.calculate_operating_cost(frm, d);
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
workstation: function(frm, cdt, cdn) {
|
||||
workstation: function (frm, cdt, cdn) {
|
||||
const d = locals[cdt][cdn];
|
||||
if(!d.workstation) return;
|
||||
if (!d.workstation) return;
|
||||
frappe.call({
|
||||
"method": "frappe.client.get",
|
||||
method: "frappe.client.get",
|
||||
args: {
|
||||
doctype: "Workstation",
|
||||
name: d.workstation
|
||||
name: d.workstation,
|
||||
},
|
||||
callback: function (data) {
|
||||
frappe.model.set_value(d.doctype, d.name, "hour_rate", data.message.hour_rate);
|
||||
frm.events.calculate_operating_cost(frm, d);
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
time_in_mins: function(frm, cdt, cdn) {
|
||||
time_in_mins: function (frm, cdt, cdn) {
|
||||
const d = locals[cdt][cdn];
|
||||
frm.events.calculate_operating_cost(frm, d);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
frappe.tour['Routing'] = [
|
||||
frappe.tour["Routing"] = [
|
||||
{
|
||||
fieldname: "routing_name",
|
||||
title: "Routing Name",
|
||||
description: __("Enter a name for Routing.")
|
||||
description: __("Enter a name for Routing."),
|
||||
},
|
||||
{
|
||||
fieldname: "operations",
|
||||
title: "BOM Operations",
|
||||
description: __("Enter the Operation, the table will fetch the Operation details like Hourly Rate, Workstation automatically.\n\n After that, set the Operation Time in minutes and the table will calculate the Operation Costs based on the Hourly Rate and Operation Time.")
|
||||
}
|
||||
description: __(
|
||||
"Enter the Operation, the table will fetch the Operation details like Hourly Rate, Workstation automatically.\n\n After that, set the Operation Time in minutes and the table will calculate the Operation Costs based on the Hourly Rate and Operation Time."
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Sub Operation', {
|
||||
frappe.ui.form.on("Sub Operation", {
|
||||
// refresh: function(frm) {
|
||||
|
||||
// }
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,23 +2,23 @@
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.views.calendar["Work Order"] = {
|
||||
fields: ["planned_start_date", "planned_end_date", "status", "produced_qty", "qty", "name", "name"],
|
||||
fields: ["planned_start_date", "planned_end_date", "status", "produced_qty", "qty", "name", "name"],
|
||||
field_map: {
|
||||
"start": "planned_start_date",
|
||||
"end": "planned_end_date",
|
||||
"id": "name",
|
||||
"title": "name",
|
||||
"status": "status",
|
||||
"allDay": "allDay",
|
||||
"progress": function(data) {
|
||||
return flt(data.produced_qty) / data.qty * 100;
|
||||
}
|
||||
start: "planned_start_date",
|
||||
end: "planned_end_date",
|
||||
id: "name",
|
||||
title: "name",
|
||||
status: "status",
|
||||
allDay: "allDay",
|
||||
progress: function (data) {
|
||||
return (flt(data.produced_qty) / data.qty) * 100;
|
||||
},
|
||||
},
|
||||
gantt: true,
|
||||
get_css_class: function(data) {
|
||||
if(data.status==="Completed") {
|
||||
get_css_class: function (data) {
|
||||
if (data.status === "Completed") {
|
||||
return "success";
|
||||
} else if(data.status==="In Process") {
|
||||
} else if (data.status === "In Process") {
|
||||
return "warning";
|
||||
} else {
|
||||
return "danger";
|
||||
@@ -26,23 +26,23 @@ frappe.views.calendar["Work Order"] = {
|
||||
},
|
||||
filters: [
|
||||
{
|
||||
"fieldtype": "Link",
|
||||
"fieldname": "sales_order",
|
||||
"options": "Sales Order",
|
||||
"label": __("Sales Order")
|
||||
fieldtype: "Link",
|
||||
fieldname: "sales_order",
|
||||
options: "Sales Order",
|
||||
label: __("Sales Order"),
|
||||
},
|
||||
{
|
||||
"fieldtype": "Link",
|
||||
"fieldname": "production_item",
|
||||
"options": "Item",
|
||||
"label": __("Production Item")
|
||||
fieldtype: "Link",
|
||||
fieldname: "production_item",
|
||||
options: "Item",
|
||||
label: __("Production Item"),
|
||||
},
|
||||
{
|
||||
"fieldtype": "Link",
|
||||
"fieldname": "wip_warehouse",
|
||||
"options": "Warehouse",
|
||||
"label": __("WIP Warehouse")
|
||||
}
|
||||
fieldtype: "Link",
|
||||
fieldname: "wip_warehouse",
|
||||
options: "Warehouse",
|
||||
label: __("WIP Warehouse"),
|
||||
},
|
||||
],
|
||||
get_events_method: "frappe.desk.calendar.get_events"
|
||||
}
|
||||
get_events_method: "frappe.desk.calendar.get_events",
|
||||
};
|
||||
|
||||
@@ -1,19 +1,31 @@
|
||||
frappe.listview_settings['Work Order'] = {
|
||||
add_fields: ["bom_no", "status", "sales_order", "qty",
|
||||
"produced_qty", "expected_delivery_date", "planned_start_date", "planned_end_date"],
|
||||
frappe.listview_settings["Work Order"] = {
|
||||
add_fields: [
|
||||
"bom_no",
|
||||
"status",
|
||||
"sales_order",
|
||||
"qty",
|
||||
"produced_qty",
|
||||
"expected_delivery_date",
|
||||
"planned_start_date",
|
||||
"planned_end_date",
|
||||
],
|
||||
filters: [["status", "!=", "Stopped"]],
|
||||
get_indicator: function(doc) {
|
||||
if(doc.status==="Submitted") {
|
||||
get_indicator: function (doc) {
|
||||
if (doc.status === "Submitted") {
|
||||
return [__("Not Started"), "orange", "status,=,Submitted"];
|
||||
} else {
|
||||
return [__(doc.status), {
|
||||
"Draft": "red",
|
||||
"Stopped": "red",
|
||||
"Not Started": "red",
|
||||
"In Process": "orange",
|
||||
"Completed": "green",
|
||||
"Cancelled": "gray"
|
||||
}[doc.status], "status,=," + doc.status];
|
||||
return [
|
||||
__(doc.status),
|
||||
{
|
||||
Draft: "red",
|
||||
Stopped: "red",
|
||||
"Not Started": "red",
|
||||
"In Process": "orange",
|
||||
Completed: "green",
|
||||
Cancelled: "gray",
|
||||
}[doc.status],
|
||||
"status,=," + doc.status,
|
||||
];
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
@@ -8,16 +7,16 @@ QUnit.test("test: Workstation", function (assert) {
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially('Workstation', [
|
||||
frappe.run_serially("Workstation", [
|
||||
// insert a new Workstation
|
||||
() => frappe.tests.make([
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() =>
|
||||
frappe.tests.make([
|
||||
// values to be set
|
||||
{ key: "value" },
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
assert.equal(cur_frm.doc.key, "value");
|
||||
},
|
||||
() => done()
|
||||
() => done(),
|
||||
]);
|
||||
|
||||
});
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
|
||||
frappe.ui.form.on("Workstation", {
|
||||
set_illustration_image(frm) {
|
||||
let status_image_field = frm.doc.status == "Production" ? frm.doc.on_status_image : frm.doc.off_status_image;
|
||||
let status_image_field =
|
||||
frm.doc.status == "Production" ? frm.doc.on_status_image : frm.doc.off_status_image;
|
||||
if (status_image_field) {
|
||||
frm.sidebar.image_wrapper.find(".sidebar-image").attr("src", status_image_field);
|
||||
}
|
||||
@@ -20,22 +21,21 @@ frappe.ui.form.on("Workstation", {
|
||||
|
||||
let workstation_dashboard = new WorkstationDashboard({
|
||||
wrapper: $parent,
|
||||
frm: frm
|
||||
frm: frm,
|
||||
});
|
||||
},
|
||||
|
||||
onload(frm) {
|
||||
if(frm.is_new())
|
||||
{
|
||||
if (frm.is_new()) {
|
||||
frappe.call({
|
||||
type:"GET",
|
||||
method:"erpnext.manufacturing.doctype.workstation.workstation.get_default_holiday_list",
|
||||
callback: function(r) {
|
||||
if(!r.exe && r.message){
|
||||
type: "GET",
|
||||
method: "erpnext.manufacturing.doctype.workstation.workstation.get_default_holiday_list",
|
||||
callback: function (r) {
|
||||
if (!r.exe && r.message) {
|
||||
cur_frm.set_value("holiday_list", r.message);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -44,40 +44,43 @@ frappe.ui.form.on("Workstation", {
|
||||
frm.call({
|
||||
method: "set_data_based_on_workstation_type",
|
||||
doc: frm.doc,
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
frm.refresh_fields();
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
frappe.tour['Workstation'] = [
|
||||
frappe.tour["Workstation"] = [
|
||||
{
|
||||
fieldname: "workstation_name",
|
||||
title: "Workstation Name",
|
||||
description: __("You can set it as a machine name or operation type. For example, stiching machine 12")
|
||||
description: __(
|
||||
"You can set it as a machine name or operation type. For example, stiching machine 12"
|
||||
),
|
||||
},
|
||||
{
|
||||
fieldname: "production_capacity",
|
||||
title: "Production Capacity",
|
||||
description: __("No. of parallel job cards which can be allowed on this workstation. Example: 2 would mean this workstation can process production for two Work Orders at a time.")
|
||||
description: __(
|
||||
"No. of parallel job cards which can be allowed on this workstation. Example: 2 would mean this workstation can process production for two Work Orders at a time."
|
||||
),
|
||||
},
|
||||
{
|
||||
fieldname: "holiday_list",
|
||||
title: "Holiday List",
|
||||
description: __("A Holiday List can be added to exclude counting these days for the Workstation.")
|
||||
description: __("A Holiday List can be added to exclude counting these days for the Workstation."),
|
||||
},
|
||||
{
|
||||
fieldname: "working_hours",
|
||||
title: "Working Hours",
|
||||
description: __("Under Working Hours table, you can add start and end times for a Workstation. For example, a Workstation may be active from 9 am to 1 pm, then 2 pm to 5 pm. You can also specify the working hours based on shifts. While scheduling a Work Order, the system will check for the availability of the Workstation based on the working hours specified.")
|
||||
description: __(
|
||||
"Under Working Hours table, you can add start and end times for a Workstation. For example, a Workstation may be active from 9 am to 1 pm, then 2 pm to 5 pm. You can also specify the working hours based on shifts. While scheduling a Work Order, the system will check for the availability of the Workstation based on the working hours specified."
|
||||
),
|
||||
},
|
||||
|
||||
|
||||
];
|
||||
|
||||
|
||||
class WorkstationDashboard {
|
||||
constructor({ wrapper, frm }) {
|
||||
this.$wrapper = $(wrapper);
|
||||
@@ -90,20 +93,20 @@ class WorkstationDashboard {
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.workstation.workstation.get_job_cards",
|
||||
args: {
|
||||
workstation: this.frm.doc.name
|
||||
workstation: this.frm.doc.name,
|
||||
},
|
||||
callback: (r) => {
|
||||
if (r.message) {
|
||||
this.job_cards = r.message;
|
||||
this.render_job_cards();
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
render_job_cards() {
|
||||
let template = frappe.render_template("workstation_job_card", {
|
||||
data: this.job_cards
|
||||
let template = frappe.render_template("workstation_job_card", {
|
||||
data: this.job_cards,
|
||||
});
|
||||
|
||||
this.$wrapper.html(template);
|
||||
@@ -114,11 +117,18 @@ class WorkstationDashboard {
|
||||
|
||||
toggle_job_card() {
|
||||
this.$wrapper.find(".collapse-indicator-job").on("click", (e) => {
|
||||
$(e.currentTarget).closest(".form-dashboard-section").find(".section-body-job-card").toggleClass("hide")
|
||||
if ($(e.currentTarget).closest(".form-dashboard-section").find(".section-body-job-card").hasClass("hide"))
|
||||
$(e.currentTarget).html(frappe.utils.icon("es-line-down", "sm", "mb-1"))
|
||||
else
|
||||
$(e.currentTarget).html(frappe.utils.icon("es-line-up", "sm", "mb-1"))
|
||||
$(e.currentTarget)
|
||||
.closest(".form-dashboard-section")
|
||||
.find(".section-body-job-card")
|
||||
.toggleClass("hide");
|
||||
if (
|
||||
$(e.currentTarget)
|
||||
.closest(".form-dashboard-section")
|
||||
.find(".section-body-job-card")
|
||||
.hasClass("hide")
|
||||
)
|
||||
$(e.currentTarget).html(frappe.utils.icon("es-line-down", "sm", "mb-1"));
|
||||
else $(e.currentTarget).html(frappe.utils.icon("es-line-up", "sm", "mb-1"));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -142,80 +152,90 @@ class WorkstationDashboard {
|
||||
|
||||
start_job(job_card) {
|
||||
let me = this;
|
||||
frappe.prompt([
|
||||
{
|
||||
fieldtype: 'Datetime',
|
||||
label: __('Start Time'),
|
||||
fieldname: 'start_time',
|
||||
reqd: 1,
|
||||
default: frappe.datetime.now_datetime()
|
||||
},
|
||||
{
|
||||
label: __('Operator'),
|
||||
fieldname: 'employee',
|
||||
fieldtype: 'Link',
|
||||
options: 'Employee',
|
||||
}
|
||||
], data => {
|
||||
this.frm.call({
|
||||
method: "start_job",
|
||||
doc: this.frm.doc,
|
||||
args: {
|
||||
job_card: job_card,
|
||||
from_time: data.start_time,
|
||||
employee: data.employee,
|
||||
frappe.prompt(
|
||||
[
|
||||
{
|
||||
fieldtype: "Datetime",
|
||||
label: __("Start Time"),
|
||||
fieldname: "start_time",
|
||||
reqd: 1,
|
||||
default: frappe.datetime.now_datetime(),
|
||||
},
|
||||
callback(r) {
|
||||
if (r.message) {
|
||||
me.job_cards = [r.message];
|
||||
me.prepare_timer()
|
||||
me.update_job_card_details();
|
||||
}
|
||||
}
|
||||
});
|
||||
}, __("Enter Value"), __("Start Job"));
|
||||
{
|
||||
label: __("Operator"),
|
||||
fieldname: "employee",
|
||||
fieldtype: "Link",
|
||||
options: "Employee",
|
||||
},
|
||||
],
|
||||
(data) => {
|
||||
this.frm.call({
|
||||
method: "start_job",
|
||||
doc: this.frm.doc,
|
||||
args: {
|
||||
job_card: job_card,
|
||||
from_time: data.start_time,
|
||||
employee: data.employee,
|
||||
},
|
||||
callback(r) {
|
||||
if (r.message) {
|
||||
me.job_cards = [r.message];
|
||||
me.prepare_timer();
|
||||
me.update_job_card_details();
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
__("Enter Value"),
|
||||
__("Start Job")
|
||||
);
|
||||
}
|
||||
|
||||
complete_job(job_card, qty_to_manufacture) {
|
||||
let me = this;
|
||||
let fields = [
|
||||
{
|
||||
fieldtype: 'Float',
|
||||
label: __('Completed Quantity'),
|
||||
fieldname: 'qty',
|
||||
fieldtype: "Float",
|
||||
label: __("Completed Quantity"),
|
||||
fieldname: "qty",
|
||||
reqd: 1,
|
||||
default: flt(qty_to_manufacture || 0)
|
||||
default: flt(qty_to_manufacture || 0),
|
||||
},
|
||||
{
|
||||
fieldtype: 'Datetime',
|
||||
label: __('End Time'),
|
||||
fieldname: 'end_time',
|
||||
default: frappe.datetime.now_datetime()
|
||||
fieldtype: "Datetime",
|
||||
label: __("End Time"),
|
||||
fieldname: "end_time",
|
||||
default: frappe.datetime.now_datetime(),
|
||||
},
|
||||
];
|
||||
|
||||
frappe.prompt(fields, data => {
|
||||
if (data.qty <= 0) {
|
||||
frappe.throw(__("Quantity should be greater than 0"));
|
||||
}
|
||||
|
||||
this.frm.call({
|
||||
method: "complete_job",
|
||||
doc: this.frm.doc,
|
||||
args: {
|
||||
job_card: job_card,
|
||||
qty: data.qty,
|
||||
to_time: data.end_time,
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r.message) {
|
||||
me.job_cards = [r.message];
|
||||
me.prepare_timer()
|
||||
me.update_job_card_details();
|
||||
}
|
||||
frappe.prompt(
|
||||
fields,
|
||||
(data) => {
|
||||
if (data.qty <= 0) {
|
||||
frappe.throw(__("Quantity should be greater than 0"));
|
||||
}
|
||||
});
|
||||
}, __("Enter Value"), __("Submit"));
|
||||
|
||||
this.frm.call({
|
||||
method: "complete_job",
|
||||
doc: this.frm.doc,
|
||||
args: {
|
||||
job_card: job_card,
|
||||
qty: data.qty,
|
||||
to_time: data.end_time,
|
||||
},
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
me.job_cards = [r.message];
|
||||
me.prepare_timer();
|
||||
me.update_job_card_details();
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
__("Enter Value"),
|
||||
__("Submit")
|
||||
);
|
||||
}
|
||||
|
||||
make_material_request(job_card) {
|
||||
@@ -229,7 +249,7 @@ class WorkstationDashboard {
|
||||
var doc = frappe.model.sync(r.message)[0];
|
||||
frappe.set_route("Form", doc.doctype, doc.name);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -248,18 +268,17 @@ class WorkstationDashboard {
|
||||
|
||||
update_job_card_details() {
|
||||
let color_map = {
|
||||
"Pending": "var(--bg-blue)",
|
||||
Pending: "var(--bg-blue)",
|
||||
"In Process": "var(--bg-yellow)",
|
||||
"Submitted": "var(--bg-blue)",
|
||||
"Open": "var(--bg-gray)",
|
||||
"Closed": "var(--bg-green)",
|
||||
Submitted: "var(--bg-blue)",
|
||||
Open: "var(--bg-gray)",
|
||||
Closed: "var(--bg-green)",
|
||||
"Work In Progress": "var(--bg-orange)",
|
||||
}
|
||||
};
|
||||
|
||||
this.job_cards.forEach((data) => {
|
||||
let job_card_selector = this.$wrapper.find(`
|
||||
[data-name='${data.name}']`
|
||||
);
|
||||
let job_card_selector = this.$wrapper.find(`
|
||||
[data-name='${data.name}']`);
|
||||
|
||||
$(job_card_selector).find(".job-card-status").text(data.status);
|
||||
$(job_card_selector).find(".job-card-status").css("backgroundColor", color_map[data.status]);
|
||||
@@ -284,20 +303,26 @@ class WorkstationDashboard {
|
||||
updateStopwatch(data) {
|
||||
let increment = data._current_time;
|
||||
let hours = Math.floor(increment / 3600);
|
||||
let minutes = Math.floor((increment - (hours * 3600)) / 60);
|
||||
let seconds = cint(increment - (hours * 3600) - (minutes * 60));
|
||||
let minutes = Math.floor((increment - hours * 3600) / 60);
|
||||
let seconds = cint(increment - hours * 3600 - minutes * 60);
|
||||
|
||||
let job_card_selector = `[data-job-card='${data.name}']`
|
||||
let timer_selector = this.$wrapper.find(job_card_selector)
|
||||
let job_card_selector = `[data-job-card='${data.name}']`;
|
||||
let timer_selector = this.$wrapper.find(job_card_selector);
|
||||
|
||||
$(timer_selector).find(".hours").text(hours < 10 ? ("0" + hours.toString()) : hours.toString());
|
||||
$(timer_selector).find(".minutes").text(minutes < 10 ? ("0" + minutes.toString()) : minutes.toString());
|
||||
$(timer_selector).find(".seconds").text(seconds < 10 ? ("0" + seconds.toString()) : seconds.toString());
|
||||
$(timer_selector)
|
||||
.find(".hours")
|
||||
.text(hours < 10 ? "0" + hours.toString() : hours.toString());
|
||||
$(timer_selector)
|
||||
.find(".minutes")
|
||||
.text(minutes < 10 ? "0" + minutes.toString() : minutes.toString());
|
||||
$(timer_selector)
|
||||
.find(".seconds")
|
||||
.text(seconds < 10 ? "0" + seconds.toString() : seconds.toString());
|
||||
}
|
||||
|
||||
get_current_time(data) {
|
||||
let current_time = 0.0;
|
||||
data.time_logs.forEach(d => {
|
||||
data.time_logs.forEach((d) => {
|
||||
if (d.to_time) {
|
||||
if (d.time_in_mins) {
|
||||
current_time += flt(d.time_in_mins, 2) * 60;
|
||||
@@ -315,4 +340,4 @@ class WorkstationDashboard {
|
||||
get_seconds_diff(d1, d2) {
|
||||
return moment(d1).diff(d2, "seconds");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
|
||||
frappe.listview_settings['Workstation'] = {
|
||||
frappe.listview_settings["Workstation"] = {
|
||||
add_fields: ["status"],
|
||||
get_indicator: function(doc) {
|
||||
get_indicator: function (doc) {
|
||||
let color_map = {
|
||||
"Production": "green",
|
||||
"Off": "gray",
|
||||
"Idle": "gray",
|
||||
"Problem": "red",
|
||||
"Maintenance": "yellow",
|
||||
"Setup": "blue",
|
||||
}
|
||||
Production: "green",
|
||||
Off: "gray",
|
||||
Idle: "gray",
|
||||
Problem: "red",
|
||||
Maintenance: "yellow",
|
||||
Setup: "blue",
|
||||
};
|
||||
|
||||
return [__(doc.status), color_map[doc.status], true];
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Workstation Type', {
|
||||
frappe.ui.form.on("Workstation Type", {
|
||||
// refresh: function(frm) {
|
||||
|
||||
// }
|
||||
});
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
frappe.pages['bom-comparison-tool'].on_page_load = function(wrapper) {
|
||||
frappe.pages["bom-comparison-tool"].on_page_load = function (wrapper) {
|
||||
var page = frappe.ui.make_app_page({
|
||||
parent: wrapper,
|
||||
title: __('BOM Comparison Tool'),
|
||||
single_column: true
|
||||
title: __("BOM Comparison Tool"),
|
||||
single_column: true,
|
||||
});
|
||||
|
||||
new erpnext.BOMComparisonTool(page);
|
||||
}
|
||||
};
|
||||
|
||||
erpnext.BOMComparisonTool = class BOMComparisonTool {
|
||||
constructor(page) {
|
||||
@@ -18,45 +18,45 @@ erpnext.BOMComparisonTool = class BOMComparisonTool {
|
||||
this.form = new frappe.ui.FieldGroup({
|
||||
fields: [
|
||||
{
|
||||
label: __('BOM 1'),
|
||||
fieldname: 'name1',
|
||||
fieldtype: 'Link',
|
||||
options: 'BOM',
|
||||
label: __("BOM 1"),
|
||||
fieldname: "name1",
|
||||
fieldtype: "Link",
|
||||
options: "BOM",
|
||||
change: () => this.fetch_and_render(),
|
||||
get_query: () => {
|
||||
return {
|
||||
filters: {
|
||||
"name": ["not in", [this.form.get_value("name2") || ""]]
|
||||
}
|
||||
}
|
||||
}
|
||||
name: ["not in", [this.form.get_value("name2") || ""]],
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldtype: 'Column Break'
|
||||
fieldtype: "Column Break",
|
||||
},
|
||||
{
|
||||
label: __('BOM 2'),
|
||||
fieldname: 'name2',
|
||||
fieldtype: 'Link',
|
||||
options: 'BOM',
|
||||
label: __("BOM 2"),
|
||||
fieldname: "name2",
|
||||
fieldtype: "Link",
|
||||
options: "BOM",
|
||||
change: () => this.fetch_and_render(),
|
||||
get_query: () => {
|
||||
return {
|
||||
filters: {
|
||||
"name": ["not in", [this.form.get_value("name1") || ""]]
|
||||
}
|
||||
}
|
||||
}
|
||||
name: ["not in", [this.form.get_value("name1") || ""]],
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldtype: 'Section Break'
|
||||
fieldtype: "Section Break",
|
||||
},
|
||||
{
|
||||
fieldtype: 'HTML',
|
||||
fieldname: 'preview'
|
||||
}
|
||||
fieldtype: "HTML",
|
||||
fieldname: "preview",
|
||||
},
|
||||
],
|
||||
body: this.page.body
|
||||
body: this.page.body,
|
||||
});
|
||||
this.form.make();
|
||||
}
|
||||
@@ -64,33 +64,34 @@ erpnext.BOMComparisonTool = class BOMComparisonTool {
|
||||
fetch_and_render() {
|
||||
let { name1, name2 } = this.form.get_values();
|
||||
if (!(name1 && name2)) {
|
||||
this.form.get_field('preview').html('');
|
||||
this.form.get_field("preview").html("");
|
||||
return;
|
||||
}
|
||||
|
||||
// set working state
|
||||
this.form.get_field('preview').html(`
|
||||
this.form.get_field("preview").html(`
|
||||
<div class="text-muted margin-top">
|
||||
${__("Fetching...")}
|
||||
</div>
|
||||
`);
|
||||
|
||||
frappe.call('erpnext.manufacturing.doctype.bom.bom.get_bom_diff', {
|
||||
bom1: name1,
|
||||
bom2: name2
|
||||
}).then(r => {
|
||||
let diff = r.message;
|
||||
frappe.model.with_doctype('BOM', () => {
|
||||
this.render('BOM', name1, name2, diff);
|
||||
frappe
|
||||
.call("erpnext.manufacturing.doctype.bom.bom.get_bom_diff", {
|
||||
bom1: name1,
|
||||
bom2: name2,
|
||||
})
|
||||
.then((r) => {
|
||||
let diff = r.message;
|
||||
frappe.model.with_doctype("BOM", () => {
|
||||
this.render("BOM", name1, name2, diff);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
render(doctype, name1, name2, diff) {
|
||||
|
||||
let change_html = (title, doctype, changed) => {
|
||||
let values_changed = this.get_changed_values(doctype, changed)
|
||||
.map(change => {
|
||||
.map((change) => {
|
||||
let [fieldname, value1, value2] = change;
|
||||
return `
|
||||
<tr>
|
||||
@@ -100,14 +101,14 @@ erpnext.BOMComparisonTool = class BOMComparisonTool {
|
||||
</tr>
|
||||
`;
|
||||
})
|
||||
.join('');
|
||||
.join("");
|
||||
|
||||
return `
|
||||
<h4 class="margin-top">${title}</h4>
|
||||
<div>
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
<th width="33%">${__('Field')}</th>
|
||||
<th width="33%">${__("Field")}</th>
|
||||
<th width="33%">${name1}</th>
|
||||
<th width="33%">${name2}</th>
|
||||
</tr>
|
||||
@@ -115,28 +116,30 @@ erpnext.BOMComparisonTool = class BOMComparisonTool {
|
||||
</table>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
};
|
||||
|
||||
let value_changes = change_html(__('Values Changed'), doctype, diff.changed);
|
||||
let value_changes = change_html(__("Values Changed"), doctype, diff.changed);
|
||||
|
||||
let row_changes_by_fieldname = group_items(diff.row_changed, change => change[0]);
|
||||
let row_changes_by_fieldname = group_items(diff.row_changed, (change) => change[0]);
|
||||
|
||||
let table_changes = Object.keys(row_changes_by_fieldname).map(fieldname => {
|
||||
let changes = row_changes_by_fieldname[fieldname];
|
||||
let df = frappe.meta.get_docfield(doctype, fieldname);
|
||||
|
||||
let html = changes.map(change => {
|
||||
let [fieldname,, item_code, changes] = change;
|
||||
let table_changes = Object.keys(row_changes_by_fieldname)
|
||||
.map((fieldname) => {
|
||||
let changes = row_changes_by_fieldname[fieldname];
|
||||
let df = frappe.meta.get_docfield(doctype, fieldname);
|
||||
let child_doctype = df.options;
|
||||
let values_changed = this.get_changed_values(child_doctype, changes);
|
||||
|
||||
return values_changed.map((change, i) => {
|
||||
let [fieldname, value1, value2] = change;
|
||||
let th = i === 0
|
||||
? `<th rowspan="${values_changed.length}">${item_code}</th>`
|
||||
: '';
|
||||
return `
|
||||
let html = changes
|
||||
.map((change) => {
|
||||
let [fieldname, , item_code, changes] = change;
|
||||
let df = frappe.meta.get_docfield(doctype, fieldname);
|
||||
let child_doctype = df.options;
|
||||
let values_changed = this.get_changed_values(child_doctype, changes);
|
||||
|
||||
return values_changed
|
||||
.map((change, i) => {
|
||||
let [fieldname, value1, value2] = change;
|
||||
let th =
|
||||
i === 0 ? `<th rowspan="${values_changed.length}">${item_code}</th>` : "";
|
||||
return `
|
||||
<tr>
|
||||
${th}
|
||||
<td>${frappe.meta.get_label(child_doctype, fieldname)}</td>
|
||||
@@ -144,54 +147,58 @@ erpnext.BOMComparisonTool = class BOMComparisonTool {
|
||||
<td>${value2}</td>
|
||||
</tr>
|
||||
`;
|
||||
}).join('');
|
||||
}).join('');
|
||||
})
|
||||
.join("");
|
||||
})
|
||||
.join("");
|
||||
|
||||
return `
|
||||
<h4 class="margin-top">${__('Changes in {0}', [df.label])}</h4>
|
||||
return `
|
||||
<h4 class="margin-top">${__("Changes in {0}", [df.label])}</h4>
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
<th width="25%">${__('Item Code')}</th>
|
||||
<th width="25%">${__('Field')}</th>
|
||||
<th width="25%">${__("Item Code")}</th>
|
||||
<th width="25%">${__("Field")}</th>
|
||||
<th width="25%">${name1}</th>
|
||||
<th width="25%">${name2}</th>
|
||||
</tr>
|
||||
${html}
|
||||
</table>
|
||||
`;
|
||||
}).join('');
|
||||
})
|
||||
.join("");
|
||||
|
||||
let get_added_removed_html = (title, grouped_items) => {
|
||||
return Object.keys(grouped_items).map(fieldname => {
|
||||
let rows = grouped_items[fieldname];
|
||||
let df = frappe.meta.get_docfield(doctype, fieldname);
|
||||
let fields = frappe.meta.get_docfields(df.options)
|
||||
.filter(df => df.in_list_view);
|
||||
return Object.keys(grouped_items)
|
||||
.map((fieldname) => {
|
||||
let rows = grouped_items[fieldname];
|
||||
let df = frappe.meta.get_docfield(doctype, fieldname);
|
||||
let fields = frappe.meta.get_docfields(df.options).filter((df) => df.in_list_view);
|
||||
|
||||
let html = rows.map(row => {
|
||||
let [, doc] = row;
|
||||
let cells = fields
|
||||
.map(df => `<td>${doc[df.fieldname]}</td>`)
|
||||
.join('');
|
||||
return `<tr>${cells}</tr>`;
|
||||
}).join('');
|
||||
let html = rows
|
||||
.map((row) => {
|
||||
let [, doc] = row;
|
||||
let cells = fields.map((df) => `<td>${doc[df.fieldname]}</td>`).join("");
|
||||
return `<tr>${cells}</tr>`;
|
||||
})
|
||||
.join("");
|
||||
|
||||
let header = fields.map(df => `<th>${df.label}</th>`).join('');
|
||||
return `
|
||||
let header = fields.map((df) => `<th>${df.label}</th>`).join("");
|
||||
return `
|
||||
<h4 class="margin-top">${$.format(title, [df.label])}</h4>
|
||||
<table class="table table-bordered">
|
||||
<tr>${header}</tr>
|
||||
${html}
|
||||
</table>
|
||||
`;
|
||||
}).join('');
|
||||
})
|
||||
.join("");
|
||||
};
|
||||
|
||||
let added_by_fieldname = group_items(diff.added, change => change[0]);
|
||||
let removed_by_fieldname = group_items(diff.removed, change => change[0]);
|
||||
let added_by_fieldname = group_items(diff.added, (change) => change[0]);
|
||||
let removed_by_fieldname = group_items(diff.removed, (change) => change[0]);
|
||||
|
||||
let added_html = get_added_removed_html(__('Rows Added in {0}'), added_by_fieldname);
|
||||
let removed_html = get_added_removed_html(__('Rows Removed in {0}'), removed_by_fieldname);
|
||||
let added_html = get_added_removed_html(__("Rows Added in {0}"), added_by_fieldname);
|
||||
let removed_html = get_added_removed_html(__("Rows Removed in {0}"), removed_by_fieldname);
|
||||
|
||||
let html = `
|
||||
${value_changes}
|
||||
@@ -200,14 +207,14 @@ erpnext.BOMComparisonTool = class BOMComparisonTool {
|
||||
${removed_html}
|
||||
`;
|
||||
|
||||
this.form.get_field('preview').html(html);
|
||||
this.form.get_field("preview").html(html);
|
||||
}
|
||||
|
||||
get_changed_values(doctype, changed) {
|
||||
return changed.filter(change => {
|
||||
return changed.filter((change) => {
|
||||
let [fieldname, value1, value2] = change;
|
||||
if (!value1) value1 = '';
|
||||
if (!value2) value2 = '';
|
||||
if (!value1) value1 = "";
|
||||
if (!value2) value2 = "";
|
||||
if (value1 === value2) return false;
|
||||
let df = frappe.meta.get_docfield(doctype, fieldname);
|
||||
if (!df) return false;
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
|
||||
|
||||
frappe.pages['visual-plant-floor'].on_page_load = function(wrapper) {
|
||||
frappe.pages["visual-plant-floor"].on_page_load = function (wrapper) {
|
||||
var page = frappe.ui.make_app_page({
|
||||
parent: wrapper,
|
||||
title: 'Visual Plant Floor',
|
||||
single_column: true
|
||||
title: "Visual Plant Floor",
|
||||
single_column: true,
|
||||
});
|
||||
|
||||
frappe.visual_plant_floor = new frappe.ui.VisualPlantFloor(
|
||||
{wrapper: $(wrapper).find('.layout-main-section')}, wrapper.page
|
||||
{ wrapper: $(wrapper).find(".layout-main-section") },
|
||||
wrapper.page
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.query_reports["BOM Explorer"] = {
|
||||
"filters": [
|
||||
filters: [
|
||||
{
|
||||
fieldname: "bom",
|
||||
label: __("BOM"),
|
||||
fieldtype: "Link",
|
||||
options: "BOM",
|
||||
reqd: 1
|
||||
reqd: 1,
|
||||
},
|
||||
]
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,42 +1,41 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.query_reports["BOM Operations Time"] = {
|
||||
"filters": [
|
||||
filters: [
|
||||
{
|
||||
"fieldname": "item_code",
|
||||
"label": __("Item Code"),
|
||||
"fieldtype": "Link",
|
||||
"width": "100",
|
||||
"options": "Item",
|
||||
"get_query": () =>{
|
||||
fieldname: "item_code",
|
||||
label: __("Item Code"),
|
||||
fieldtype: "Link",
|
||||
width: "100",
|
||||
options: "Item",
|
||||
get_query: () => {
|
||||
return {
|
||||
filters: { "is_stock_item": 1 }
|
||||
}
|
||||
}
|
||||
filters: { is_stock_item: 1 },
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "bom_id",
|
||||
"label": __("BOM ID"),
|
||||
"fieldtype": "MultiSelectList",
|
||||
"width": "100",
|
||||
"options": "BOM",
|
||||
"get_data": function(txt) {
|
||||
fieldname: "bom_id",
|
||||
label: __("BOM ID"),
|
||||
fieldtype: "MultiSelectList",
|
||||
width: "100",
|
||||
options: "BOM",
|
||||
get_data: function (txt) {
|
||||
return frappe.db.get_link_options("BOM", txt);
|
||||
},
|
||||
"get_query": () =>{
|
||||
get_query: () => {
|
||||
return {
|
||||
filters: { "docstatus": 1, "is_active": 1, "with_operations": 1 }
|
||||
}
|
||||
}
|
||||
filters: { docstatus: 1, is_active: 1, with_operations: 1 },
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "workstation",
|
||||
"label": __("Workstation"),
|
||||
"fieldtype": "Link",
|
||||
"width": "100",
|
||||
"options": "Workstation"
|
||||
fieldname: "workstation",
|
||||
label: __("Workstation"),
|
||||
fieldtype: "Link",
|
||||
width: "100",
|
||||
options: "Workstation",
|
||||
},
|
||||
]
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,34 +1,33 @@
|
||||
// Copyright (c) 2016, Epoch Consulting and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.query_reports["BOM Stock Calculated"] = {
|
||||
"filters": [
|
||||
filters: [
|
||||
{
|
||||
"fieldname": "bom",
|
||||
"label": __("BOM"),
|
||||
"fieldtype": "Link",
|
||||
"options": "BOM",
|
||||
"reqd": 1
|
||||
fieldname: "bom",
|
||||
label: __("BOM"),
|
||||
fieldtype: "Link",
|
||||
options: "BOM",
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
"fieldname": "warehouse",
|
||||
"label": __("Warehouse"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Warehouse",
|
||||
fieldname: "warehouse",
|
||||
label: __("Warehouse"),
|
||||
fieldtype: "Link",
|
||||
options: "Warehouse",
|
||||
},
|
||||
{
|
||||
"fieldname": "qty_to_make",
|
||||
"label": __("Quantity to Make"),
|
||||
"fieldtype": "Float",
|
||||
"default": "1.0",
|
||||
"reqd": 1
|
||||
fieldname: "qty_to_make",
|
||||
label: __("Quantity to Make"),
|
||||
fieldtype: "Float",
|
||||
default: "1.0",
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
"fieldname": "show_exploded_view",
|
||||
"label": __("Show exploded view"),
|
||||
"fieldtype": "Check",
|
||||
"default": false,
|
||||
}
|
||||
]
|
||||
}
|
||||
fieldname: "show_exploded_view",
|
||||
label: __("Show exploded view"),
|
||||
fieldtype: "Check",
|
||||
default: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,38 +1,41 @@
|
||||
frappe.query_reports["BOM Stock Report"] = {
|
||||
"filters": [
|
||||
filters: [
|
||||
{
|
||||
"fieldname": "bom",
|
||||
"label": __("BOM"),
|
||||
"fieldtype": "Link",
|
||||
"options": "BOM",
|
||||
"reqd": 1
|
||||
}, {
|
||||
"fieldname": "warehouse",
|
||||
"label": __("Warehouse"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Warehouse",
|
||||
"reqd": 1
|
||||
}, {
|
||||
"fieldname": "show_exploded_view",
|
||||
"label": __("Show exploded view"),
|
||||
"fieldtype": "Check"
|
||||
}, {
|
||||
"fieldname": "qty_to_produce",
|
||||
"label": __("Quantity to Produce"),
|
||||
"fieldtype": "Int",
|
||||
"default": "1"
|
||||
},
|
||||
fieldname: "bom",
|
||||
label: __("BOM"),
|
||||
fieldtype: "Link",
|
||||
options: "BOM",
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
fieldname: "warehouse",
|
||||
label: __("Warehouse"),
|
||||
fieldtype: "Link",
|
||||
options: "Warehouse",
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
fieldname: "show_exploded_view",
|
||||
label: __("Show exploded view"),
|
||||
fieldtype: "Check",
|
||||
},
|
||||
{
|
||||
fieldname: "qty_to_produce",
|
||||
label: __("Quantity to Produce"),
|
||||
fieldtype: "Int",
|
||||
default: "1",
|
||||
},
|
||||
],
|
||||
"formatter": function(value, row, column, data, default_formatter) {
|
||||
formatter: function (value, row, column, data, default_formatter) {
|
||||
value = default_formatter(value, row, column, data);
|
||||
|
||||
if (column.id == "item") {
|
||||
if (data["in_stock_qty"] >= data["required_qty"]) {
|
||||
value = `<a style='color:green' href="/app/item/${data['item']}" data-doctype="Item">${data['item']}</a>`;
|
||||
value = `<a style='color:green' href="/app/item/${data["item"]}" data-doctype="Item">${data["item"]}</a>`;
|
||||
} else {
|
||||
value = `<a style='color:red' href="/app/item/${data['item']}" data-doctype="Item">${data['item']}</a>`;
|
||||
value = `<a style='color:red' href="/app/item/${data["item"]}" data-doctype="Item">${data["item"]}</a>`;
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
}
|
||||
return value;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,29 +1,28 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.query_reports["BOM Variance Report"] = {
|
||||
"filters": [
|
||||
filters: [
|
||||
{
|
||||
"fieldname":"bom_no",
|
||||
"label": __("BOM No"),
|
||||
"fieldtype": "Link",
|
||||
"options": "BOM"
|
||||
fieldname: "bom_no",
|
||||
label: __("BOM No"),
|
||||
fieldtype: "Link",
|
||||
options: "BOM",
|
||||
},
|
||||
{
|
||||
"fieldname":"work_order",
|
||||
"label": __("Work Order"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Work Order",
|
||||
"get_query": function() {
|
||||
var bom_no = frappe.query_report.get_filter_value('bom_no');
|
||||
return{
|
||||
fieldname: "work_order",
|
||||
label: __("Work Order"),
|
||||
fieldtype: "Link",
|
||||
options: "Work Order",
|
||||
get_query: function () {
|
||||
var bom_no = frappe.query_report.get_filter_value("bom_no");
|
||||
return {
|
||||
query: "erpnext.manufacturing.report.bom_variance_report.bom_variance_report.get_work_orders",
|
||||
filters: {
|
||||
'bom_no': bom_no
|
||||
}
|
||||
}
|
||||
}
|
||||
bom_no: bom_no,
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,26 +1,27 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.query_reports["Cost of Poor Quality Report"] = {
|
||||
"filters": [
|
||||
filters: [
|
||||
{
|
||||
label: __("Company"),
|
||||
fieldname: "company",
|
||||
fieldtype: "Link",
|
||||
options: "Company",
|
||||
default: frappe.defaults.get_user_default("Company"),
|
||||
reqd: 1
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
label: __("From Date"),
|
||||
fieldname:"from_date",
|
||||
fieldname: "from_date",
|
||||
fieldtype: "Datetime",
|
||||
default: frappe.datetime.convert_to_system_tz(frappe.datetime.add_months(frappe.datetime.now_datetime(), -1)),
|
||||
default: frappe.datetime.convert_to_system_tz(
|
||||
frappe.datetime.add_months(frappe.datetime.now_datetime(), -1)
|
||||
),
|
||||
},
|
||||
{
|
||||
label: __("To Date"),
|
||||
fieldname:"to_date",
|
||||
fieldname: "to_date",
|
||||
fieldtype: "Datetime",
|
||||
default: frappe.datetime.now_datetime(),
|
||||
},
|
||||
@@ -29,45 +30,45 @@ frappe.query_reports["Cost of Poor Quality Report"] = {
|
||||
fieldname: "name",
|
||||
fieldtype: "Link",
|
||||
options: "Job Card",
|
||||
get_query: function() {
|
||||
get_query: function () {
|
||||
return {
|
||||
filters: {
|
||||
is_corrective_job_card: 1,
|
||||
docstatus: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
docstatus: 1,
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: __("Work Order"),
|
||||
fieldname: "work_order",
|
||||
fieldtype: "Link",
|
||||
options: "Work Order"
|
||||
options: "Work Order",
|
||||
},
|
||||
{
|
||||
label: __("Operation"),
|
||||
fieldname: "operation",
|
||||
fieldtype: "Link",
|
||||
options: "Operation",
|
||||
get_query: function() {
|
||||
get_query: function () {
|
||||
return {
|
||||
filters: {
|
||||
is_corrective_operation: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
is_corrective_operation: 1,
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: __("Workstation"),
|
||||
fieldname: "workstation",
|
||||
fieldtype: "Link",
|
||||
options: "Workstation"
|
||||
options: "Workstation",
|
||||
},
|
||||
{
|
||||
label: __("Item"),
|
||||
fieldname: "production_item",
|
||||
fieldtype: "Link",
|
||||
options: "Item"
|
||||
options: "Item",
|
||||
},
|
||||
{
|
||||
label: __("Serial No"),
|
||||
@@ -75,14 +76,14 @@ frappe.query_reports["Cost of Poor Quality Report"] = {
|
||||
fieldtype: "Link",
|
||||
options: "Serial No",
|
||||
depends_on: "eval: doc.production_item",
|
||||
get_query: function() {
|
||||
var item_code = frappe.query_report.get_filter_value('production_item');
|
||||
get_query: function () {
|
||||
var item_code = frappe.query_report.get_filter_value("production_item");
|
||||
return {
|
||||
filters: {
|
||||
item_code: item_code
|
||||
}
|
||||
}
|
||||
}
|
||||
item_code: item_code,
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: __("Batch No"),
|
||||
@@ -90,14 +91,14 @@ frappe.query_reports["Cost of Poor Quality Report"] = {
|
||||
fieldtype: "Link",
|
||||
options: "Batch No",
|
||||
depends_on: "eval: doc.production_item",
|
||||
get_query: function() {
|
||||
var item_code = frappe.query_report.get_filter_value('production_item');
|
||||
get_query: function () {
|
||||
var item_code = frappe.query_report.get_filter_value("production_item");
|
||||
return {
|
||||
filters: {
|
||||
item: item_code
|
||||
}
|
||||
}
|
||||
}
|
||||
item: item_code,
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
]
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.query_reports["Downtime Analysis"] = {
|
||||
"filters": [
|
||||
filters: [
|
||||
{
|
||||
label: __("From Date"),
|
||||
fieldname:"from_date",
|
||||
fieldname: "from_date",
|
||||
fieldtype: "Datetime",
|
||||
default: frappe.datetime.convert_to_system_tz(frappe.datetime.add_months(frappe.datetime.now_datetime(), -1)),
|
||||
reqd: 1
|
||||
default: frappe.datetime.convert_to_system_tz(
|
||||
frappe.datetime.add_months(frappe.datetime.now_datetime(), -1)
|
||||
),
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
label: __("To Date"),
|
||||
fieldname:"to_date",
|
||||
fieldname: "to_date",
|
||||
fieldtype: "Datetime",
|
||||
default: frappe.datetime.now_datetime(),
|
||||
reqd: 1,
|
||||
@@ -22,7 +23,7 @@ frappe.query_reports["Downtime Analysis"] = {
|
||||
label: __("Machine"),
|
||||
fieldname: "workstation",
|
||||
fieldtype: "Link",
|
||||
options: "Workstation"
|
||||
}
|
||||
]
|
||||
options: "Workstation",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,97 +1,96 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.query_reports["Exponential Smoothing Forecasting"] = {
|
||||
"filters": [
|
||||
filters: [
|
||||
{
|
||||
"fieldname":"company",
|
||||
"label": __("Company"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Company",
|
||||
"reqd": 1,
|
||||
"default": frappe.defaults.get_user_default("Company")
|
||||
fieldname: "company",
|
||||
label: __("Company"),
|
||||
fieldtype: "Link",
|
||||
options: "Company",
|
||||
reqd: 1,
|
||||
default: frappe.defaults.get_user_default("Company"),
|
||||
},
|
||||
{
|
||||
"fieldname":"from_date",
|
||||
"label": __("From Date"),
|
||||
"fieldtype": "Date",
|
||||
"default": frappe.datetime.get_today(),
|
||||
"reqd": 1
|
||||
fieldname: "from_date",
|
||||
label: __("From Date"),
|
||||
fieldtype: "Date",
|
||||
default: frappe.datetime.get_today(),
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
"fieldname":"to_date",
|
||||
"label": __("To Date"),
|
||||
"fieldtype": "Date",
|
||||
"default": frappe.datetime.add_months(frappe.datetime.get_today(), 12),
|
||||
"reqd": 1
|
||||
fieldname: "to_date",
|
||||
label: __("To Date"),
|
||||
fieldtype: "Date",
|
||||
default: frappe.datetime.add_months(frappe.datetime.get_today(), 12),
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
"fieldname":"based_on_document",
|
||||
"label": __("Based On Document"),
|
||||
"fieldtype": "Select",
|
||||
"options": ["Sales Order", "Sales Invoice", "Delivery Note", "Quotation"],
|
||||
"default": "Sales Order",
|
||||
"reqd": 1
|
||||
fieldname: "based_on_document",
|
||||
label: __("Based On Document"),
|
||||
fieldtype: "Select",
|
||||
options: ["Sales Order", "Sales Invoice", "Delivery Note", "Quotation"],
|
||||
default: "Sales Order",
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
"fieldname":"based_on_field",
|
||||
"label": __("Based On"),
|
||||
"fieldtype": "Select",
|
||||
"options": ["Qty", "Amount"],
|
||||
"default": "Qty",
|
||||
"reqd": 1
|
||||
fieldname: "based_on_field",
|
||||
label: __("Based On"),
|
||||
fieldtype: "Select",
|
||||
options: ["Qty", "Amount"],
|
||||
default: "Qty",
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
"fieldname":"no_of_years",
|
||||
"label": __("Based On Data ( in years )"),
|
||||
"fieldtype": "Select",
|
||||
"options": [3, 6, 9],
|
||||
"default": 3,
|
||||
"reqd": 1
|
||||
fieldname: "no_of_years",
|
||||
label: __("Based On Data ( in years )"),
|
||||
fieldtype: "Select",
|
||||
options: [3, 6, 9],
|
||||
default: 3,
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
"fieldname": "periodicity",
|
||||
"label": __("Periodicity"),
|
||||
"fieldtype": "Select",
|
||||
"options": [
|
||||
{ "value": "Monthly", "label": __("Monthly") },
|
||||
{ "value": "Quarterly", "label": __("Quarterly") },
|
||||
{ "value": "Half-Yearly", "label": __("Half-Yearly") },
|
||||
{ "value": "Yearly", "label": __("Yearly") }
|
||||
fieldname: "periodicity",
|
||||
label: __("Periodicity"),
|
||||
fieldtype: "Select",
|
||||
options: [
|
||||
{ value: "Monthly", label: __("Monthly") },
|
||||
{ value: "Quarterly", label: __("Quarterly") },
|
||||
{ value: "Half-Yearly", label: __("Half-Yearly") },
|
||||
{ value: "Yearly", label: __("Yearly") },
|
||||
],
|
||||
"default": "Yearly",
|
||||
"reqd": 1
|
||||
default: "Yearly",
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
"fieldname":"smoothing_constant",
|
||||
"label": __("Smoothing Constant"),
|
||||
"fieldtype": "Select",
|
||||
"options": [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0],
|
||||
"reqd": 1,
|
||||
"default": 0.3
|
||||
fieldname: "smoothing_constant",
|
||||
label: __("Smoothing Constant"),
|
||||
fieldtype: "Select",
|
||||
options: [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0],
|
||||
reqd: 1,
|
||||
default: 0.3,
|
||||
},
|
||||
{
|
||||
"fieldname":"item_code",
|
||||
"label": __("Item Code"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Item"
|
||||
fieldname: "item_code",
|
||||
label: __("Item Code"),
|
||||
fieldtype: "Link",
|
||||
options: "Item",
|
||||
},
|
||||
{
|
||||
"fieldname":"warehouse",
|
||||
"label": __("Warehouse"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Warehouse",
|
||||
fieldname: "warehouse",
|
||||
label: __("Warehouse"),
|
||||
fieldtype: "Link",
|
||||
options: "Warehouse",
|
||||
get_query: () => {
|
||||
var company = frappe.query_report.get_filter_value('company');
|
||||
var company = frappe.query_report.get_filter_value("company");
|
||||
if (company) {
|
||||
return {
|
||||
filters: {
|
||||
'company': company
|
||||
}
|
||||
company: company,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.query_reports["Job Card Summary"] = {
|
||||
"filters": [
|
||||
filters: [
|
||||
{
|
||||
label: __("Company"),
|
||||
fieldname: "company",
|
||||
fieldtype: "Link",
|
||||
options: "Company",
|
||||
default: frappe.defaults.get_user_default("Company"),
|
||||
reqd: 1
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
fieldname: "fiscal_year",
|
||||
@@ -19,30 +18,30 @@ frappe.query_reports["Job Card Summary"] = {
|
||||
options: "Fiscal Year",
|
||||
default: erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||
reqd: 1,
|
||||
on_change: function(query_report) {
|
||||
on_change: function (query_report) {
|
||||
var fiscal_year = query_report.get_values().fiscal_year;
|
||||
if (!fiscal_year) {
|
||||
return;
|
||||
}
|
||||
frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
|
||||
frappe.model.with_doc("Fiscal Year", fiscal_year, function (r) {
|
||||
var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
|
||||
frappe.query_report.set_filter_value({
|
||||
from_date: fy.year_start_date,
|
||||
to_date: fy.year_end_date
|
||||
to_date: fy.year_end_date,
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
label: __("From Posting Date"),
|
||||
fieldname:"from_date",
|
||||
fieldname: "from_date",
|
||||
fieldtype: "Date",
|
||||
default: erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[1],
|
||||
reqd: 1
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
label: __("To Posting Date"),
|
||||
fieldname:"to_date",
|
||||
fieldname: "to_date",
|
||||
fieldtype: "Date",
|
||||
default: erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[2],
|
||||
reqd: 1,
|
||||
@@ -51,35 +50,35 @@ frappe.query_reports["Job Card Summary"] = {
|
||||
label: __("Status"),
|
||||
fieldname: "status",
|
||||
fieldtype: "Select",
|
||||
options: ["", "Open", "Work In Progress", "Completed", "On Hold"]
|
||||
options: ["", "Open", "Work In Progress", "Completed", "On Hold"],
|
||||
},
|
||||
{
|
||||
label: __("Work Orders"),
|
||||
fieldname: "work_order",
|
||||
fieldtype: "MultiSelectList",
|
||||
get_data: function(txt) {
|
||||
return frappe.db.get_link_options('Work Order', txt);
|
||||
}
|
||||
get_data: function (txt) {
|
||||
return frappe.db.get_link_options("Work Order", txt);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: __("Production Item"),
|
||||
fieldname: "production_item",
|
||||
fieldtype: "MultiSelectList",
|
||||
get_data: function(txt) {
|
||||
return frappe.db.get_link_options('Item', txt);
|
||||
}
|
||||
get_data: function (txt) {
|
||||
return frappe.db.get_link_options("Item", txt);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: __("Workstation"),
|
||||
fieldname: "workstation",
|
||||
fieldtype: "Link",
|
||||
options: "Workstation"
|
||||
options: "Workstation",
|
||||
},
|
||||
{
|
||||
label: __("Operation"),
|
||||
fieldname: "operation",
|
||||
fieldtype: "Link",
|
||||
options: "Operation"
|
||||
}
|
||||
]
|
||||
options: "Operation",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,44 +1,43 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.query_reports["Process Loss Report"] = {
|
||||
filters: [
|
||||
{
|
||||
label: __("Company"),
|
||||
fieldname: "company",
|
||||
fieldtype: "Link",
|
||||
options: "Company",
|
||||
mandatory: true,
|
||||
default: frappe.defaults.get_user_default("Company"),
|
||||
},
|
||||
{
|
||||
label: __("Item"),
|
||||
fieldname: "item",
|
||||
fieldtype: "Link",
|
||||
options: "Item",
|
||||
mandatory: false,
|
||||
label: __("Company"),
|
||||
fieldname: "company",
|
||||
fieldtype: "Link",
|
||||
options: "Company",
|
||||
mandatory: true,
|
||||
default: frappe.defaults.get_user_default("Company"),
|
||||
},
|
||||
{
|
||||
label: __("Work Order"),
|
||||
fieldname: "work_order",
|
||||
fieldtype: "Link",
|
||||
options: "Work Order",
|
||||
mandatory: false,
|
||||
label: __("Item"),
|
||||
fieldname: "item",
|
||||
fieldtype: "Link",
|
||||
options: "Item",
|
||||
mandatory: false,
|
||||
},
|
||||
{
|
||||
label: __("From Date"),
|
||||
fieldname: "from_date",
|
||||
fieldtype: "Date",
|
||||
mandatory: true,
|
||||
default: frappe.datetime.year_start(),
|
||||
},
|
||||
{
|
||||
label: __("To Date"),
|
||||
fieldname: "to_date",
|
||||
fieldtype: "Date",
|
||||
mandatory: true,
|
||||
default: frappe.datetime.get_today(),
|
||||
},
|
||||
]
|
||||
{
|
||||
label: __("Work Order"),
|
||||
fieldname: "work_order",
|
||||
fieldtype: "Link",
|
||||
options: "Work Order",
|
||||
mandatory: false,
|
||||
},
|
||||
{
|
||||
label: __("From Date"),
|
||||
fieldname: "from_date",
|
||||
fieldtype: "Date",
|
||||
mandatory: true,
|
||||
default: frappe.datetime.year_start(),
|
||||
},
|
||||
{
|
||||
label: __("To Date"),
|
||||
fieldname: "to_date",
|
||||
fieldtype: "Date",
|
||||
mandatory: true,
|
||||
default: frappe.datetime.get_today(),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,43 +1,42 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.query_reports["Production Analytics"] = {
|
||||
"filters": [
|
||||
filters: [
|
||||
{
|
||||
fieldname: "company",
|
||||
label: __("Company"),
|
||||
fieldtype: "Link",
|
||||
options: "Company",
|
||||
default: frappe.defaults.get_user_default("Company"),
|
||||
reqd: 1
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
fieldname: "from_date",
|
||||
label: __("From Date"),
|
||||
fieldtype: "Date",
|
||||
default: erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[1],
|
||||
reqd: 1
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
fieldname:"to_date",
|
||||
fieldname: "to_date",
|
||||
label: __("To Date"),
|
||||
fieldtype: "Date",
|
||||
default: erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[2],
|
||||
reqd: 1
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
fieldname: "range",
|
||||
label: __("Range"),
|
||||
fieldtype: "Select",
|
||||
options: [
|
||||
{ "value": "Weekly", "label": __("Weekly") },
|
||||
{ "value": "Monthly", "label": __("Monthly") },
|
||||
{ "value": "Quarterly", "label": __("Quarterly") },
|
||||
{ "value": "Yearly", "label": __("Yearly") }
|
||||
{ value: "Weekly", label: __("Weekly") },
|
||||
{ value: "Monthly", label: __("Monthly") },
|
||||
{ value: "Quarterly", label: __("Quarterly") },
|
||||
{ value: "Yearly", label: __("Yearly") },
|
||||
],
|
||||
default: "Monthly",
|
||||
reqd: 1
|
||||
}
|
||||
]
|
||||
}
|
||||
reqd: 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,30 +1,29 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.query_reports["Production Plan Summary"] = {
|
||||
"filters": [
|
||||
filters: [
|
||||
{
|
||||
fieldname: "production_plan",
|
||||
label: __("Production Plan"),
|
||||
fieldtype: "Link",
|
||||
options: "Production Plan",
|
||||
reqd: 1,
|
||||
get_query: function() {
|
||||
get_query: function () {
|
||||
return {
|
||||
filters: {
|
||||
"docstatus": 1
|
||||
}
|
||||
docstatus: 1,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
"formatter": function(value, row, column, data, default_formatter) {
|
||||
formatter: function (value, row, column, data, default_formatter) {
|
||||
value = default_formatter(value, row, column, data);
|
||||
|
||||
if (column.fieldname == "item_code") {
|
||||
var color = data.pending_qty > 0 ? 'red': 'green';
|
||||
value = `<a style='color:${color}' href="/app/item/${data['item_code']}" data-doctype="Item">${data['item_code']}</a>`;
|
||||
var color = data.pending_qty > 0 ? "red" : "green";
|
||||
value = `<a style='color:${color}' href="/app/item/${data["item_code"]}" data-doctype="Item">${data["item_code"]}</a>`;
|
||||
}
|
||||
|
||||
return value;
|
||||
|
||||
@@ -1,108 +1,111 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.query_reports["Production Planning Report"] = {
|
||||
"filters": [
|
||||
filters: [
|
||||
{
|
||||
"fieldname":"company",
|
||||
"label": __("Company"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Company",
|
||||
"reqd": 1,
|
||||
"default": frappe.defaults.get_user_default("Company")
|
||||
fieldname: "company",
|
||||
label: __("Company"),
|
||||
fieldtype: "Link",
|
||||
options: "Company",
|
||||
reqd: 1,
|
||||
default: frappe.defaults.get_user_default("Company"),
|
||||
},
|
||||
{
|
||||
"fieldname":"based_on",
|
||||
"label": __("Based On"),
|
||||
"fieldtype": "Select",
|
||||
"options": ["Sales Order", "Material Request", "Work Order"],
|
||||
"default": "Sales Order",
|
||||
"reqd": 1,
|
||||
on_change: function() {
|
||||
fieldname: "based_on",
|
||||
label: __("Based On"),
|
||||
fieldtype: "Select",
|
||||
options: ["Sales Order", "Material Request", "Work Order"],
|
||||
default: "Sales Order",
|
||||
reqd: 1,
|
||||
on_change: function () {
|
||||
let filters = frappe.query_report.filters;
|
||||
let based_on = frappe.query_report.get_filter_value('based_on');
|
||||
let based_on = frappe.query_report.get_filter_value("based_on");
|
||||
let options = {
|
||||
"Sales Order": ["Delivery Date", "Total Amount"],
|
||||
"Material Request": ["Required Date"],
|
||||
"Work Order": ["Planned Start Date"]
|
||||
}
|
||||
"Work Order": ["Planned Start Date"],
|
||||
};
|
||||
|
||||
filters.forEach(d => {
|
||||
filters.forEach((d) => {
|
||||
if (d.fieldname == "order_by") {
|
||||
d.df.options = options[based_on];
|
||||
d.set_input(d.df.options)
|
||||
d.set_input(d.df.options);
|
||||
}
|
||||
});
|
||||
|
||||
frappe.query_report.refresh();
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname":"docnames",
|
||||
"label": __("Document Name"),
|
||||
"fieldtype": "MultiSelectList",
|
||||
"options": "Sales Order",
|
||||
"get_data": function(txt) {
|
||||
fieldname: "docnames",
|
||||
label: __("Document Name"),
|
||||
fieldtype: "MultiSelectList",
|
||||
options: "Sales Order",
|
||||
get_data: function (txt) {
|
||||
if (!frappe.query_report.filters) return;
|
||||
|
||||
let based_on = frappe.query_report.get_filter_value('based_on');
|
||||
let based_on = frappe.query_report.get_filter_value("based_on");
|
||||
if (!based_on) return;
|
||||
|
||||
return frappe.db.get_link_options(based_on, txt);
|
||||
},
|
||||
"get_query": function() {
|
||||
var company = frappe.query_report.get_filter_value('company');
|
||||
get_query: function () {
|
||||
var company = frappe.query_report.get_filter_value("company");
|
||||
return {
|
||||
filters: {
|
||||
"docstatus": 1,
|
||||
"company": company
|
||||
}
|
||||
docstatus: 1,
|
||||
company: company,
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname":"raw_material_warehouse",
|
||||
"label": __("Raw Material Warehouse"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Warehouse",
|
||||
"depends_on": "eval: doc.based_on != 'Work Order'",
|
||||
"get_query": function() {
|
||||
var company = frappe.query_report.get_filter_value('company');
|
||||
fieldname: "raw_material_warehouse",
|
||||
label: __("Raw Material Warehouse"),
|
||||
fieldtype: "Link",
|
||||
options: "Warehouse",
|
||||
depends_on: "eval: doc.based_on != 'Work Order'",
|
||||
get_query: function () {
|
||||
var company = frappe.query_report.get_filter_value("company");
|
||||
return {
|
||||
filters: {
|
||||
"company": company
|
||||
}
|
||||
company: company,
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname":"order_by",
|
||||
"label": __("Order By"),
|
||||
"fieldtype": "Select",
|
||||
"options": ["Delivery Date", "Total Amount"],
|
||||
"default": "Delivery Date"
|
||||
fieldname: "order_by",
|
||||
label: __("Order By"),
|
||||
fieldtype: "Select",
|
||||
options: ["Delivery Date", "Total Amount"],
|
||||
default: "Delivery Date",
|
||||
},
|
||||
{
|
||||
"fieldname":"include_subassembly_raw_materials",
|
||||
"label": __("Include Sub-assembly Raw Materials"),
|
||||
"fieldtype": "Check",
|
||||
"depends_on": "eval: doc.based_on != 'Work Order'",
|
||||
"default": 0
|
||||
fieldname: "include_subassembly_raw_materials",
|
||||
label: __("Include Sub-assembly Raw Materials"),
|
||||
fieldtype: "Check",
|
||||
depends_on: "eval: doc.based_on != 'Work Order'",
|
||||
default: 0,
|
||||
},
|
||||
],
|
||||
"formatter": function(value, row, column, data, default_formatter) {
|
||||
formatter: function (value, row, column, data, default_formatter) {
|
||||
value = default_formatter(value, row, column, data);
|
||||
|
||||
if (column.fieldname == "production_item_name" && data && data.qty_to_manufacture > data.available_qty ) {
|
||||
if (
|
||||
column.fieldname == "production_item_name" &&
|
||||
data &&
|
||||
data.qty_to_manufacture > data.available_qty
|
||||
) {
|
||||
value = `<div style="color:red">${value}</div>`;
|
||||
}
|
||||
|
||||
if (column.fieldname == "production_item" && !data.name ) {
|
||||
if (column.fieldname == "production_item" && !data.name) {
|
||||
value = "";
|
||||
}
|
||||
|
||||
if (column.fieldname == "raw_material_name" && data && data.required_qty > data.allotted_qty ) {
|
||||
if (column.fieldname == "raw_material_name" && data && data.required_qty > data.allotted_qty) {
|
||||
value = `<div style="color:red">${value}</div>`;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.query_reports["Quality Inspection Summary"] = {
|
||||
"filters": [
|
||||
filters: [
|
||||
{
|
||||
label: __("From Date"),
|
||||
fieldname:"from_date",
|
||||
fieldname: "from_date",
|
||||
fieldtype: "Date",
|
||||
default: frappe.datetime.add_months(frappe.datetime.get_today(), -12),
|
||||
reqd: 1
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
label: __("To Date"),
|
||||
fieldname:"to_date",
|
||||
fieldname: "to_date",
|
||||
fieldtype: "Date",
|
||||
default: frappe.datetime.get_today(),
|
||||
reqd: 1,
|
||||
@@ -22,19 +21,19 @@ frappe.query_reports["Quality Inspection Summary"] = {
|
||||
label: __("Status"),
|
||||
fieldname: "status",
|
||||
fieldtype: "Select",
|
||||
options: ["", "Accepted", "Rejected"]
|
||||
options: ["", "Accepted", "Rejected"],
|
||||
},
|
||||
{
|
||||
label: __("Item Code"),
|
||||
fieldname: "item_code",
|
||||
fieldtype: "Link",
|
||||
options: "Item"
|
||||
options: "Item",
|
||||
},
|
||||
{
|
||||
label: __("Inspected By"),
|
||||
fieldname: "inspected_by",
|
||||
fieldtype: "Link",
|
||||
options: "User"
|
||||
}
|
||||
]
|
||||
options: "User",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,67 +1,66 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.query_reports["Work Order Consumed Materials"] = {
|
||||
"filters": [
|
||||
filters: [
|
||||
{
|
||||
label: __("Company"),
|
||||
fieldname: "company",
|
||||
fieldtype: "Link",
|
||||
options: "Company",
|
||||
default: frappe.defaults.get_user_default("Company"),
|
||||
reqd: 1
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
label: __("From Date"),
|
||||
fieldname:"from_date",
|
||||
fieldname: "from_date",
|
||||
fieldtype: "Date",
|
||||
default: frappe.datetime.add_months(frappe.datetime.get_today(), -1),
|
||||
reqd: 1
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
fieldname:"to_date",
|
||||
fieldname: "to_date",
|
||||
label: __("To Date"),
|
||||
fieldtype: "Date",
|
||||
default: frappe.datetime.get_today(),
|
||||
reqd: 1
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
label: __("Work Order"),
|
||||
fieldname: "name",
|
||||
fieldtype: "Link",
|
||||
options: "Work Order",
|
||||
get_query: function() {
|
||||
get_query: function () {
|
||||
return {
|
||||
filters: {
|
||||
status: ["in", ["In Process", "Completed", "Stopped"]]
|
||||
}
|
||||
}
|
||||
}
|
||||
status: ["in", ["In Process", "Completed", "Stopped"]],
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: __("Production Item"),
|
||||
fieldname: "production_item",
|
||||
fieldtype: "Link",
|
||||
depends_on: "eval: !doc.name",
|
||||
options: "Item"
|
||||
options: "Item",
|
||||
},
|
||||
{
|
||||
label: __("Status"),
|
||||
fieldname: "status",
|
||||
fieldtype: "Select",
|
||||
options: ["", "In Process", "Completed", "Stopped"]
|
||||
options: ["", "In Process", "Completed", "Stopped"],
|
||||
},
|
||||
{
|
||||
label: __("Excess Materials Consumed"),
|
||||
fieldname: "show_extra_consumed_materials",
|
||||
fieldtype: "Check"
|
||||
}
|
||||
fieldtype: "Check",
|
||||
},
|
||||
],
|
||||
"formatter": function(value, row, column, data, default_formatter) {
|
||||
formatter: function (value, row, column, data, default_formatter) {
|
||||
value = default_formatter(value, row, column, data);
|
||||
|
||||
if (column.fieldname == "raw_material_name" && data && data.extra_consumed_qty > 0 ) {
|
||||
if (column.fieldname == "raw_material_name" && data && data.extra_consumed_qty > 0) {
|
||||
value = `<div style="color:red">${value}</div>`;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.query_reports["Work Order Stock Report"] = {
|
||||
"filters": [
|
||||
filters: [
|
||||
{
|
||||
"fieldname": "warehouse",
|
||||
"label": __("Warehouse"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Warehouse"
|
||||
}
|
||||
]
|
||||
}
|
||||
fieldname: "warehouse",
|
||||
label: __("Warehouse"),
|
||||
fieldtype: "Link",
|
||||
options: "Warehouse",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,34 +1,33 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.query_reports["Work Order Summary"] = {
|
||||
"filters": [
|
||||
filters: [
|
||||
{
|
||||
label: __("Company"),
|
||||
fieldname: "company",
|
||||
fieldtype: "Link",
|
||||
options: "Company",
|
||||
default: frappe.defaults.get_user_default("Company"),
|
||||
reqd: 1
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
label: __("Based On"),
|
||||
fieldname:"based_on",
|
||||
fieldname: "based_on",
|
||||
fieldtype: "Select",
|
||||
options: "Creation Date\nPlanned Date\nActual Date",
|
||||
default: "Creation Date"
|
||||
default: "Creation Date",
|
||||
},
|
||||
{
|
||||
label: __("From Posting Date"),
|
||||
fieldname:"from_date",
|
||||
fieldname: "from_date",
|
||||
fieldtype: "Date",
|
||||
default: frappe.datetime.add_months(frappe.datetime.get_today(), -3),
|
||||
reqd: 1
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
label: __("To Posting Date"),
|
||||
fieldname:"to_date",
|
||||
fieldname: "to_date",
|
||||
fieldtype: "Date",
|
||||
default: frappe.datetime.get_today(),
|
||||
reqd: 1,
|
||||
@@ -37,36 +36,36 @@ frappe.query_reports["Work Order Summary"] = {
|
||||
label: __("Status"),
|
||||
fieldname: "status",
|
||||
fieldtype: "Select",
|
||||
options: ["", "Not Started", "In Process", "Completed", "Stopped", "Closed"]
|
||||
options: ["", "Not Started", "In Process", "Completed", "Stopped", "Closed"],
|
||||
},
|
||||
{
|
||||
label: __("Sales Orders"),
|
||||
fieldname: "sales_order",
|
||||
fieldtype: "MultiSelectList",
|
||||
get_data: function(txt) {
|
||||
return frappe.db.get_link_options('Sales Order', txt);
|
||||
}
|
||||
get_data: function (txt) {
|
||||
return frappe.db.get_link_options("Sales Order", txt);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: __("Production Item"),
|
||||
fieldname: "production_item",
|
||||
fieldtype: "MultiSelectList",
|
||||
get_data: function(txt) {
|
||||
return frappe.db.get_link_options('Item', txt);
|
||||
}
|
||||
get_data: function (txt) {
|
||||
return frappe.db.get_link_options("Item", txt);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: __("Age"),
|
||||
fieldname:"age",
|
||||
fieldname: "age",
|
||||
fieldtype: "Int",
|
||||
default: "0"
|
||||
default: "0",
|
||||
},
|
||||
{
|
||||
label: __("Charts Based On"),
|
||||
fieldname:"charts_based_on",
|
||||
fieldname: "charts_based_on",
|
||||
fieldtype: "Select",
|
||||
options: ["Status", "Age", "Quantity"],
|
||||
default: "Status"
|
||||
default: "Status",
|
||||
},
|
||||
]
|
||||
],
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user