Skip to content

Commit

Permalink
Merge pull request #26514 from ankush/backport/develop/pr-26240
Browse files Browse the repository at this point in the history
feat: provision to make subcontracted purchase order from the production plan (#26240)
  • Loading branch information
rohitwaghchaure committed Jul 16, 2021
2 parents 1b5f3cf + a748dd9 commit bae2890
Show file tree
Hide file tree
Showing 28 changed files with 808 additions and 111 deletions.
Expand Up @@ -97,6 +97,9 @@
"is_fixed_asset",
"item_tax_rate",
"section_break_72",
"production_plan",
"production_plan_item",
"production_plan_sub_assembly_item",
"page_break"
],
"fields": [
Expand Down Expand Up @@ -803,13 +806,37 @@
"options": "Company:company:default_currency",
"print_hide": 1,
"read_only": 1
},
{
"fieldname": "production_plan",
"fieldtype": "Link",
"label": "Production Plan",
"options": "Production Plan",
"print_hide": 1,
"read_only": 1
},
{
"fieldname": "production_plan_item",
"fieldtype": "Data",
"hidden": 1,
"label": "Production Plan Item",
"no_copy": 1,
"read_only": 1
},
{
"fieldname": "production_plan_sub_assembly_item",
"fieldtype": "Data",
"hidden": 1,
"label": "Production Plan Sub Assembly Item",
"no_copy": 1,
"read_only": 1
}
],
"idx": 1,
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2021-03-22 11:46:12.357435",
"modified": "2021-06-28 19:22:22.715365",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order Item",
Expand Down
21 changes: 20 additions & 1 deletion erpnext/manufacturing/doctype/bom/bom.json
Expand Up @@ -36,6 +36,9 @@
"materials_section",
"inspection_required",
"quality_inspection_template",
"column_break_31",
"bom_level",
"section_break_33",
"items",
"scrap_section",
"scrap_items",
Expand Down Expand Up @@ -513,14 +516,30 @@
"no_copy": 1,
"print_hide": 1,
"read_only": 1
},
{
"fieldname": "column_break_31",
"fieldtype": "Column Break"
},
{
"default": "0",
"fieldname": "bom_level",
"fieldtype": "Int",
"label": "BOM Level",
"read_only": 1
},
{
"fieldname": "section_break_33",
"fieldtype": "Section Break",
"hide_border": 1
}
],
"icon": "fa fa-sitemap",
"idx": 1,
"image_field": "image",
"is_submittable": 1,
"links": [],
"modified": "2021-03-16 12:25:09.081968",
"modified": "2021-05-16 12:25:09.081968",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM",
Expand Down
19 changes: 17 additions & 2 deletions erpnext/manufacturing/doctype/bom/bom.py
Expand Up @@ -154,6 +154,7 @@ def validate(self):
self.calculate_cost()
self.update_stock_qty()
self.update_cost(update_parent=False, from_child_bom=True, update_hour_rate = False, save=False)
self.set_bom_level()

def get_context(self, context):
context.parents = [{'name': 'boms', 'title': _('All BOMs') }]
Expand Down Expand Up @@ -676,6 +677,19 @@ def get_tree_representation(self) -> BOMTree:
"""Get a complete tree representation preserving order of child items."""
return BOMTree(self.name)

def set_bom_level(self, update=False):
levels = []

self.bom_level = 0
for row in self.items:
if row.bom_no:
levels.append(frappe.get_cached_value("BOM", row.bom_no, "bom_level") or 0)

if levels:
self.bom_level = max(levels) + 1

if update:
self.db_set("bom_level", self.bom_level)

def get_bom_item_rate(args, bom_doc):
if bom_doc.rm_cost_as_per == 'Valuation Rate':
Expand Down Expand Up @@ -860,7 +874,7 @@ def get_children(doctype, parent=None, is_root=False, **filters):
frappe.form_dict.parent = parent

if frappe.form_dict.parent:
bom_doc = frappe.get_doc("BOM", frappe.form_dict.parent)
bom_doc = frappe.get_cached_doc("BOM", frappe.form_dict.parent)
frappe.has_permission("BOM", doc=bom_doc, throw=True)

bom_items = frappe.get_all('BOM Item',
Expand All @@ -871,7 +885,7 @@ def get_children(doctype, parent=None, is_root=False, **filters):
item_names = tuple(d.get('item_code') for d in bom_items)

items = frappe.get_list('Item',
fields=['image', 'description', 'name', 'stock_uom', 'item_name'],
fields=['image', 'description', 'name', 'stock_uom', 'item_name', 'is_sub_contracted_item'],
filters=[['name', 'in', item_names]]) # to get only required item dicts

for bom_item in bom_items:
Expand All @@ -884,6 +898,7 @@ def get_children(doctype, parent=None, is_root=False, **filters):

bom_item.parent_bom_qty = bom_doc.quantity
bom_item.expandable = 0 if bom_item.value in ('', None) else 1
bom_item.image = frappe.db.escape(bom_item.image)

return bom_items

Expand Down
36 changes: 27 additions & 9 deletions erpnext/manufacturing/doctype/bom/bom_item_preview.html
@@ -1,13 +1,31 @@
<div style="padding: 15px;">
{% if data.image %}
<img class="responsive" src={{ data.image }}>
<hr style="margin: 15px -15px;">
{% endif %}
<h4>
{{ __("Description") }}
</h4>
<div style="padding-top: 10px;">
{{ data.description }}
<div class="row mb-5">
<div class="col-md-5" style="max-height: 500px">
{% if data.image %}
<div class="border image-field " style="overflow: hidden;border-color:#e6e6e6">
<img class="responsive" src={{ data.image }}>
</div>
{% endif %}
</div>
<div class="col-md-7 h-500">
<h4>
{{ __("Description") }}
</h4>
<div style="padding-top: 10px;">
{{ data.description }}
</div>
<hr style="margin: 15px -15px;">
<p>
{% if data.value %}
<a style="margin-right: 7px; margin-bottom: 7px" class="btn btn-default btn-xs" href="#Form/BOM/{{ data.value }}">
{{ __("Open BOM {0}", [data.value.bold()]) }}</a>
{% endif %}
{% if data.item_code %}
<a class="btn btn-default btn-xs" href="#Form/Item/{{ data.item_code }}">
{{ __("Open Item {0}", [data.item_code.bold()]) }}</a>
{% endif %}
</p>
</div>
</div>
<hr style="margin: 15px -15px;">
<p>
Expand Down
2 changes: 1 addition & 1 deletion erpnext/manufacturing/doctype/bom/bom_tree.js
Expand Up @@ -64,7 +64,7 @@ frappe.treeview_settings["BOM"] = {
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 = bom.image || "";
node.data.image = escape(bom.image) || "";
node.data.description = bom.description || "";
});
}
Expand Down
41 changes: 30 additions & 11 deletions erpnext/manufacturing/doctype/production_plan/production_plan.js
Expand Up @@ -4,7 +4,7 @@
frappe.ui.form.on('Production Plan', {
setup: function(frm) {
frm.custom_make_buttons = {
'Work Order': 'Work Order',
'Work Order': 'Work Order / Subcontract PO',
'Material Request': 'Material Request',
};

Expand Down Expand Up @@ -68,17 +68,13 @@ frappe.ui.form.on('Production Plan', {
frm.trigger("show_progress");

if (frm.doc.status !== "Completed") {
if (frm.doc.po_items && frm.doc.status !== "Closed") {
frm.add_custom_button(__("Work Order"), ()=> {
frm.trigger("make_work_order");
}, __('Create'));
}
frm.add_custom_button(__("Work Order Tree"), ()=> {
frappe.set_route('Tree', 'Work Order', {production_plan: frm.doc.name});
}, __('View'));

if (frm.doc.mr_items && !in_list(['Material Requested', 'Closed'], frm.doc.status)) {
frm.add_custom_button(__("Material Request"), ()=> {
frm.trigger("make_material_request");
}, __('Create'));
}
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() {
Expand All @@ -89,6 +85,18 @@ frappe.ui.form.on('Production Plan', {
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'));
}

if (frm.doc.mr_items && !in_list(['Material Requested', 'Closed'], frm.doc.status)) {
frm.add_custom_button(__("Material Request"), ()=> {
frm.trigger("make_material_request");
}, __('Create'));
}
}
}

Expand Down Expand Up @@ -233,6 +241,17 @@ frappe.ui.form.on('Production Plan', {
});
},

get_sub_assembly_items: function(frm) {
frappe.call({
method: "get_sub_assembly_items",
freeze: true,
doc: frm.doc,
callback: function() {
refresh_field("sub_assembly_items");
}
});
},

get_items_for_mr: function(frm) {
if (!frm.doc.for_warehouse) {
frappe.throw(__("Select warehouse for material requests"));
Expand Down
31 changes: 26 additions & 5 deletions erpnext/manufacturing/doctype/production_plan/production_plan.json
Expand Up @@ -32,6 +32,9 @@
"po_items",
"section_break_25",
"prod_plan_references",
"section_break_24",
"get_sub_assembly_items",
"sub_assembly_items",
"material_request_planning",
"include_non_stock_items",
"include_subcontracted_items",
Expand Down Expand Up @@ -187,7 +190,7 @@
"depends_on": "get_items_from",
"fieldname": "get_items",
"fieldtype": "Button",
"label": "Get Items For Work Order"
"label": "Get Finished Goods for Manufacture"
},
{
"fieldname": "po_items",
Expand All @@ -199,7 +202,7 @@
{
"fieldname": "material_request_planning",
"fieldtype": "Section Break",
"label": "Material Request Planning"
"label": "Material Requirement Planning"
},
{
"default": "1",
Expand Down Expand Up @@ -237,12 +240,13 @@
},
{
"fieldname": "section_break_27",
"fieldtype": "Section Break"
"fieldtype": "Section Break",
"hide_border": 1
},
{
"fieldname": "mr_items",
"fieldtype": "Table",
"label": "Material Request Plan Item",
"label": "Raw Materials",
"no_copy": 1,
"options": "Material Request Plan Item"
},
Expand Down Expand Up @@ -337,13 +341,30 @@
"hidden": 1,
"label": "Production Plan Item Reference",
"options": "Production Plan Item Reference"
},
{
"fieldname": "section_break_24",
"fieldtype": "Section Break",
"hide_border": 1
},
{
"fieldname": "sub_assembly_items",
"fieldtype": "Table",
"label": "Sub Assembly Items",
"no_copy": 1,
"options": "Production Plan Sub Assembly Item"
},
{
"fieldname": "get_sub_assembly_items",
"fieldtype": "Button",
"label": "Get Sub Assembly Items"
}
],
"icon": "fa fa-calendar",
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2021-05-24 16:59:03.643211",
"modified": "2021-06-28 20:00:33.905114",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Production Plan",
Expand Down

0 comments on commit bae2890

Please sign in to comment.