Skip to content

Commit

Permalink
feat: Alternative workstation in job card and operation (#56)
Browse files Browse the repository at this point in the history
* feat: New field and link filters to select alternative workstation

* fix: add alternativ workstation in fixture

* fix:change alternative workstation in fixture

* change to error key function

* fix: set validation on workstation if not operation

* changes field name in testcase

* fix: change a class base function to saperate function

* added a searchfield in query

* added a searchfield in query

* added a searchfield in query

* added a searchfield in query

* added a searchfield in query

* feat: validation to not allow default workstation in alternative

* added comment on function
  • Loading branch information
viralkansodiya authored Mar 1, 2024
1 parent d1e126b commit 0788d3c
Show file tree
Hide file tree
Showing 11 changed files with 269 additions and 2 deletions.
7 changes: 7 additions & 0 deletions inventory_tools/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
"Purchase Order": "public/js/purchase_order_custom.js",
"Purchase Invoice": "public/js/purchase_invoice_custom.js",
"Stock Entry": "public/js/stock_entry_custom.js",
"Job Card": "public/js/job_card_custom.js",
"Operation": "public/js/operation_custom.js",
}
# doctype_list_js = {"doctype" : "public/js/doctype_list.js"}
# doctype_tree_js = {"doctype" : "public/js/doctype_tree.js"}
Expand Down Expand Up @@ -139,6 +141,11 @@
"Warehouse": {
"validate": ["inventory_tools.inventory_tools.overrides.warehouse.update_warehouse_path"]
},
"Operation": {
"validate": [
"inventory_tools.inventory_tools.overrides.operation.validate_alternative_workstation"
]
},
}

# Scheduled Tasks
Expand Down
70 changes: 70 additions & 0 deletions inventory_tools/inventory_tools/custom/operation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"custom_fields": [
{
"_assign": null,
"_comments": null,
"_liked_by": null,
"_user_tags": null,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
"creation": "2024-02-16 05:04:42.422068",
"default": null,
"depends_on": null,
"description": null,
"docstatus": 0,
"dt": "Operation",
"fetch_from": null,
"fetch_if_empty": 0,
"fieldname": "alternative_workstations",
"fieldtype": "Table MultiSelect",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
"hide_seconds": 0,
"idx": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
"insert_after": "workstation",
"is_system_generated": 0,
"is_virtual": 0,
"label": "Alternative Workstations",
"length": 0,
"mandatory_depends_on": null,
"modified": "2024-02-16 05:04:42.422068",
"modified_by": "Administrator",
"module": "Inventory Tools",
"name": "Operation-alternative_workstations",
"no_copy": 0,
"non_negative": 0,
"options": "Alternative Workstations",
"owner": "Administrator",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": null,
"read_only": 0,
"read_only_depends_on": null,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"sort_options": 0,
"translatable": 0,
"unique": 0,
"width": null
}
],
"custom_perms": [],
"doctype": "Operation",
"links": [],
"property_setters": [],
"sync_on_migrate": 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2024-02-01 04:03:58.033322",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"workstation"
],
"fields": [
{
"fieldname": "workstation",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Workstation",
"options": "Workstation"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2024-02-01 07:04:30.059469",
"modified_by": "Administrator",
"module": "Inventory Tools",
"name": "Alternative Workstations",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2024, AgriTheory and contributors
# For license information, please see license.txt

# import frappe
from frappe.model.document import Document


class AlternativeWorkstations(Document):
pass
8 changes: 8 additions & 0 deletions inventory_tools/inventory_tools/overrides/operation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import frappe


def validate_alternative_workstation(self, method):
if self.workstation:
for row in self.alternative_workstations:
if row.workstation == self.workstation:
frappe.throw("Default Workstation should not be selected as alternative workstation")
62 changes: 62 additions & 0 deletions inventory_tools/inventory_tools/overrides/workstation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import json

import frappe

"""
This function fetch workstation of the document operation.
In Operation you can select multiple workstations in Alternative Workstation field.
In the Work Order, Operation table, and Jobcard, there exists an operation field.
When selecting an operation, this function is responsible for fetching the workstations
both from the Alternative Workstation and the default workstation.
Example : Operation : Cool Pie Op
Default Workstation: Cooling Racks Station
Alternative Workstation:
`````````````````````````````````````````````````````
: Cooling Station , Refrigerator Station , :
: :
: :
``````````````````````````````````````````````````````
In work order and job card when you select operation Cool Pie Op then you find below workstation in workstation field
: Cooling Station :
: Refrigerator Station :
: Cooling Racks Station :
"""


@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_alternative_workstations(doctype, txt, searchfield, start, page_len, filters):
operation = filters.get("operation")
if not operation:
frappe.throw("Please select a Operation first.")

if txt:
searchfields = frappe.get_meta(doctype).get_search_fields()
searchfields = " or ".join(["ws." + field + f" LIKE '%{txt}%'" for field in searchfields])

conditions = ""
if txt and searchfields:
conditions = f"and ({searchfields})"

workstation = frappe.db.sql(
"""
Select aw.workstation, ws.workstation_type, ws.description
From `tabOperation` as op
Left Join `tabAlternative Workstations` as aw ON aw.parent = op.name
Left Join `tabWorkstation` as ws ON ws.name = aw.workstation
Where op.name = '{operation}' {conditions}
""".format(
conditions=conditions, operation=operation
)
)

default_workstation = frappe.db.get_value("Operation", operation, "workstation")
flag = True
for row in workstation:
if row[0] == None:
workstation = ((default_workstation,),)
flag = False
if flag:
workstation += ((default_workstation,),)
return workstation
21 changes: 21 additions & 0 deletions inventory_tools/public/js/job_card_custom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
frappe.ui.form.on('Job Card', {
refresh: frm => {
if (frm.doc.operation) {
set_workstation_query(frm)
}
},
operation: frm => {
set_workstation_query(frm)
},
})

function set_workstation_query(frm) {
frm.set_query('workstation', doc => {
return {
query: 'inventory_tools.inventory_tools.overrides.workstation.get_alternative_workstations',
filters: {
operation: doc.operation,
},
}
})
}
18 changes: 18 additions & 0 deletions inventory_tools/public/js/operation_custom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
frappe.ui.form.on('Operation', {
refresh: frm => {
get_filter_workstations(frm)
},
workstation: frm => {
get_filter_workstations(frm)
},
})

function get_filter_workstations(frm) {
cur_frm.fields_dict.alternative_workstations.get_query = function (doc) {
return {
filters: {
workstation_name: ['!=', frm.doc.workstation],
},
}
}
}
19 changes: 19 additions & 0 deletions inventory_tools/public/js/work_order_custom.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,28 @@ frappe.ui.form.on('Work Order', {
},
refresh: frm => {
manage_subcontracting_buttons(frm)
get_workstations(frm)
},
operation: frm => {
get_workstations(frm)
},
})

function get_workstations(frm) {
frm.set_query('workstation', 'operations', (doc, cdt, cdn) => {
var d = locals[cdt][cdn]
if (!d.operation) {
frappe.throw('Please select a Operation first.')
}
return {
query: 'inventory_tools.inventory_tools.overrides.workstation.get_alternative_workstations',
filters: {
operation: d.operation,
},
}
})
}

function manage_subcontracting_buttons(frm) {
if (frm.doc.company) {
frappe.db.get_value('BOM', { name: frm.doc.bom_no }, 'is_subcontracted').then(r => {
Expand Down
17 changes: 15 additions & 2 deletions inventory_tools/tests/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
- Remove butter and ice water from refrigerator
- Place ingredients at workstation
- Measure amounts for batch size into mixing bowl""",
["Food Prep Table 1"],
),
(
"Gather Pie Filling Ingredients",
Expand All @@ -94,6 +95,7 @@
- Remove sugar and cornstarch
- Get water from sink
- Measure ingredients and place in pot, excluding 1/4 of fruit and butter""",
["Food Prep Table 2"],
),
(
"Assemble Pie Op",
Expand All @@ -104,6 +106,7 @@
- Fill bottom crust with filling
- Create decorative cut out for top crust
- Layer top crust over bottom crust / filling and create a crimped seal""",
["Food Prep Table 1", "Assemble Pie Station"],
),
(
"Cook Pie Filling Operation",
Expand All @@ -121,6 +124,7 @@
- Pulse for 30 seconds
- Divide into equal-sized portions, one portion for each pie crust being made
- Put in refrigerator""",
["Mix Pie Crust Station", "Mix Pie Filling Station"],
),
("Box Pie Op", "Packaging Station", "5", "- Place pie into box for sale"),
(
Expand All @@ -131,22 +135,31 @@
- Separate each portion into two (one for bottom crust, one for top)
- Flour board and roll out each portion into a circle
- Place bottom crust into pie tin, then layer a piece of parchment paper, followed by the top crust""",
["Food Prep Table 1", "Roll Pie Crust Station"],
),
("Divide Dough Op", "Food Prep Table 2", "1", "Divide Dough Op"),
("Divide Dough Op", "Food Prep Table 2", "1", "Divide Dough Op", ["Food Prep Table 1"]),
(
"Bake Op",
"Oven Station",
"1",
"""- Place assembled pies into oven
- Bake at 375F for 50 minutes
- Remove from oven""",
["Baking Station"],
),
(
"Chill Pie Crust Op",
"Refrigerator Station",
"1",
"- Chill pie crust for at least 30 minutes",
["Cooling Station", "Cooling Racks Station"],
),
("Chill Pie Crust Op", "Refrigerator Station", "1", "- Chill pie crust for at least 30 minutes"),
(
"Cool Pie Op",
"Cooling Racks Station",
"1",
"Cool baked pies for at least 30 minutes before boxing",
["Cooling Station", "Refrigerator Station"],
),
]

Expand Down
8 changes: 8 additions & 0 deletions inventory_tools/tests/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,14 @@ def create_operations():
oper.workstation = op[1]
oper.batch_size = op[2]
oper.description = op[3]
if len(op) == 5:
for aw in op[4]:
oper.append(
"alternative_workstations",
{
"workstation": aw,
},
)
oper.save()


Expand Down

0 comments on commit 0788d3c

Please sign in to comment.