Skip to content

Commit

Permalink
Merge pull request #39741 from frappe/mergify/bp/version-15-hotfix/pr…
Browse files Browse the repository at this point in the history
…-38362

feat: visual plant floor (backport #38362)
  • Loading branch information
rohitwaghchaure authored Feb 5, 2024
2 parents b126720 + 3bef12c commit 7923bd7
Show file tree
Hide file tree
Showing 21 changed files with 1,607 additions and 151 deletions.
14 changes: 14 additions & 0 deletions erpnext/manufacturing/doctype/job_card/job_card.py
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,14 @@ def set_status(self, update_status=False):
if update_status:
self.db_set("status", self.status)

if self.status in ["Completed", "Work In Progress"]:
status = {
"Completed": "Off",
"Work In Progress": "Production",
}.get(self.status)

self.update_status_in_workstation(status)

def set_wip_warehouse(self):
if not self.wip_warehouse:
self.wip_warehouse = frappe.db.get_single_value(
Expand Down Expand Up @@ -1035,6 +1043,12 @@ def is_work_order_closed(self):

return False

def update_status_in_workstation(self, status):
if not self.workstation:
return

frappe.db.set_value("Workstation", self.workstation, "status", status)


@frappe.whitelist()
def make_time_log(args):
Expand Down
Empty file.
256 changes: 256 additions & 0 deletions erpnext/manufacturing/doctype/plant_floor/plant_floor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt

frappe.ui.form.on("Plant Floor", {
setup(frm) {
frm.trigger("setup_queries");
},

setup_queries(frm) {
frm.set_query("warehouse", (doc) => {
if (!doc.company) {
frappe.throw(__("Please select Company first"));
}

return {
filters: {
"is_group": 0,
"company": doc.company
}
}
});
},

refresh(frm) {
frm.trigger('prepare_stock_dashboard')
frm.trigger('prepare_workstation_dashboard')
},

prepare_workstation_dashboard(frm) {
let wrapper = $(frm.fields_dict["plant_dashboard"].wrapper);
wrapper.empty();

frappe.visual_plant_floor = new frappe.ui.VisualPlantFloor({
wrapper: wrapper,
skip_filters: true,
plant_floor: frm.doc.name,
});
},

prepare_stock_dashboard(frm) {
if (!frm.doc.warehouse) {
return;
}

let wrapper = $(frm.fields_dict["stock_summary"].wrapper);
wrapper.empty();

frappe.visual_stock = new VisualStock({
wrapper: wrapper,
frm: frm,
});
},
});


class VisualStock {
constructor(opts) {
Object.assign(this, opts);
this.make();
}

make() {
this.prepare_filters();
this.prepare_stock_summary({
start:0
});
}

prepare_filters() {
this.wrapper.append(`
<div class="row">
<div class="col-sm-12 filter-section section-body">
</div>
</div>
`);

this.item_filter = frappe.ui.form.make_control({
df: {
fieldtype: "Link",
fieldname: "item_code",
placeholder: __("Item"),
options: "Item",
onchange: () => this.prepare_stock_summary({
start:0,
item_code: this.item_filter.value
})
},
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_group_filter = frappe.ui.form.make_control({
df: {
fieldtype: "Link",
fieldname: "item_group",
placeholder: __("Item Group"),
options: "Item Group",
change: () => this.prepare_stock_summary({
start:0,
item_group: this.item_group_filter.value
})
},
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();
}

prepare_stock_summary(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.stock_summary = stock_summary.message;
this.render_stock_summary();
this.bind_events();
});
}

async get_stock_summary(start, item_code, item_group) {
let stock_summary = await frappe.call({
method: "erpnext.manufacturing.doctype.plant_floor.plant_floor.get_stock_summary",
args: {
warehouse: this.frm.doc.warehouse,
start: start,
item_code: item_code,
item_group: item_group
}
});

return stock_summary;
}

render_stock_summary() {
let template = frappe.render_template("stock_summary_template", {
stock_summary: this.stock_summary
});

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.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.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,
(values) => {
this.values = values;
this.stock_entry_type = stock_entry_type;
this.update_values();

this.frm.call({
method: "make_stock_entry",
doc: this.frm.doc,
args: {
kwargs: this.values,
},
callback: (r) => {
if (!r.exc) {
var doc = frappe.model.sync(r.message);
frappe.set_route("Form", r.message.doctype, r.message.name);
}
}
})
}, __(title), __("Create")
);
}

update_values() {
if (!this.values.qty) {
frappe.throw(__("Quantity is required"));
}

let from_warehouse = "";
let to_warehouse = "";

if (this.stock_entry_type == "Material Receipt") {
to_warehouse = this.frm.doc.warehouse;
} else {
from_warehouse = this.frm.doc.warehouse;
to_warehouse = this.values.to_warehouse;
}

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,
}
}
}
}
97 changes: 97 additions & 0 deletions erpnext/manufacturing/doctype/plant_floor/plant_floor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
{
"actions": [],
"allow_rename": 1,
"autoname": "field:floor_name",
"creation": "2023-10-06 15:06:07.976066",
"default_view": "List",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"workstations_tab",
"plant_dashboard",
"stock_summary_tab",
"stock_summary",
"details_tab",
"column_break_mvbx",
"floor_name",
"company",
"warehouse"
],
"fields": [
{
"fieldname": "floor_name",
"fieldtype": "Data",
"label": "Floor Name",
"unique": 1
},
{
"depends_on": "eval:!doc.__islocal",
"fieldname": "workstations_tab",
"fieldtype": "Tab Break",
"label": "Workstations"
},
{
"fieldname": "plant_dashboard",
"fieldtype": "HTML",
"label": "Plant Dashboard"
},
{
"fieldname": "details_tab",
"fieldtype": "Tab Break",
"label": "Floor"
},
{
"fieldname": "column_break_mvbx",
"fieldtype": "Column Break"
},
{
"fieldname": "warehouse",
"fieldtype": "Link",
"label": "Warehouse",
"options": "Warehouse"
},
{
"depends_on": "eval:!doc.__islocal && doc.warehouse",
"fieldname": "stock_summary_tab",
"fieldtype": "Tab Break",
"label": "Stock Summary"
},
{
"fieldname": "stock_summary",
"fieldtype": "HTML",
"label": "Stock Summary"
},
{
"fieldname": "company",
"fieldtype": "Link",
"label": "Company",
"options": "Company"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2024-01-30 11:59:07.508535",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Plant Floor",
"naming_rule": "By fieldname",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}
Loading

0 comments on commit 7923bd7

Please sign in to comment.