diff --git a/erpnext/manufacturing/report/bom_stock_report/__init__.py b/erpnext/manufacturing/report/bom_stock_report/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.js b/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.js new file mode 100644 index 00000000000..8aed965ab82 --- /dev/null +++ b/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.js @@ -0,0 +1,17 @@ +frappe.query_reports["BOM Stock Report"] = { + "filters": [ + { + "fieldname":"bom", + "label": __("BOM"), + "fieldtype": "Link", + "options": "BOM", + "reqd": 1 + },{ + "fieldname":"warehouse", + "label": __("Warehouse"), + "fieldtype": "Link", + "options": "Warehouse", + "reqd": 1 + } + ] +} diff --git a/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.json b/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.json new file mode 100644 index 00000000000..64d0ebbed46 --- /dev/null +++ b/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.json @@ -0,0 +1,20 @@ +{ + "add_total_row": 0, + "apply_user_permissions": 1, + "creation": "2017-01-10 14:00:50.387244", + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "letter_head": "Standard", + "modified": "2017-02-09 23:19:32.050905", + "modified_by": "Administrator", + "module": "Manufacturing", + "name": "BOM Stock Report", + "owner": "Administrator", + "query": "SELECT \n\tbom_item.item_code as \"Item:Link/Item:200\",\n\tbom_item.description as \"Description:Data:300\",\n\tbom_item.qty as \"Required Qty:Float:100\",\n\tledger.actual_qty as \"In Stock Qty:Float:100\",\n\tFLOOR(ledger.actual_qty /bom_item.qty) as \"Enough Parts to Build:Int:100\"\nFROM\n\t`tabBOM Item` AS bom_item \n\tLEFT JOIN `tabBin` AS ledger\t\n\t\tON bom_item.item_code = ledger.item_code \n\t\tAND ledger.warehouse = %(warehouse)s\nWHERE\n\tbom_item.parent=%(bom)s\n\nGROUP BY bom_item.item_code", + "ref_doctype": "BOM", + "report_name": "BOM Stock Report", + "report_type": "Query Report" +} \ No newline at end of file diff --git a/erpnext/manufacturing/report/production_order_stock_report/__init__.py b/erpnext/manufacturing/report/production_order_stock_report/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/manufacturing/report/production_order_stock_report/production_order_stock_report.js b/erpnext/manufacturing/report/production_order_stock_report/production_order_stock_report.js new file mode 100644 index 00000000000..917af5da9d2 --- /dev/null +++ b/erpnext/manufacturing/report/production_order_stock_report/production_order_stock_report.js @@ -0,0 +1,14 @@ +// Copyright (c) 2016, Velometro Mobility Inc and contributors +// For license information, please see license.txt + +frappe.query_reports["Production Order Stock Report"] = { + "filters": [ + { + "fieldname":"warehouse", + "label": __("Warehouse"), + "fieldtype": "Link", + "options": "Warehouse" + + } + ] +} diff --git a/erpnext/manufacturing/report/production_order_stock_report/production_order_stock_report.json b/erpnext/manufacturing/report/production_order_stock_report/production_order_stock_report.json new file mode 100644 index 00000000000..1b1357e5669 --- /dev/null +++ b/erpnext/manufacturing/report/production_order_stock_report/production_order_stock_report.json @@ -0,0 +1,19 @@ +{ + "add_total_row": 0, + "apply_user_permissions": 1, + "creation": "2017-01-10 14:01:43.905861", + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "letter_head": "Standard", + "modified": "2017-01-10 14:01:43.905861", + "modified_by": "Administrator", + "module": "Manufacturing", + "name": "Production Order Stock Report", + "owner": "Administrator", + "ref_doctype": "Production Order", + "report_name": "Production Order Stock Report", + "report_type": "Script Report" +} \ No newline at end of file diff --git a/erpnext/manufacturing/report/production_order_stock_report/production_order_stock_report.py b/erpnext/manufacturing/report/production_order_stock_report/production_order_stock_report.py new file mode 100644 index 00000000000..4bb00a2939b --- /dev/null +++ b/erpnext/manufacturing/report/production_order_stock_report/production_order_stock_report.py @@ -0,0 +1,133 @@ +# Copyright (c) 2017, Velometro Mobility Inc and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +from frappe.utils import flt, cint +import frappe + +def execute(filters=None): + prod_list = get_production_orders() + data = get_item_list(prod_list, filters) + columns = get_columns() + return columns, data + +def get_item_list(prod_list, filters): + out = [] + + low_price_data = [] + low_supplier = [] + + #Add a row for each item/qty + for prod_order in prod_list: + bom = frappe.db.get_value("Production Order", prod_order.name, "bom_no") + warehouse = frappe.db.get_value("Production Order", prod_order.name, "source_warehouse") + desc = frappe.db.get_value("BOM", bom, "description") + qty = frappe.db.get_value("Production Order", prod_order.name, "qty") + produced_value = frappe.db.get_value("Production Order", prod_order.name, "produced_qty") + item_list = frappe.db.sql("""SELECT + bom_item.item_code as item_code, + ifnull(ledger.actual_qty/bom_item.qty,0) as build_qty + FROM + `tabBOM Item` AS bom_item + LEFT JOIN `tabBin` AS ledger + ON bom_item.item_code = ledger.item_code + AND ledger.warehouse = ifnull(%(warehouse)s,%(filterhouse)s) + WHERE + bom_item.parent = %(bom)s + GROUP BY + bom_item.item_code""", {"bom": bom, "warehouse": warehouse, "filterhouse": filters.warehouse}, as_dict=1) + stock_qty = 0 + count = 0 + buildable_qty = qty + for item in item_list: + count = count + 1 + if item.build_qty >= (qty-produced_value): + stock_qty = stock_qty + 1 + elif buildable_qty >= item.build_qty: + buildable_qty = item.build_qty + + + if count == stock_qty: + build = "Y" + else: + build = "N" + + row = frappe._dict({ + "production_order": prod_order.name, + "status": prod_order.status, + "req_items": cint(count), + "instock": stock_qty, + "description": desc, + "bom_no": bom, + "qty": qty, + "buildable_qty": buildable_qty, + "ready_to_build": build + }) + + out.append(row) + + return out + +def get_production_orders(): + + out = frappe.get_all("Production Order", filters={"docstatus": 1, "status": ( "!=","Completed")}, fields=["name","status"], order_by='name') + return out + +def get_columns(): + columns = [{ + "fieldname": "production_order", + "label": "Production Order", + "fieldtype": "Link", + "options": "Production Order", + "width": 110 + }, { + "fieldname": "bom_no", + "label": "BOM", + "fieldtype": "Link", + "options": "BOM", + "width": 120 + }, { + "fieldname": "description", + "label": "Description", + "fieldtype": "Data", + "options": "", + "width": 230 + }, { + "fieldname": "qty", + "label": "Qty to Build", + "fieldtype": "Data", + "options": "", + "width": 110 + }, { + "fieldname": "status", + "label": "Status", + "fieldtype": "Data", + "options": "", + "width": 100 + }, { + "fieldname": "req_items", + "label": "# Req'd Items", + "fieldtype": "Data", + "options": "", + "width": 105 + }, { + "fieldname": "instock", + "label": "# In Stock", + "fieldtype": "Data", + "options": "", + "width": 105 + }, { + "fieldname": "buildable_qty", + "label": "Buildable Qty", + "fieldtype": "Data", + "options": "", + "width": 100 + }, { + "fieldname": "ready_to_build", + "label": "Build All?", + "fieldtype": "Data", + "options": "", + "width": 90 + }] + + return columns