├── .gitignore ├── MANIFEST.in ├── README.md ├── license.txt ├── requirements.txt ├── setup.py └── spp ├── __init__.py ├── config ├── __init__.py ├── desktop.py └── docs.py ├── docs └── .gitkeep ├── hooks.py ├── modules.txt ├── patches.txt ├── public ├── .gitkeep ├── css │ └── .gitkeep └── js │ └── .gitkeep ├── simplified_production_process ├── __init__.py └── doctype │ ├── __init__.py │ ├── simplified_production_items │ ├── __init__.py │ ├── simplified_production_items.json │ └── simplified_production_items.py │ ├── simplified_production_material_request │ ├── __init__.py │ ├── simplified_production_material_request.json │ └── simplified_production_material_request.py │ ├── simplified_production_sales_orders │ ├── __init__.py │ ├── simplified_production_sales_orders.json │ └── simplified_production_sales_orders.py │ └── simplified_production_tool │ ├── __init__.py │ ├── simplified_production_tool.js │ ├── simplified_production_tool.json │ ├── simplified_production_tool.py │ ├── test_simplified_production_tool.js │ └── test_simplified_production_tool.py └── templates ├── __init__.py └── pages └── __init__.py /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.pyc 3 | *.egg-info 4 | *.swp 5 | tags 6 | spp/docs/current -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include MANIFEST.in 2 | include requirements.txt 3 | include *.json 4 | include *.md 5 | include *.py 6 | include *.txt 7 | recursive-include spp *.css 8 | recursive-include spp *.csv 9 | recursive-include spp *.html 10 | recursive-include spp *.ico 11 | recursive-include spp *.js 12 | recursive-include spp *.json 13 | recursive-include spp *.md 14 | recursive-include spp *.png 15 | recursive-include spp *.py 16 | recursive-include spp *.svg 17 | recursive-include spp *.txt 18 | recursive-exclude spp *.pyc -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Simplified Production Process 2 | 3 | Simplified production process was suggested first by @tara_antonius and we talked about it there: 4 | https://discuss.erpnext.com/t/manufacturing-process/17013 5 | 6 | SPP makes stock entries from BOMs to track a manufacture process without production orders. 7 | 8 | The code comes from Production Planning Tool. 9 | 10 | #### Please contribute 11 | 12 | Get orders from Material Request is not working for now. 13 | 14 | 15 | #### How to use 16 | 17 | Select some ordes with the filters, click on "get items", and then "manufacture items" 18 | Stock entries will be created and submited. 19 | 20 | Raw material source warehouse and Finished products destination warehouse are set from default warehouses settings inside 'Manufacturing Settings'. Leave one of this field or both fields empty and the default item's warehouse will be used. 21 | 22 | 23 | #### Installation 24 | 25 | ```shell 26 | bench get-app spp https://github.com/hiousi/erpnext-spp 27 | bench --site site1.local install-app spp ` 28 | ``` 29 | 30 | #### License 31 | 32 | MIT -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | License: MIT -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | frappe -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from setuptools import setup, find_packages 3 | import re, ast 4 | 5 | with open('requirements.txt') as f: 6 | install_requires = f.read().strip().split('\n') 7 | 8 | # get version from __version__ variable in spp/__init__.py 9 | _version_re = re.compile(r'__version__\s+=\s+(.*)') 10 | 11 | with open('spp/__init__.py', 'rb') as f: 12 | version = str(ast.literal_eval(_version_re.search( 13 | f.read().decode('utf-8')).group(1))) 14 | 15 | setup( 16 | name='spp', 17 | version=version, 18 | description='SPP makes stock entries from BOMs', 19 | author='hiousi', 20 | packages=find_packages(), 21 | zip_safe=False, 22 | include_package_data=True, 23 | install_requires=install_requires 24 | 25 | ) 26 | -------------------------------------------------------------------------------- /spp/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | __version__ = '0.0.1' 5 | 6 | -------------------------------------------------------------------------------- /spp/config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiousi/erpnext-spp/44eb2064bb476a2460a0f34085d61537bd60b2f3/spp/config/__init__.py -------------------------------------------------------------------------------- /spp/config/desktop.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | from frappe import _ 4 | 5 | def get_data(): 6 | return [ 7 | { 8 | "module_name": "Simplified Production Process", 9 | "color": "grey", 10 | "icon": "octicon octicon-file-directory", 11 | "type": "module", 12 | "label": _("Simplified Production Process") 13 | } 14 | ] 15 | -------------------------------------------------------------------------------- /spp/config/docs.py: -------------------------------------------------------------------------------- 1 | """ 2 | Configuration for docs 3 | """ 4 | 5 | # source_link = "https://github.com/[org_name]/spp" 6 | # docs_base_url = "https://[org_name].github.io/spp" 7 | # headline = "App that does everything" 8 | # sub_heading = "Yes, you got that right the first time, everything" 9 | 10 | def get_context(context): 11 | context.brand_html = "Simplified Production Process" 12 | -------------------------------------------------------------------------------- /spp/docs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiousi/erpnext-spp/44eb2064bb476a2460a0f34085d61537bd60b2f3/spp/docs/.gitkeep -------------------------------------------------------------------------------- /spp/hooks.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | from . import __version__ as app_version 4 | 5 | app_name = "spp" 6 | app_title = "Simplified Production Process" 7 | app_publisher = "o10c" 8 | app_description = "SPP makes stock entries from BOMs" 9 | app_icon = "octicon octicon-tools" 10 | app_color = "grey" 11 | app_email = "o10c@yahoo.fr" 12 | app_license = "MIT" 13 | 14 | # Includes in
15 | # ------------------ 16 | 17 | # include js, css files in header of desk.html 18 | # app_include_css = "/assets/spp/css/spp.css" 19 | # app_include_js = "/assets/spp/js/spp.js" 20 | 21 | # include js, css files in header of web template 22 | # web_include_css = "/assets/spp/css/spp.css" 23 | # web_include_js = "/assets/spp/js/spp.js" 24 | 25 | # include js in page 26 | # page_js = {"page" : "public/js/file.js"} 27 | 28 | # include js in doctype views 29 | # doctype_js = {"doctype" : "public/js/doctype.js"} 30 | # doctype_list_js = {"doctype" : "public/js/doctype_list.js"} 31 | # doctype_tree_js = {"doctype" : "public/js/doctype_tree.js"} 32 | # doctype_calendar_js = {"doctype" : "public/js/doctype_calendar.js"} 33 | 34 | # Home Pages 35 | # ---------- 36 | 37 | # application home page (will override Website Settings) 38 | # home_page = "login" 39 | 40 | # website user home page (by Role) 41 | # role_home_page = { 42 | # "Role": "home_page" 43 | # } 44 | 45 | # Website user home page (by function) 46 | # get_website_user_home_page = "spp.utils.get_home_page" 47 | 48 | # Generators 49 | # ---------- 50 | 51 | # automatically create page for each record of this doctype 52 | # website_generators = ["Web Page"] 53 | 54 | # Installation 55 | # ------------ 56 | 57 | # before_install = "spp.install.before_install" 58 | # after_install = "spp.install.after_install" 59 | 60 | # Desk Notifications 61 | # ------------------ 62 | # See frappe.core.notifications.get_notification_config 63 | 64 | # notification_config = "spp.notifications.get_notification_config" 65 | 66 | # Permissions 67 | # ----------- 68 | # Permissions evaluated in scripted ways 69 | 70 | # permission_query_conditions = { 71 | # "Event": "frappe.desk.doctype.event.event.get_permission_query_conditions", 72 | # } 73 | # 74 | # has_permission = { 75 | # "Event": "frappe.desk.doctype.event.event.has_permission", 76 | # } 77 | 78 | # Document Events 79 | # --------------- 80 | # Hook on document methods and events 81 | 82 | # doc_events = { 83 | # "*": { 84 | # "on_update": "method", 85 | # "on_cancel": "method", 86 | # "on_trash": "method" 87 | # } 88 | # } 89 | 90 | # Scheduled Tasks 91 | # --------------- 92 | 93 | # scheduler_events = { 94 | # "all": [ 95 | # "spp.tasks.all" 96 | # ], 97 | # "daily": [ 98 | # "spp.tasks.daily" 99 | # ], 100 | # "hourly": [ 101 | # "spp.tasks.hourly" 102 | # ], 103 | # "weekly": [ 104 | # "spp.tasks.weekly" 105 | # ] 106 | # "monthly": [ 107 | # "spp.tasks.monthly" 108 | # ] 109 | # } 110 | 111 | # Testing 112 | # ------- 113 | 114 | # before_tests = "spp.install.before_tests" 115 | 116 | # Overriding Whitelisted Methods 117 | # ------------------------------ 118 | # 119 | # override_whitelisted_methods = { 120 | # "frappe.desk.doctype.event.event.get_events": "spp.event.get_events" 121 | # } 122 | 123 | -------------------------------------------------------------------------------- /spp/modules.txt: -------------------------------------------------------------------------------- 1 | Simplified Production Process -------------------------------------------------------------------------------- /spp/patches.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiousi/erpnext-spp/44eb2064bb476a2460a0f34085d61537bd60b2f3/spp/patches.txt -------------------------------------------------------------------------------- /spp/public/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiousi/erpnext-spp/44eb2064bb476a2460a0f34085d61537bd60b2f3/spp/public/.gitkeep -------------------------------------------------------------------------------- /spp/public/css/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiousi/erpnext-spp/44eb2064bb476a2460a0f34085d61537bd60b2f3/spp/public/css/.gitkeep -------------------------------------------------------------------------------- /spp/public/js/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiousi/erpnext-spp/44eb2064bb476a2460a0f34085d61537bd60b2f3/spp/public/js/.gitkeep -------------------------------------------------------------------------------- /spp/simplified_production_process/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiousi/erpnext-spp/44eb2064bb476a2460a0f34085d61537bd60b2f3/spp/simplified_production_process/__init__.py -------------------------------------------------------------------------------- /spp/simplified_production_process/doctype/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiousi/erpnext-spp/44eb2064bb476a2460a0f34085d61537bd60b2f3/spp/simplified_production_process/doctype/__init__.py -------------------------------------------------------------------------------- /spp/simplified_production_process/doctype/simplified_production_items/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiousi/erpnext-spp/44eb2064bb476a2460a0f34085d61537bd60b2f3/spp/simplified_production_process/doctype/simplified_production_items/__init__.py -------------------------------------------------------------------------------- /spp/simplified_production_process/doctype/simplified_production_items/simplified_production_items.json: -------------------------------------------------------------------------------- 1 | { 2 | "allow_copy": 0, 3 | "allow_guest_to_view": 0, 4 | "allow_import": 0, 5 | "allow_rename": 0, 6 | "autoname": "hash", 7 | "beta": 0, 8 | "creation": "2017-08-24 14:53:21.646002", 9 | "custom": 0, 10 | "docstatus": 0, 11 | "doctype": "DocType", 12 | "document_type": "", 13 | "editable_grid": 1, 14 | "engine": "InnoDB", 15 | "fields": [ 16 | { 17 | "allow_bulk_edit": 0, 18 | "allow_on_submit": 0, 19 | "bold": 0, 20 | "collapsible": 0, 21 | "columns": 0, 22 | "fieldname": "item_code", 23 | "fieldtype": "Link", 24 | "hidden": 0, 25 | "ignore_user_permissions": 0, 26 | "ignore_xss_filter": 0, 27 | "in_filter": 0, 28 | "in_global_search": 0, 29 | "in_list_view": 1, 30 | "in_standard_filter": 0, 31 | "label": "Item Code", 32 | "length": 0, 33 | "no_copy": 0, 34 | "options": "Item", 35 | "permlevel": 0, 36 | "precision": "", 37 | "print_hide": 0, 38 | "print_hide_if_no_value": 0, 39 | "read_only": 0, 40 | "remember_last_selected_value": 0, 41 | "report_hide": 0, 42 | "reqd": 1, 43 | "search_index": 0, 44 | "set_only_once": 0, 45 | "unique": 0 46 | }, 47 | { 48 | "allow_bulk_edit": 0, 49 | "allow_on_submit": 0, 50 | "bold": 0, 51 | "collapsible": 0, 52 | "columns": 0, 53 | "fieldname": "bom_no", 54 | "fieldtype": "Link", 55 | "hidden": 0, 56 | "ignore_user_permissions": 0, 57 | "ignore_xss_filter": 0, 58 | "in_filter": 0, 59 | "in_global_search": 0, 60 | "in_list_view": 0, 61 | "in_standard_filter": 0, 62 | "label": "BOM", 63 | "length": 0, 64 | "no_copy": 0, 65 | "options": "BOM", 66 | "permlevel": 0, 67 | "precision": "", 68 | "print_hide": 0, 69 | "print_hide_if_no_value": 0, 70 | "read_only": 0, 71 | "remember_last_selected_value": 0, 72 | "report_hide": 0, 73 | "reqd": 1, 74 | "search_index": 0, 75 | "set_only_once": 0, 76 | "unique": 0 77 | }, 78 | { 79 | "allow_bulk_edit": 0, 80 | "allow_on_submit": 0, 81 | "bold": 0, 82 | "collapsible": 0, 83 | "columns": 0, 84 | "fieldname": "planned_qty", 85 | "fieldtype": "Float", 86 | "hidden": 0, 87 | "ignore_user_permissions": 0, 88 | "ignore_xss_filter": 0, 89 | "in_filter": 0, 90 | "in_global_search": 0, 91 | "in_list_view": 1, 92 | "in_standard_filter": 0, 93 | "label": "Planned Qty", 94 | "length": 0, 95 | "no_copy": 0, 96 | "permlevel": 0, 97 | "precision": "", 98 | "print_hide": 0, 99 | "print_hide_if_no_value": 0, 100 | "read_only": 0, 101 | "remember_last_selected_value": 0, 102 | "report_hide": 0, 103 | "reqd": 1, 104 | "search_index": 0, 105 | "set_only_once": 0, 106 | "unique": 0 107 | }, 108 | { 109 | "allow_bulk_edit": 0, 110 | "allow_on_submit": 0, 111 | "bold": 0, 112 | "collapsible": 0, 113 | "columns": 0, 114 | "fieldname": "plannad_start_date", 115 | "fieldtype": "Datetime", 116 | "hidden": 0, 117 | "ignore_user_permissions": 0, 118 | "ignore_xss_filter": 0, 119 | "in_filter": 0, 120 | "in_global_search": 0, 121 | "in_list_view": 1, 122 | "in_standard_filter": 0, 123 | "label": "Planned Start Date", 124 | "length": 0, 125 | "no_copy": 0, 126 | "permlevel": 0, 127 | "precision": "", 128 | "print_hide": 0, 129 | "print_hide_if_no_value": 0, 130 | "read_only": 0, 131 | "remember_last_selected_value": 0, 132 | "report_hide": 0, 133 | "reqd": 1, 134 | "search_index": 0, 135 | "set_only_once": 0, 136 | "unique": 0 137 | }, 138 | { 139 | "allow_bulk_edit": 0, 140 | "allow_on_submit": 0, 141 | "bold": 0, 142 | "collapsible": 0, 143 | "columns": 0, 144 | "fieldname": "column_break_5", 145 | "fieldtype": "Column Break", 146 | "hidden": 0, 147 | "ignore_user_permissions": 0, 148 | "ignore_xss_filter": 0, 149 | "in_filter": 0, 150 | "in_global_search": 0, 151 | "in_list_view": 0, 152 | "in_standard_filter": 0, 153 | "length": 0, 154 | "no_copy": 0, 155 | "permlevel": 0, 156 | "precision": "", 157 | "print_hide": 0, 158 | "print_hide_if_no_value": 0, 159 | "read_only": 0, 160 | "remember_last_selected_value": 0, 161 | "report_hide": 0, 162 | "reqd": 0, 163 | "search_index": 0, 164 | "set_only_once": 0, 165 | "unique": 0 166 | }, 167 | { 168 | "allow_bulk_edit": 0, 169 | "allow_on_submit": 0, 170 | "bold": 0, 171 | "collapsible": 0, 172 | "columns": 0, 173 | "fieldname": "warehouse", 174 | "fieldtype": "Link", 175 | "hidden": 0, 176 | "ignore_user_permissions": 0, 177 | "ignore_xss_filter": 0, 178 | "in_filter": 0, 179 | "in_global_search": 0, 180 | "in_list_view": 0, 181 | "in_standard_filter": 0, 182 | "label": "Warehouse", 183 | "length": 0, 184 | "no_copy": 0, 185 | "options": "Warehouse", 186 | "permlevel": 0, 187 | "precision": "", 188 | "print_hide": 0, 189 | "print_hide_if_no_value": 0, 190 | "read_only": 0, 191 | "remember_last_selected_value": 0, 192 | "report_hide": 0, 193 | "reqd": 0, 194 | "search_index": 0, 195 | "set_only_once": 0, 196 | "unique": 0 197 | }, 198 | { 199 | "allow_bulk_edit": 0, 200 | "allow_on_submit": 0, 201 | "bold": 0, 202 | "collapsible": 0, 203 | "columns": 0, 204 | "fieldname": "sales_order", 205 | "fieldtype": "Link", 206 | "hidden": 0, 207 | "ignore_user_permissions": 0, 208 | "ignore_xss_filter": 0, 209 | "in_filter": 0, 210 | "in_global_search": 0, 211 | "in_list_view": 0, 212 | "in_standard_filter": 0, 213 | "label": "Sales Order", 214 | "length": 0, 215 | "no_copy": 0, 216 | "options": "Sales Order", 217 | "permlevel": 0, 218 | "precision": "", 219 | "print_hide": 0, 220 | "print_hide_if_no_value": 0, 221 | "read_only": 1, 222 | "remember_last_selected_value": 0, 223 | "report_hide": 0, 224 | "reqd": 0, 225 | "search_index": 0, 226 | "set_only_once": 0, 227 | "unique": 0 228 | }, 229 | { 230 | "allow_bulk_edit": 0, 231 | "allow_on_submit": 0, 232 | "bold": 0, 233 | "collapsible": 0, 234 | "columns": 0, 235 | "fieldname": "material_request", 236 | "fieldtype": "Link", 237 | "hidden": 0, 238 | "ignore_user_permissions": 0, 239 | "ignore_xss_filter": 0, 240 | "in_filter": 0, 241 | "in_global_search": 0, 242 | "in_list_view": 0, 243 | "in_standard_filter": 0, 244 | "label": "Material Request", 245 | "length": 0, 246 | "no_copy": 0, 247 | "options": "Material Request", 248 | "permlevel": 0, 249 | "precision": "", 250 | "print_hide": 0, 251 | "print_hide_if_no_value": 0, 252 | "read_only": 1, 253 | "remember_last_selected_value": 0, 254 | "report_hide": 0, 255 | "reqd": 0, 256 | "search_index": 0, 257 | "set_only_once": 0, 258 | "unique": 0 259 | }, 260 | { 261 | "allow_bulk_edit": 0, 262 | "allow_on_submit": 0, 263 | "bold": 0, 264 | "collapsible": 0, 265 | "columns": 0, 266 | "fieldname": "pending_qty", 267 | "fieldtype": "Float", 268 | "hidden": 0, 269 | "ignore_user_permissions": 0, 270 | "ignore_xss_filter": 0, 271 | "in_filter": 0, 272 | "in_global_search": 0, 273 | "in_list_view": 1, 274 | "in_standard_filter": 0, 275 | "label": "Pending Qty", 276 | "length": 0, 277 | "no_copy": 0, 278 | "permlevel": 0, 279 | "precision": "", 280 | "print_hide": 0, 281 | "print_hide_if_no_value": 0, 282 | "read_only": 1, 283 | "remember_last_selected_value": 0, 284 | "report_hide": 0, 285 | "reqd": 0, 286 | "search_index": 0, 287 | "set_only_once": 0, 288 | "unique": 0, 289 | "width": "100px" 290 | }, 291 | { 292 | "allow_bulk_edit": 0, 293 | "allow_on_submit": 0, 294 | "bold": 0, 295 | "collapsible": 0, 296 | "columns": 0, 297 | "fieldname": "stock_uom", 298 | "fieldtype": "Link", 299 | "hidden": 0, 300 | "ignore_user_permissions": 0, 301 | "ignore_xss_filter": 0, 302 | "in_filter": 0, 303 | "in_global_search": 0, 304 | "in_list_view": 0, 305 | "in_standard_filter": 0, 306 | "label": "UOM", 307 | "length": 0, 308 | "no_copy": 0, 309 | "options": "UOM", 310 | "permlevel": 0, 311 | "precision": "", 312 | "print_hide": 0, 313 | "print_hide_if_no_value": 0, 314 | "read_only": 1, 315 | "remember_last_selected_value": 0, 316 | "report_hide": 0, 317 | "reqd": 1, 318 | "search_index": 0, 319 | "set_only_once": 0, 320 | "unique": 0, 321 | "width": "80px" 322 | }, 323 | { 324 | "allow_bulk_edit": 0, 325 | "allow_on_submit": 0, 326 | "bold": 0, 327 | "collapsible": 0, 328 | "columns": 0, 329 | "fieldname": "description", 330 | "fieldtype": "Text Editor", 331 | "hidden": 0, 332 | "ignore_user_permissions": 0, 333 | "ignore_xss_filter": 0, 334 | "in_filter": 0, 335 | "in_global_search": 0, 336 | "in_list_view": 1, 337 | "in_standard_filter": 0, 338 | "label": "Description", 339 | "length": 0, 340 | "no_copy": 0, 341 | "permlevel": 0, 342 | "precision": "", 343 | "print_hide": 0, 344 | "print_hide_if_no_value": 0, 345 | "read_only": 0, 346 | "remember_last_selected_value": 0, 347 | "report_hide": 0, 348 | "reqd": 0, 349 | "search_index": 0, 350 | "set_only_once": 0, 351 | "unique": 0 352 | }, 353 | { 354 | "allow_bulk_edit": 0, 355 | "allow_on_submit": 0, 356 | "bold": 0, 357 | "collapsible": 0, 358 | "columns": 0, 359 | "fieldname": "material_request_item", 360 | "fieldtype": "Data", 361 | "hidden": 0, 362 | "ignore_user_permissions": 0, 363 | "ignore_xss_filter": 0, 364 | "in_filter": 0, 365 | "in_global_search": 0, 366 | "in_list_view": 0, 367 | "in_standard_filter": 0, 368 | "label": "material_request_item", 369 | "length": 0, 370 | "no_copy": 0, 371 | "permlevel": 0, 372 | "precision": "", 373 | "print_hide": 0, 374 | "print_hide_if_no_value": 0, 375 | "read_only": 0, 376 | "remember_last_selected_value": 0, 377 | "report_hide": 0, 378 | "reqd": 0, 379 | "search_index": 0, 380 | "set_only_once": 0, 381 | "unique": 0 382 | } 383 | ], 384 | "has_web_view": 0, 385 | "hide_heading": 0, 386 | "hide_toolbar": 0, 387 | "idx": 0, 388 | "image_view": 0, 389 | "in_create": 0, 390 | "is_submittable": 0, 391 | "issingle": 0, 392 | "istable": 1, 393 | "max_attachments": 0, 394 | "modified": "2017-10-13 18:26:25.386906", 395 | "modified_by": "Administrator", 396 | "module": "Simplified Production Process", 397 | "name": "Simplified Production Items", 398 | "name_case": "", 399 | "owner": "Administrator", 400 | "permissions": [], 401 | "quick_entry": 1, 402 | "read_only": 0, 403 | "read_only_onload": 0, 404 | "show_name_in_global_search": 0, 405 | "sort_field": "modified", 406 | "sort_order": "DESC", 407 | "track_changes": 1, 408 | "track_seen": 0 409 | } -------------------------------------------------------------------------------- /spp/simplified_production_process/doctype/simplified_production_items/simplified_production_items.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (c) 2017, o10c and contributors 3 | # For license information, please see license.txt 4 | 5 | from __future__ import unicode_literals 6 | import frappe 7 | from frappe.model.document import Document 8 | 9 | class SimplifiedProductionItems(Document): 10 | pass 11 | -------------------------------------------------------------------------------- /spp/simplified_production_process/doctype/simplified_production_material_request/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiousi/erpnext-spp/44eb2064bb476a2460a0f34085d61537bd60b2f3/spp/simplified_production_process/doctype/simplified_production_material_request/__init__.py -------------------------------------------------------------------------------- /spp/simplified_production_process/doctype/simplified_production_material_request/simplified_production_material_request.json: -------------------------------------------------------------------------------- 1 | { 2 | "allow_copy": 0, 3 | "allow_guest_to_view": 0, 4 | "allow_import": 0, 5 | "allow_rename": 0, 6 | "beta": 0, 7 | "creation": "2017-08-24 15:33:26.975390", 8 | "custom": 0, 9 | "docstatus": 0, 10 | "doctype": "DocType", 11 | "document_type": "", 12 | "editable_grid": 1, 13 | "engine": "InnoDB", 14 | "fields": [ 15 | { 16 | "allow_bulk_edit": 0, 17 | "allow_on_submit": 0, 18 | "bold": 0, 19 | "collapsible": 0, 20 | "columns": 0, 21 | "fieldname": "material_request", 22 | "fieldtype": "Link", 23 | "hidden": 0, 24 | "ignore_user_permissions": 0, 25 | "ignore_xss_filter": 0, 26 | "in_filter": 0, 27 | "in_global_search": 0, 28 | "in_list_view": 0, 29 | "in_standard_filter": 0, 30 | "label": "Material Request", 31 | "length": 0, 32 | "no_copy": 0, 33 | "options": "Material Request", 34 | "permlevel": 0, 35 | "precision": "", 36 | "print_hide": 0, 37 | "print_hide_if_no_value": 0, 38 | "read_only": 0, 39 | "remember_last_selected_value": 0, 40 | "report_hide": 0, 41 | "reqd": 0, 42 | "search_index": 0, 43 | "set_only_once": 0, 44 | "unique": 0 45 | }, 46 | { 47 | "allow_bulk_edit": 0, 48 | "allow_on_submit": 0, 49 | "bold": 0, 50 | "collapsible": 0, 51 | "columns": 0, 52 | "fieldname": "column_break_2", 53 | "fieldtype": "Column Break", 54 | "hidden": 0, 55 | "ignore_user_permissions": 0, 56 | "ignore_xss_filter": 0, 57 | "in_filter": 0, 58 | "in_global_search": 0, 59 | "in_list_view": 0, 60 | "in_standard_filter": 0, 61 | "length": 0, 62 | "no_copy": 0, 63 | "permlevel": 0, 64 | "precision": "", 65 | "print_hide": 0, 66 | "print_hide_if_no_value": 0, 67 | "read_only": 0, 68 | "remember_last_selected_value": 0, 69 | "report_hide": 0, 70 | "reqd": 0, 71 | "search_index": 0, 72 | "set_only_once": 0, 73 | "unique": 0 74 | }, 75 | { 76 | "allow_bulk_edit": 0, 77 | "allow_on_submit": 0, 78 | "bold": 0, 79 | "collapsible": 0, 80 | "columns": 0, 81 | "fieldname": "material_request_date", 82 | "fieldtype": "Date", 83 | "hidden": 0, 84 | "ignore_user_permissions": 0, 85 | "ignore_xss_filter": 0, 86 | "in_filter": 0, 87 | "in_global_search": 0, 88 | "in_list_view": 0, 89 | "in_standard_filter": 0, 90 | "label": "Material Request Date", 91 | "length": 0, 92 | "no_copy": 0, 93 | "permlevel": 0, 94 | "precision": "", 95 | "print_hide": 0, 96 | "print_hide_if_no_value": 0, 97 | "read_only": 0, 98 | "remember_last_selected_value": 0, 99 | "report_hide": 0, 100 | "reqd": 0, 101 | "search_index": 0, 102 | "set_only_once": 0, 103 | "unique": 0 104 | } 105 | ], 106 | "has_web_view": 0, 107 | "hide_heading": 0, 108 | "hide_toolbar": 0, 109 | "idx": 0, 110 | "image_view": 0, 111 | "in_create": 0, 112 | "is_submittable": 0, 113 | "issingle": 0, 114 | "istable": 1, 115 | "max_attachments": 0, 116 | "modified": "2017-10-13 18:26:31.787434", 117 | "modified_by": "Administrator", 118 | "module": "Simplified Production Process", 119 | "name": "Simplified Production Material Request", 120 | "name_case": "", 121 | "owner": "Administrator", 122 | "permissions": [], 123 | "quick_entry": 1, 124 | "read_only": 0, 125 | "read_only_onload": 0, 126 | "show_name_in_global_search": 0, 127 | "sort_field": "modified", 128 | "sort_order": "DESC", 129 | "track_changes": 1, 130 | "track_seen": 0 131 | } -------------------------------------------------------------------------------- /spp/simplified_production_process/doctype/simplified_production_material_request/simplified_production_material_request.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (c) 2017, o10c and contributors 3 | # For license information, please see license.txt 4 | 5 | from __future__ import unicode_literals 6 | import frappe 7 | from frappe.model.document import Document 8 | 9 | class SimplifiedProductionMaterialRequest(Document): 10 | pass 11 | -------------------------------------------------------------------------------- /spp/simplified_production_process/doctype/simplified_production_sales_orders/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiousi/erpnext-spp/44eb2064bb476a2460a0f34085d61537bd60b2f3/spp/simplified_production_process/doctype/simplified_production_sales_orders/__init__.py -------------------------------------------------------------------------------- /spp/simplified_production_process/doctype/simplified_production_sales_orders/simplified_production_sales_orders.json: -------------------------------------------------------------------------------- 1 | { 2 | "allow_copy": 0, 3 | "allow_guest_to_view": 0, 4 | "allow_import": 0, 5 | "allow_rename": 0, 6 | "autoname": "hash", 7 | "beta": 0, 8 | "creation": "2017-08-24 11:50:58.461102", 9 | "custom": 0, 10 | "docstatus": 0, 11 | "doctype": "DocType", 12 | "document_type": "", 13 | "editable_grid": 1, 14 | "engine": "InnoDB", 15 | "fields": [ 16 | { 17 | "allow_bulk_edit": 0, 18 | "allow_on_submit": 0, 19 | "bold": 0, 20 | "collapsible": 0, 21 | "columns": 0, 22 | "fieldname": "sales_order", 23 | "fieldtype": "Link", 24 | "hidden": 0, 25 | "ignore_user_permissions": 0, 26 | "ignore_xss_filter": 0, 27 | "in_filter": 0, 28 | "in_global_search": 0, 29 | "in_list_view": 1, 30 | "in_standard_filter": 0, 31 | "label": "Sales Order", 32 | "length": 0, 33 | "no_copy": 0, 34 | "options": "Sales Order", 35 | "permlevel": 0, 36 | "precision": "", 37 | "print_hide": 0, 38 | "print_hide_if_no_value": 0, 39 | "read_only": 0, 40 | "remember_last_selected_value": 0, 41 | "report_hide": 0, 42 | "reqd": 0, 43 | "search_index": 0, 44 | "set_only_once": 0, 45 | "unique": 0 46 | }, 47 | { 48 | "allow_bulk_edit": 0, 49 | "allow_on_submit": 0, 50 | "bold": 0, 51 | "collapsible": 0, 52 | "columns": 0, 53 | "fieldname": "sales_order_date", 54 | "fieldtype": "Date", 55 | "hidden": 0, 56 | "ignore_user_permissions": 0, 57 | "ignore_xss_filter": 0, 58 | "in_filter": 0, 59 | "in_global_search": 0, 60 | "in_list_view": 1, 61 | "in_standard_filter": 0, 62 | "label": "Sales Order Date", 63 | "length": 0, 64 | "no_copy": 0, 65 | "permlevel": 0, 66 | "precision": "", 67 | "print_hide": 0, 68 | "print_hide_if_no_value": 0, 69 | "read_only": 0, 70 | "remember_last_selected_value": 0, 71 | "report_hide": 0, 72 | "reqd": 0, 73 | "search_index": 0, 74 | "set_only_once": 0, 75 | "unique": 0 76 | }, 77 | { 78 | "allow_bulk_edit": 0, 79 | "allow_on_submit": 0, 80 | "bold": 0, 81 | "collapsible": 0, 82 | "columns": 0, 83 | "fieldname": "column_break_3", 84 | "fieldtype": "Column Break", 85 | "hidden": 0, 86 | "ignore_user_permissions": 0, 87 | "ignore_xss_filter": 0, 88 | "in_filter": 0, 89 | "in_global_search": 0, 90 | "in_list_view": 0, 91 | "in_standard_filter": 0, 92 | "length": 0, 93 | "no_copy": 0, 94 | "options": "", 95 | "permlevel": 0, 96 | "precision": "", 97 | "print_hide": 0, 98 | "print_hide_if_no_value": 0, 99 | "read_only": 0, 100 | "remember_last_selected_value": 0, 101 | "report_hide": 0, 102 | "reqd": 0, 103 | "search_index": 0, 104 | "set_only_once": 0, 105 | "unique": 0 106 | }, 107 | { 108 | "allow_bulk_edit": 0, 109 | "allow_on_submit": 0, 110 | "bold": 0, 111 | "collapsible": 0, 112 | "columns": 0, 113 | "fieldname": "customer", 114 | "fieldtype": "Link", 115 | "hidden": 0, 116 | "ignore_user_permissions": 0, 117 | "ignore_xss_filter": 0, 118 | "in_filter": 0, 119 | "in_global_search": 0, 120 | "in_list_view": 1, 121 | "in_standard_filter": 0, 122 | "label": "Customer", 123 | "length": 0, 124 | "no_copy": 0, 125 | "options": "Customer", 126 | "permlevel": 0, 127 | "precision": "", 128 | "print_hide": 0, 129 | "print_hide_if_no_value": 0, 130 | "read_only": 0, 131 | "remember_last_selected_value": 0, 132 | "report_hide": 0, 133 | "reqd": 0, 134 | "search_index": 0, 135 | "set_only_once": 0, 136 | "unique": 0 137 | }, 138 | { 139 | "allow_bulk_edit": 0, 140 | "allow_on_submit": 0, 141 | "bold": 0, 142 | "collapsible": 0, 143 | "columns": 0, 144 | "fieldname": "grand_total", 145 | "fieldtype": "Currency", 146 | "hidden": 0, 147 | "ignore_user_permissions": 0, 148 | "ignore_xss_filter": 0, 149 | "in_filter": 0, 150 | "in_global_search": 0, 151 | "in_list_view": 1, 152 | "in_standard_filter": 0, 153 | "label": "Grand Total", 154 | "length": 0, 155 | "no_copy": 0, 156 | "permlevel": 0, 157 | "precision": "", 158 | "print_hide": 0, 159 | "print_hide_if_no_value": 0, 160 | "read_only": 0, 161 | "remember_last_selected_value": 0, 162 | "report_hide": 0, 163 | "reqd": 0, 164 | "search_index": 0, 165 | "set_only_once": 0, 166 | "unique": 0 167 | } 168 | ], 169 | "has_web_view": 0, 170 | "hide_heading": 0, 171 | "hide_toolbar": 0, 172 | "idx": 0, 173 | "image_view": 0, 174 | "in_create": 0, 175 | "is_submittable": 0, 176 | "issingle": 0, 177 | "istable": 1, 178 | "max_attachments": 0, 179 | "modified": "2017-10-13 18:26:37.370338", 180 | "modified_by": "Administrator", 181 | "module": "Simplified Production Process", 182 | "name": "Simplified Production Sales Orders", 183 | "name_case": "", 184 | "owner": "Administrator", 185 | "permissions": [], 186 | "quick_entry": 1, 187 | "read_only": 0, 188 | "read_only_onload": 0, 189 | "show_name_in_global_search": 0, 190 | "sort_field": "modified", 191 | "sort_order": "DESC", 192 | "track_changes": 1, 193 | "track_seen": 0 194 | } -------------------------------------------------------------------------------- /spp/simplified_production_process/doctype/simplified_production_sales_orders/simplified_production_sales_orders.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (c) 2017, o10c and contributors 3 | # For license information, please see license.txt 4 | 5 | from __future__ import unicode_literals 6 | import frappe 7 | from frappe.model.document import Document 8 | 9 | class SimplifiedProductionSalesOrders(Document): 10 | pass 11 | -------------------------------------------------------------------------------- /spp/simplified_production_process/doctype/simplified_production_tool/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiousi/erpnext-spp/44eb2064bb476a2460a0f34085d61537bd60b2f3/spp/simplified_production_process/doctype/simplified_production_tool/__init__.py -------------------------------------------------------------------------------- /spp/simplified_production_process/doctype/simplified_production_tool/simplified_production_tool.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | cur_frm.cscript.onload = function(doc) { 4 | cur_frm.set_value("company", frappe.defaults.get_user_default("Company")) 5 | } 6 | */ 7 | 8 | 9 | cur_frm.cscript.refresh = function(doc) { 10 | cur_frm.disable_save(); 11 | } 12 | 13 | 14 | cur_frm.add_fetch("material_request", "transaction_date", "material_request_date"); 15 | 16 | cur_frm.add_fetch("sales_order", "transaction_date", "sales_order_date"); 17 | cur_frm.add_fetch("sales_order", "customer", "customer"); 18 | cur_frm.add_fetch("sales_order", "base_grand_total", "grand_total"); 19 | 20 | frappe.ui.form.on("Simplified Production Tool", { 21 | 22 | onload_post_render: function(frm) { 23 | frm.get_field("items").grid.set_multiple_add("item_code", "planned_qty"); 24 | }, 25 | 26 | get_sales_orders: function(frm) { 27 | frappe.call({ 28 | doc: frm.doc, 29 | method: "get_open_sales_orders", 30 | callback: function(r) { 31 | refresh_field("sales_orders"); 32 | } 33 | }); 34 | }, 35 | 36 | get_material_request: function(frm) { 37 | frappe.call({ 38 | doc: frm.doc, 39 | method: "get_pending_material_requests", 40 | callback: function(r) { 41 | refresh_field("material_requests"); 42 | } 43 | }); 44 | }, 45 | 46 | get_items: function(frm) { 47 | frappe.call({ 48 | doc: frm.doc, 49 | method: "get_items", 50 | callback: function(r) { 51 | refresh_field("items"); 52 | } 53 | }); 54 | }, 55 | 56 | manufacture_items: function(frm) { 57 | frappe.call({ 58 | doc: frm.doc, 59 | method: "raise_stock_entries" 60 | }); 61 | }, 62 | 63 | create_material_requests: function(frm) { 64 | frappe.call({ 65 | doc: frm.doc, 66 | method: "raise_material_requests" 67 | }); 68 | } 69 | 70 | 71 | }); 72 | 73 | 74 | 75 | cur_frm.cscript.item_code = function(doc,cdt,cdn) { 76 | var d = locals[cdt][cdn]; 77 | if (d.item_code) { 78 | frappe.call({ 79 | method: "erpnext.manufacturing.doctype.production_order.production_order.get_item_details", 80 | args: { 81 | "item" : d.item_code 82 | }, 83 | callback: function(r) { 84 | $.extend(d, r.message); 85 | refresh_field("items"); 86 | } 87 | }); 88 | } 89 | } 90 | 91 | cur_frm.cscript.download_materials_required = function(doc, cdt, cdn) { 92 | return $c_obj(doc, 'validate_data', '', function(r, rt) { 93 | if (!r['exc']) 94 | $c_obj_csv(doc, 'download_raw_materials', '', ''); 95 | }); 96 | } 97 | 98 | 99 | 100 | cur_frm.fields_dict['sales_orders'].grid.get_field('sales_order').get_query = function(doc) { 101 | var args = { "docstatus": 1 }; 102 | if(doc.customer) { 103 | args["customer"] = doc.customer; 104 | } 105 | 106 | return { filters: args } 107 | } 108 | 109 | 110 | 111 | cur_frm.fields_dict['items'].grid.get_field('item_code').get_query = function(doc) { 112 | return erpnext.queries.item({ 113 | 'is_stock_item': 1 114 | }); 115 | } 116 | 117 | cur_frm.fields_dict['items'].grid.get_field('bom_no').get_query = function(doc, cdt, cdn) { 118 | var d = locals[cdt][cdn]; 119 | if (d.item_code) { 120 | return { 121 | query: "erpnext.controllers.queries.bom", 122 | filters:{'item': cstr(d.item_code)} 123 | } 124 | } else frappe.msgprint(__("Please enter Item first")); 125 | } 126 | 127 | 128 | 129 | 130 | cur_frm.fields_dict.customer.get_query = function(doc,cdt,cdn) { 131 | return{ 132 | query: "erpnext.controllers.queries.customer_query" 133 | } 134 | } 135 | 136 | cur_frm.fields_dict.sales_orders.grid.get_field("customer").get_query = 137 | cur_frm.fields_dict.customer.get_query; 138 | 139 | cur_frm.cscript.planned_start_date = function(doc, cdt, cdn) { 140 | erpnext.utils.copy_value_in_all_row(doc, cdt, cdn, "items", "planned_start_date"); 141 | } 142 | 143 | 144 | -------------------------------------------------------------------------------- /spp/simplified_production_process/doctype/simplified_production_tool/simplified_production_tool.json: -------------------------------------------------------------------------------- 1 | { 2 | "allow_copy": 1, 3 | "allow_guest_to_view": 0, 4 | "allow_import": 0, 5 | "allow_rename": 0, 6 | "beta": 0, 7 | "creation": "2017-08-24 11:32:58.610832", 8 | "custom": 0, 9 | "description": "Separate stock entries will be created for each finished good item.", 10 | "docstatus": 0, 11 | "doctype": "DocType", 12 | "document_type": "Setup", 13 | "editable_grid": 1, 14 | "engine": "InnoDB", 15 | "fields": [ 16 | { 17 | "allow_bulk_edit": 0, 18 | "allow_on_submit": 0, 19 | "bold": 0, 20 | "collapsible": 0, 21 | "columns": 0, 22 | "fieldname": "get_items_from", 23 | "fieldtype": "Select", 24 | "hidden": 0, 25 | "ignore_user_permissions": 0, 26 | "ignore_xss_filter": 0, 27 | "in_filter": 0, 28 | "in_global_search": 0, 29 | "in_list_view": 0, 30 | "in_standard_filter": 0, 31 | "label": "Get Items From", 32 | "length": 0, 33 | "no_copy": 0, 34 | "options": "\nSales Order\nMaterial Request", 35 | "permlevel": 0, 36 | "precision": "", 37 | "print_hide": 0, 38 | "print_hide_if_no_value": 0, 39 | "read_only": 0, 40 | "remember_last_selected_value": 0, 41 | "report_hide": 0, 42 | "reqd": 0, 43 | "search_index": 0, 44 | "set_only_once": 0, 45 | "unique": 0 46 | }, 47 | { 48 | "allow_bulk_edit": 0, 49 | "allow_on_submit": 0, 50 | "bold": 0, 51 | "collapsible": 0, 52 | "columns": 0, 53 | "depends_on": "get_items_from", 54 | "fieldname": "filters", 55 | "fieldtype": "Section Break", 56 | "hidden": 0, 57 | "ignore_user_permissions": 0, 58 | "ignore_xss_filter": 0, 59 | "in_filter": 0, 60 | "in_global_search": 0, 61 | "in_list_view": 0, 62 | "in_standard_filter": 0, 63 | "label": "Filters", 64 | "length": 0, 65 | "no_copy": 0, 66 | "permlevel": 0, 67 | "precision": "", 68 | "print_hide": 0, 69 | "print_hide_if_no_value": 0, 70 | "read_only": 0, 71 | "remember_last_selected_value": 0, 72 | "report_hide": 0, 73 | "reqd": 0, 74 | "search_index": 0, 75 | "set_only_once": 0, 76 | "unique": 0 77 | }, 78 | { 79 | "allow_bulk_edit": 0, 80 | "allow_on_submit": 0, 81 | "bold": 0, 82 | "collapsible": 0, 83 | "columns": 0, 84 | "fieldname": "fg_item", 85 | "fieldtype": "Link", 86 | "hidden": 0, 87 | "ignore_user_permissions": 0, 88 | "ignore_xss_filter": 0, 89 | "in_filter": 0, 90 | "in_global_search": 0, 91 | "in_list_view": 1, 92 | "in_standard_filter": 0, 93 | "label": "Item", 94 | "length": 0, 95 | "no_copy": 0, 96 | "options": "Item", 97 | "permlevel": 0, 98 | "precision": "", 99 | "print_hide": 0, 100 | "print_hide_if_no_value": 0, 101 | "read_only": 0, 102 | "remember_last_selected_value": 0, 103 | "report_hide": 0, 104 | "reqd": 0, 105 | "search_index": 0, 106 | "set_only_once": 0, 107 | "unique": 0 108 | }, 109 | { 110 | "allow_bulk_edit": 0, 111 | "allow_on_submit": 0, 112 | "bold": 0, 113 | "collapsible": 0, 114 | "columns": 0, 115 | "fieldname": "customer", 116 | "fieldtype": "Link", 117 | "hidden": 0, 118 | "ignore_user_permissions": 0, 119 | "ignore_xss_filter": 0, 120 | "in_filter": 0, 121 | "in_global_search": 0, 122 | "in_list_view": 1, 123 | "in_standard_filter": 0, 124 | "label": "Customer", 125 | "length": 0, 126 | "no_copy": 0, 127 | "options": "Customer", 128 | "permlevel": 0, 129 | "precision": "", 130 | "print_hide": 0, 131 | "print_hide_if_no_value": 0, 132 | "read_only": 0, 133 | "remember_last_selected_value": 0, 134 | "report_hide": 0, 135 | "reqd": 0, 136 | "search_index": 0, 137 | "set_only_once": 0, 138 | "unique": 0 139 | }, 140 | { 141 | "allow_bulk_edit": 0, 142 | "allow_on_submit": 0, 143 | "bold": 0, 144 | "collapsible": 0, 145 | "columns": 0, 146 | "fieldname": "company", 147 | "fieldtype": "Link", 148 | "hidden": 0, 149 | "ignore_user_permissions": 0, 150 | "ignore_xss_filter": 0, 151 | "in_filter": 0, 152 | "in_global_search": 0, 153 | "in_list_view": 0, 154 | "in_standard_filter": 0, 155 | "label": "Company", 156 | "length": 0, 157 | "no_copy": 0, 158 | "options": "Company", 159 | "permlevel": 0, 160 | "precision": "", 161 | "print_hide": 0, 162 | "print_hide_if_no_value": 0, 163 | "read_only": 0, 164 | "remember_last_selected_value": 0, 165 | "report_hide": 0, 166 | "reqd": 0, 167 | "search_index": 0, 168 | "set_only_once": 0, 169 | "unique": 0 170 | }, 171 | { 172 | "allow_bulk_edit": 0, 173 | "allow_on_submit": 0, 174 | "bold": 0, 175 | "collapsible": 0, 176 | "columns": 0, 177 | "fieldname": "column_break_5", 178 | "fieldtype": "Column Break", 179 | "hidden": 0, 180 | "ignore_user_permissions": 0, 181 | "ignore_xss_filter": 0, 182 | "in_filter": 0, 183 | "in_global_search": 0, 184 | "in_list_view": 0, 185 | "in_standard_filter": 0, 186 | "length": 0, 187 | "no_copy": 0, 188 | "permlevel": 0, 189 | "precision": "", 190 | "print_hide": 0, 191 | "print_hide_if_no_value": 0, 192 | "read_only": 0, 193 | "remember_last_selected_value": 0, 194 | "report_hide": 0, 195 | "reqd": 0, 196 | "search_index": 0, 197 | "set_only_once": 0, 198 | "unique": 0 199 | }, 200 | { 201 | "allow_bulk_edit": 0, 202 | "allow_on_submit": 0, 203 | "bold": 0, 204 | "collapsible": 0, 205 | "columns": 0, 206 | "fieldname": "from_date", 207 | "fieldtype": "Date", 208 | "hidden": 0, 209 | "ignore_user_permissions": 0, 210 | "ignore_xss_filter": 0, 211 | "in_filter": 0, 212 | "in_global_search": 0, 213 | "in_list_view": 0, 214 | "in_standard_filter": 0, 215 | "label": "From date", 216 | "length": 0, 217 | "no_copy": 0, 218 | "permlevel": 0, 219 | "precision": "", 220 | "print_hide": 0, 221 | "print_hide_if_no_value": 0, 222 | "read_only": 0, 223 | "remember_last_selected_value": 0, 224 | "report_hide": 0, 225 | "reqd": 0, 226 | "search_index": 0, 227 | "set_only_once": 0, 228 | "unique": 0 229 | }, 230 | { 231 | "allow_bulk_edit": 0, 232 | "allow_on_submit": 0, 233 | "bold": 0, 234 | "collapsible": 0, 235 | "columns": 0, 236 | "fieldname": "to_date", 237 | "fieldtype": "Date", 238 | "hidden": 0, 239 | "ignore_user_permissions": 0, 240 | "ignore_xss_filter": 0, 241 | "in_filter": 0, 242 | "in_global_search": 0, 243 | "in_list_view": 0, 244 | "in_standard_filter": 0, 245 | "label": "To Date", 246 | "length": 0, 247 | "no_copy": 0, 248 | "permlevel": 0, 249 | "precision": "", 250 | "print_hide": 0, 251 | "print_hide_if_no_value": 0, 252 | "read_only": 0, 253 | "remember_last_selected_value": 0, 254 | "report_hide": 0, 255 | "reqd": 0, 256 | "search_index": 0, 257 | "set_only_once": 0, 258 | "unique": 0 259 | }, 260 | { 261 | "allow_bulk_edit": 0, 262 | "allow_on_submit": 0, 263 | "bold": 0, 264 | "collapsible": 0, 265 | "columns": 0, 266 | "fieldname": "project", 267 | "fieldtype": "Link", 268 | "hidden": 0, 269 | "ignore_user_permissions": 0, 270 | "ignore_xss_filter": 0, 271 | "in_filter": 0, 272 | "in_global_search": 0, 273 | "in_list_view": 0, 274 | "in_standard_filter": 0, 275 | "label": "Project", 276 | "length": 0, 277 | "no_copy": 0, 278 | "options": "Project", 279 | "permlevel": 0, 280 | "precision": "", 281 | "print_hide": 0, 282 | "print_hide_if_no_value": 0, 283 | "read_only": 0, 284 | "remember_last_selected_value": 0, 285 | "report_hide": 0, 286 | "reqd": 0, 287 | "search_index": 0, 288 | "set_only_once": 0, 289 | "unique": 0 290 | }, 291 | { 292 | "allow_bulk_edit": 0, 293 | "allow_on_submit": 0, 294 | "bold": 0, 295 | "collapsible": 0, 296 | "columns": 0, 297 | "depends_on": "eval: doc.get_items_from == \"Sales Order\"", 298 | "fieldname": "section_break_9", 299 | "fieldtype": "Section Break", 300 | "hidden": 0, 301 | "ignore_user_permissions": 0, 302 | "ignore_xss_filter": 0, 303 | "in_filter": 0, 304 | "in_global_search": 0, 305 | "in_list_view": 0, 306 | "in_standard_filter": 0, 307 | "label": "", 308 | "length": 0, 309 | "no_copy": 0, 310 | "permlevel": 0, 311 | "precision": "", 312 | "print_hide": 0, 313 | "print_hide_if_no_value": 0, 314 | "read_only": 0, 315 | "remember_last_selected_value": 0, 316 | "report_hide": 0, 317 | "reqd": 0, 318 | "search_index": 0, 319 | "set_only_once": 0, 320 | "unique": 0 321 | }, 322 | { 323 | "allow_bulk_edit": 0, 324 | "allow_on_submit": 0, 325 | "bold": 0, 326 | "collapsible": 0, 327 | "columns": 0, 328 | "description": "Pull sales orders (pending to deliver) based on the above criteria", 329 | "fieldname": "get_sales_orders", 330 | "fieldtype": "Button", 331 | "hidden": 0, 332 | "ignore_user_permissions": 0, 333 | "ignore_xss_filter": 0, 334 | "in_filter": 0, 335 | "in_global_search": 0, 336 | "in_list_view": 0, 337 | "in_standard_filter": 0, 338 | "label": "Get Sales Orders", 339 | "length": 0, 340 | "no_copy": 0, 341 | "permlevel": 0, 342 | "precision": "", 343 | "print_hide": 0, 344 | "print_hide_if_no_value": 0, 345 | "read_only": 0, 346 | "remember_last_selected_value": 0, 347 | "report_hide": 0, 348 | "reqd": 0, 349 | "search_index": 0, 350 | "set_only_once": 0, 351 | "unique": 0 352 | }, 353 | { 354 | "allow_bulk_edit": 0, 355 | "allow_on_submit": 0, 356 | "bold": 0, 357 | "collapsible": 0, 358 | "columns": 0, 359 | "fieldname": "sales_orders", 360 | "fieldtype": "Table", 361 | "hidden": 0, 362 | "ignore_user_permissions": 0, 363 | "ignore_xss_filter": 0, 364 | "in_filter": 0, 365 | "in_global_search": 0, 366 | "in_list_view": 0, 367 | "in_standard_filter": 0, 368 | "label": "Sales Orders", 369 | "length": 0, 370 | "no_copy": 0, 371 | "options": "Simplified Production Sales Orders", 372 | "permlevel": 0, 373 | "precision": "", 374 | "print_hide": 0, 375 | "print_hide_if_no_value": 0, 376 | "read_only": 0, 377 | "remember_last_selected_value": 0, 378 | "report_hide": 0, 379 | "reqd": 0, 380 | "search_index": 0, 381 | "set_only_once": 0, 382 | "unique": 0 383 | }, 384 | { 385 | "allow_bulk_edit": 0, 386 | "allow_on_submit": 0, 387 | "bold": 0, 388 | "collapsible": 0, 389 | "columns": 0, 390 | "depends_on": "eval: doc.get_items_from == \"Material Request\"", 391 | "fieldname": "section_break_13", 392 | "fieldtype": "Section Break", 393 | "hidden": 0, 394 | "ignore_user_permissions": 0, 395 | "ignore_xss_filter": 0, 396 | "in_filter": 0, 397 | "in_global_search": 0, 398 | "in_list_view": 0, 399 | "in_standard_filter": 0, 400 | "length": 0, 401 | "no_copy": 0, 402 | "permlevel": 0, 403 | "precision": "", 404 | "print_hide": 0, 405 | "print_hide_if_no_value": 0, 406 | "read_only": 0, 407 | "remember_last_selected_value": 0, 408 | "report_hide": 0, 409 | "reqd": 0, 410 | "search_index": 0, 411 | "set_only_once": 0, 412 | "unique": 0 413 | }, 414 | { 415 | "allow_bulk_edit": 0, 416 | "allow_on_submit": 0, 417 | "bold": 0, 418 | "collapsible": 0, 419 | "columns": 0, 420 | "fieldname": "get_material_request", 421 | "fieldtype": "Button", 422 | "hidden": 0, 423 | "ignore_user_permissions": 0, 424 | "ignore_xss_filter": 0, 425 | "in_filter": 0, 426 | "in_global_search": 0, 427 | "in_list_view": 0, 428 | "in_standard_filter": 0, 429 | "label": "Get Material Request", 430 | "length": 0, 431 | "no_copy": 0, 432 | "permlevel": 0, 433 | "precision": "", 434 | "print_hide": 0, 435 | "print_hide_if_no_value": 0, 436 | "read_only": 0, 437 | "remember_last_selected_value": 0, 438 | "report_hide": 0, 439 | "reqd": 0, 440 | "search_index": 0, 441 | "set_only_once": 0, 442 | "unique": 0 443 | }, 444 | { 445 | "allow_bulk_edit": 0, 446 | "allow_on_submit": 0, 447 | "bold": 0, 448 | "collapsible": 0, 449 | "columns": 0, 450 | "fieldname": "material_requests", 451 | "fieldtype": "Table", 452 | "hidden": 0, 453 | "ignore_user_permissions": 0, 454 | "ignore_xss_filter": 0, 455 | "in_filter": 0, 456 | "in_global_search": 0, 457 | "in_list_view": 0, 458 | "in_standard_filter": 0, 459 | "label": "Material Requests", 460 | "length": 0, 461 | "no_copy": 0, 462 | "options": "Simplified Production Material Request", 463 | "permlevel": 0, 464 | "precision": "", 465 | "print_hide": 0, 466 | "print_hide_if_no_value": 0, 467 | "read_only": 0, 468 | "remember_last_selected_value": 0, 469 | "report_hide": 0, 470 | "reqd": 0, 471 | "search_index": 0, 472 | "set_only_once": 0, 473 | "unique": 0 474 | }, 475 | { 476 | "allow_bulk_edit": 0, 477 | "allow_on_submit": 0, 478 | "bold": 0, 479 | "collapsible": 0, 480 | "columns": 0, 481 | "fieldname": "select_items", 482 | "fieldtype": "Section Break", 483 | "hidden": 0, 484 | "ignore_user_permissions": 0, 485 | "ignore_xss_filter": 0, 486 | "in_filter": 0, 487 | "in_global_search": 0, 488 | "in_list_view": 0, 489 | "in_standard_filter": 0, 490 | "label": "Select Items", 491 | "length": 0, 492 | "no_copy": 0, 493 | "permlevel": 0, 494 | "precision": "", 495 | "print_hide": 0, 496 | "print_hide_if_no_value": 0, 497 | "read_only": 0, 498 | "remember_last_selected_value": 0, 499 | "report_hide": 0, 500 | "reqd": 0, 501 | "search_index": 0, 502 | "set_only_once": 0, 503 | "unique": 0 504 | }, 505 | { 506 | "allow_bulk_edit": 0, 507 | "allow_on_submit": 0, 508 | "bold": 0, 509 | "collapsible": 0, 510 | "columns": 0, 511 | "fieldname": "get_items", 512 | "fieldtype": "Button", 513 | "hidden": 0, 514 | "ignore_user_permissions": 0, 515 | "ignore_xss_filter": 0, 516 | "in_filter": 0, 517 | "in_global_search": 0, 518 | "in_list_view": 0, 519 | "in_standard_filter": 0, 520 | "label": "Get Items", 521 | "length": 0, 522 | "no_copy": 0, 523 | "permlevel": 0, 524 | "precision": "", 525 | "print_hide": 0, 526 | "print_hide_if_no_value": 0, 527 | "read_only": 0, 528 | "remember_last_selected_value": 0, 529 | "report_hide": 0, 530 | "reqd": 0, 531 | "search_index": 0, 532 | "set_only_once": 0, 533 | "unique": 0 534 | }, 535 | { 536 | "allow_bulk_edit": 0, 537 | "allow_on_submit": 0, 538 | "bold": 0, 539 | "collapsible": 0, 540 | "columns": 0, 541 | "fieldname": "items", 542 | "fieldtype": "Table", 543 | "hidden": 0, 544 | "ignore_user_permissions": 0, 545 | "ignore_xss_filter": 0, 546 | "in_filter": 0, 547 | "in_global_search": 0, 548 | "in_list_view": 0, 549 | "in_standard_filter": 0, 550 | "label": "Items", 551 | "length": 0, 552 | "no_copy": 0, 553 | "options": "Simplified Production Items", 554 | "permlevel": 0, 555 | "precision": "", 556 | "print_hide": 0, 557 | "print_hide_if_no_value": 0, 558 | "read_only": 0, 559 | "remember_last_selected_value": 0, 560 | "report_hide": 0, 561 | "reqd": 0, 562 | "search_index": 0, 563 | "set_only_once": 0, 564 | "unique": 0 565 | }, 566 | { 567 | "allow_bulk_edit": 0, 568 | "allow_on_submit": 0, 569 | "bold": 0, 570 | "collapsible": 0, 571 | "columns": 0, 572 | "fieldname": "section_break_19", 573 | "fieldtype": "Section Break", 574 | "hidden": 0, 575 | "ignore_user_permissions": 0, 576 | "ignore_xss_filter": 0, 577 | "in_filter": 0, 578 | "in_global_search": 0, 579 | "in_list_view": 0, 580 | "in_standard_filter": 0, 581 | "length": 0, 582 | "no_copy": 0, 583 | "permlevel": 0, 584 | "precision": "", 585 | "print_hide": 0, 586 | "print_hide_if_no_value": 0, 587 | "read_only": 0, 588 | "remember_last_selected_value": 0, 589 | "report_hide": 0, 590 | "reqd": 0, 591 | "search_index": 0, 592 | "set_only_once": 0, 593 | "unique": 0 594 | }, 595 | { 596 | "allow_bulk_edit": 0, 597 | "allow_on_submit": 0, 598 | "bold": 0, 599 | "collapsible": 0, 600 | "columns": 0, 601 | "fieldname": "manufacture_items", 602 | "fieldtype": "Button", 603 | "hidden": 0, 604 | "ignore_user_permissions": 0, 605 | "ignore_xss_filter": 0, 606 | "in_filter": 0, 607 | "in_global_search": 0, 608 | "in_list_view": 0, 609 | "in_standard_filter": 0, 610 | "label": "Manufacture Items", 611 | "length": 0, 612 | "no_copy": 0, 613 | "permlevel": 0, 614 | "precision": "", 615 | "print_hide": 0, 616 | "print_hide_if_no_value": 0, 617 | "read_only": 0, 618 | "remember_last_selected_value": 0, 619 | "report_hide": 0, 620 | "reqd": 0, 621 | "search_index": 0, 622 | "set_only_once": 0, 623 | "unique": 0 624 | } 625 | ], 626 | "has_web_view": 0, 627 | "hide_heading": 0, 628 | "hide_toolbar": 1, 629 | "icon": "icon-calendar", 630 | "idx": 0, 631 | "image_view": 0, 632 | "in_create": 1, 633 | "is_submittable": 0, 634 | "issingle": 1, 635 | "istable": 0, 636 | "max_attachments": 0, 637 | "modified": "2017-10-13 18:26:14.122044", 638 | "modified_by": "Administrator", 639 | "module": "Simplified Production Process", 640 | "name": "Simplified Production Tool", 641 | "name_case": "", 642 | "owner": "Administrator", 643 | "permissions": [ 644 | { 645 | "amend": 0, 646 | "apply_user_permissions": 0, 647 | "cancel": 0, 648 | "create": 1, 649 | "delete": 1, 650 | "email": 1, 651 | "export": 0, 652 | "if_owner": 0, 653 | "import": 0, 654 | "permlevel": 0, 655 | "print": 1, 656 | "read": 1, 657 | "report": 0, 658 | "role": "System Manager", 659 | "set_user_permissions": 0, 660 | "share": 1, 661 | "submit": 0, 662 | "write": 1 663 | }, 664 | { 665 | "amend": 0, 666 | "apply_user_permissions": 0, 667 | "cancel": 0, 668 | "create": 1, 669 | "delete": 0, 670 | "email": 0, 671 | "export": 0, 672 | "if_owner": 0, 673 | "import": 0, 674 | "permlevel": 0, 675 | "print": 0, 676 | "read": 1, 677 | "report": 0, 678 | "role": "Manufacturing User", 679 | "set_user_permissions": 0, 680 | "share": 0, 681 | "submit": 0, 682 | "write": 1 683 | } 684 | ], 685 | "quick_entry": 0, 686 | "read_only": 1, 687 | "read_only_onload": 0, 688 | "show_name_in_global_search": 0, 689 | "sort_field": "", 690 | "sort_order": "DESC", 691 | "track_changes": 0, 692 | "track_seen": 0 693 | } -------------------------------------------------------------------------------- /spp/simplified_production_process/doctype/simplified_production_tool/simplified_production_tool.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (c) 2017, o10c and contributors 3 | # For license information, please see license.txt 4 | 5 | 6 | from __future__ import unicode_literals 7 | import frappe 8 | from frappe.utils import cstr, flt, cint, nowdate, nowtime, add_days, comma_and 9 | 10 | from frappe import msgprint, _ 11 | 12 | from frappe.model.document import Document 13 | from erpnext.manufacturing.doctype.bom.bom import validate_bom_no 14 | from erpnext.manufacturing.doctype.production_order.production_order import get_item_details 15 | from erpnext.stock.stock_ledger import get_previous_sle, NegativeStockError 16 | 17 | class SimplifiedProductionTool(Document): 18 | 19 | def clear_table(self, table_name): 20 | self.set(table_name, []) 21 | 22 | def validate_company(self): 23 | if not self.company: 24 | frappe.throw(_("Please enter Company")) 25 | 26 | def get_open_sales_orders(self): 27 | """ Pull sales orders which are pending to deliver based on criteria selected""" 28 | so_filter = item_filter = "" 29 | if self.from_date: 30 | so_filter += " and so.transaction_date >= %(from_date)s" 31 | if self.to_date: 32 | so_filter += " and so.transaction_date <= %(to_date)s" 33 | if self.customer: 34 | so_filter += " and so.customer = %(customer)s" 35 | if self.project: 36 | so_filter += " and so.project = %(project)s" 37 | 38 | if self.fg_item: 39 | item_filter += " and so_item.item_code = %(item)s" 40 | 41 | open_so = frappe.db.sql(""" 42 | select distinct so.name, so.transaction_date, so.customer, so.base_grand_total 43 | from `tabSales Order` so, `tabSales Order Item` so_item 44 | where so_item.parent = so.name 45 | and so.docstatus = 1 and so.status not in ("Stopped", "Closed") 46 | and so.company = %(company)s 47 | and so_item.qty > so_item.delivered_qty {0} {1} 48 | and (exists (select name from `tabBOM` bom where bom.item=so_item.item_code 49 | and bom.is_active = 1) 50 | or exists (select name from `tabPacked Item` pi 51 | where pi.parent = so.name and pi.parent_item = so_item.item_code 52 | and exists (select name from `tabBOM` bom where bom.item=pi.item_code 53 | and bom.is_active = 1))) 54 | """.format(so_filter, item_filter), { 55 | "from_date": self.from_date, 56 | "to_date": self.to_date, 57 | "customer": self.customer, 58 | "project": self.project, 59 | "item": self.fg_item, 60 | "company": self.company 61 | }, as_dict=1) 62 | 63 | self.add_so_in_table(open_so) 64 | 65 | def add_so_in_table(self, open_so): 66 | """ Add sales orders in the table""" 67 | #self.clear_table("sales_orders") 68 | #so_list = [] 69 | so_list = [d.sales_order for d in self.get('sales_orders') if d.sales_order] 70 | for r in open_so: 71 | if cstr(r['name']) not in so_list: 72 | pp_so = self.append('sales_orders', {}) 73 | pp_so.sales_order = r['name'] 74 | pp_so.sales_order_date = cstr(r['transaction_date']) 75 | pp_so.customer = cstr(r['customer']) 76 | pp_so.grand_total = flt(r['base_grand_total']) 77 | 78 | 79 | def get_pending_material_requests(self): 80 | """ Pull Material Requests that are pending based on criteria selected""" 81 | mr_filter = item_filter = "" 82 | if self.from_date: 83 | mr_filter += " and mr.transaction_date >= %(from_date)s" 84 | if self.to_date: 85 | mr_filter += " and mr.transaction_date <= %(to_date)s" 86 | if self.warehouse: 87 | mr_filter += " and mr_item.warehouse = %(warehouse)s" 88 | 89 | if self.fg_item: 90 | item_filter += " and mr_item.item_code = %(item)s" 91 | 92 | pending_mr = frappe.db.sql(""" 93 | select distinct mr.name, mr.transaction_date 94 | from `tabMaterial Request` mr, `tabMaterial Request Item` mr_item 95 | where mr_item.parent = mr.name 96 | and mr.material_request_type = "Manufacture" 97 | and mr.docstatus = 1 98 | and mr_item.qty > ifnull(mr_item.ordered_qty,0) {0} {1} 99 | and (exists (select name from `tabBOM` bom where bom.item=mr_item.item_code 100 | and bom.is_active = 1)) 101 | """.format(mr_filter, item_filter), { 102 | "from_date": self.from_date, 103 | "to_date": self.to_date, 104 | "warehouse": self.warehouse, 105 | "item": self.fg_item 106 | }, as_dict=1) 107 | 108 | self.add_mr_in_table(pending_mr) 109 | 110 | def add_mr_in_table(self, pending_mr): 111 | """ Add Material Requests in the table""" 112 | self.clear_table("material_requests") 113 | 114 | mr_list = [] 115 | for r in pending_mr: 116 | if cstr(r['name']) not in mr_list: 117 | mr = self.append('material_requests', {}) 118 | mr.material_request = r['name'] 119 | mr.material_request_date = cstr(r['transaction_date']) 120 | 121 | def get_items(self): 122 | if self.get_items_from == "Sales Order": 123 | self.get_so_items() 124 | elif self.get_items_from == "Material Request": 125 | self.get_mr_items() 126 | 127 | def get_so_items(self): 128 | so_list = [d.sales_order for d in self.get('sales_orders') if d.sales_order] 129 | if not so_list: 130 | msgprint(_("Please enter Sales Orders in the above table")) 131 | return [] 132 | 133 | item_condition = "" 134 | if self.fg_item: 135 | item_condition = ' and so_item.item_code = "{0}"'.format(frappe.db.escape(self.fg_item)) 136 | 137 | items = frappe.db.sql("""select distinct parent, item_code, warehouse, 138 | (qty - delivered_qty)*conversion_factor as pending_qty 139 | from `tabSales Order Item` so_item 140 | where parent in (%s) and docstatus = 1 and qty > delivered_qty 141 | and exists (select name from `tabBOM` bom where bom.item=so_item.item_code 142 | and bom.is_active = 1) %s""" % \ 143 | (", ".join(["%s"] * len(so_list)), item_condition), tuple(so_list), as_dict=1) 144 | 145 | if self.fg_item: 146 | item_condition = ' and pi.item_code = "{0}"'.format(frappe.db.escape(self.fg_item)) 147 | 148 | packed_items = frappe.db.sql("""select distinct pi.parent, pi.item_code, pi.warehouse as warehouse, 149 | (((so_item.qty - so_item.delivered_qty) * pi.qty) / so_item.qty) 150 | as pending_qty 151 | from `tabSales Order Item` so_item, `tabPacked Item` pi 152 | where so_item.parent = pi.parent and so_item.docstatus = 1 153 | and pi.parent_item = so_item.item_code 154 | and so_item.parent in (%s) and so_item.qty > so_item.delivered_qty 155 | and exists (select name from `tabBOM` bom where bom.item=pi.item_code 156 | and bom.is_active = 1) %s""" % \ 157 | (", ".join(["%s"] * len(so_list)), item_condition), tuple(so_list), as_dict=1) 158 | 159 | self.add_items(items + packed_items) 160 | 161 | def get_mr_items(self): 162 | mr_list = [d.material_request for d in self.get('material_requests') if d.material_request] 163 | if not mr_list: 164 | msgprint(_("Please enter Material Requests in the above table")) 165 | return [] 166 | 167 | item_condition = "" 168 | if self.fg_item: 169 | item_condition = ' and mr_item.item_code = "' + frappe.db.escape(self.fg_item, percent=False) + '"' 170 | 171 | items = frappe.db.sql("""select distinct parent, name, item_code, warehouse, 172 | (qty - ordered_qty) as pending_qty 173 | from `tabMaterial Request Item` mr_item 174 | where parent in (%s) and docstatus = 1 and qty > ordered_qty 175 | and exists (select name from `tabBOM` bom where bom.item=mr_item.item_code 176 | and bom.is_active = 1) %s""" % \ 177 | (", ".join(["%s"] * len(mr_list)), item_condition), tuple(mr_list), as_dict=1) 178 | 179 | self.add_items(items) 180 | 181 | 182 | def add_items(self, items): 183 | self.clear_table("items") 184 | for p in items: 185 | item_details = get_item_details(p['item_code']) 186 | pi = self.append('items', {}) 187 | pi.warehouse = p['warehouse'] 188 | pi.item_code = p['item_code'] 189 | pi.description = item_details and item_details.description or '' 190 | pi.stock_uom = item_details and item_details.stock_uom or '' 191 | pi.bom_no = item_details and item_details.bom_no or '' 192 | pi.planned_qty = flt(p['pending_qty']) 193 | pi.pending_qty = flt(p['pending_qty']) 194 | 195 | if self.get_items_from == "Sales Order": 196 | pi.sales_order = p['parent'] 197 | elif self.get_items_from == "Material Request": 198 | pi.material_request = p['parent'] 199 | pi.material_request_item = p['name'] 200 | 201 | def validate_data(self): 202 | self.validate_company() 203 | for d in self.get('items'): 204 | if not d.bom_no: 205 | frappe.throw(_("Please select BOM for Item in Row {0}".format(d.idx))) 206 | else: 207 | validate_bom_no(d.item_code, d.bom_no) 208 | 209 | if not flt(d.planned_qty): 210 | frappe.throw(_("Please enter Planned Qty for Item {0} at row {1}").format(d.item_code, d.idx)) 211 | 212 | 213 | 214 | def raise_stock_entries(self): 215 | """It will raise a stock entries of purpose manufacture for all distinct FG items""" 216 | 217 | self.validate_data() 218 | 219 | from erpnext.utilities.transaction_base import validate_uom_is_integer 220 | validate_uom_is_integer(self, "stock_uom", "planned_qty") 221 | 222 | #frappe.flags.mute_messages = False 223 | 224 | 225 | items = self.get_manufacture_items() 226 | 227 | allow_negative_stock = cint(frappe.db.get_value("Stock Settings", None, "allow_negative_stock")) 228 | 229 | se_list = [] 230 | 231 | for key in items: 232 | i = items[key] 233 | se = self.make_stock_entry(items[key]) 234 | if se: 235 | 236 | #check quantities in stock for each BOM items before insert and submit 237 | for d in se.items: 238 | previous_sle = get_previous_sle({ 239 | "item_code": d.item_code, 240 | "warehouse": d.s_warehouse or d.t_warehouse, 241 | "posting_date": nowdate(), 242 | "posting_time": nowtime() 243 | }) 244 | 245 | # get actual stock at source warehouse 246 | d.actual_qty = previous_sle.get("qty_after_transaction") or 0 247 | 248 | # validate qty before submit 249 | if d.s_warehouse and not allow_negative_stock and d.actual_qty < d.transfer_qty: 250 | frappe.throw(_("For manufacturing item {0} you need {3} x {2} in warehouse {1}").format(i['manufacture_item'], 251 | frappe.bold(d.s_warehouse), frappe.bold(d.item_code), frappe.bold(d.transfer_qty)) 252 | + '