Skip to content

Commit

Permalink
Fix multi-company PO aggregation workflow frontend (#82)
Browse files Browse the repository at this point in the history
* wip: fix multi-company PO aggregation workflow frontend

* wip: purchase receipt generation

* test: test downstream effects of partial PO aggregation

* ci: track overrides for purchase cycle (PO/PI/PR) (#89)

* ci: track overrides for stock and manufacturing cycles (#90)

Co-authored-by: Rohan Bansal <[email protected]>

* Test alternative workstation (#80)

* test: add test for alternative workstation

* feat: make alternative workstations configurable

* fix: uncomment js code for testing

* feat: search alternative workstation names

* refactor: pop filters that cause error for Workstation

* chore: update override commit hash

---------

Co-authored-by: Heather Kusmierz <[email protected]>

* fix: rm unused variable

* fix: frappe.boot.inventory_tools_settings

* chore: track overrides

---------

Co-authored-by: Heather Kusmierz <[email protected]>
Co-authored-by: Rohan <[email protected]>
Co-authored-by: Rohan Bansal <[email protected]>
Co-authored-by: fproldan <[email protected]>
  • Loading branch information
5 people authored Aug 7, 2024
1 parent d703aec commit 3515504
Show file tree
Hide file tree
Showing 19 changed files with 438 additions and 226 deletions.
14 changes: 7 additions & 7 deletions inventory_tools/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@

# include js in doctype views
doctype_js = {
"Item": "public/js/item.js",
"Job Card": "public/js/job_card_custom.js",
"Purchase Invoice": "public/js/purchase_invoice_custom.js",
"Purchase Order": "public/js/purchase_order_custom.js",
"Operation": "public/js/operation_custom.js",
"Stock Entry": "public/js/stock_entry_custom.js",
"Work Order": "public/js/work_order_custom.js",
"Item": "public/js/custom/item.js",
"Job Card": "public/js/custom/job_card_custom.js",
"Purchase Invoice": "public/js/custom/purchase_invoice_custom.js",
"Purchase Order": "public/js/custom/purchase_order_custom.js",
"Operation": "public/js/custom/operation_custom.js",
"Stock Entry": "public/js/custom/stock_entry_custom.js",
"Work Order": "public/js/custom/work_order_custom.js",
}
# doctype_list_js = {"doctype" : "public/js/doctype_list.js"}
# doctype_tree_js = {"doctype" : "public/js/doctype_tree.js"}
Expand Down
70 changes: 70 additions & 0 deletions inventory_tools/inventory_tools/custom/purchase_order_item.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-06-04 14:06:25.331707",
"default": null,
"depends_on": null,
"description": null,
"docstatus": 0,
"dt": "Purchase Order Item",
"fetch_from": null,
"fetch_if_empty": 0,
"fieldname": "material_request_company",
"fieldtype": "Link",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
"hide_seconds": 0,
"idx": 60,
"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": "references_section",
"is_system_generated": 0,
"is_virtual": 0,
"label": "Material Request Company",
"length": 0,
"mandatory_depends_on": "",
"modified": "2024-06-04 15:44:22.874371",
"modified_by": "Administrator",
"module": "Inventory Tools",
"name": "Purchase Order Item-material_request_company",
"no_copy": 0,
"non_negative": 0,
"options": "Company",
"owner": "Administrator",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": null,
"read_only": 1,
"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": "Purchase Order Item",
"links": [],
"property_setters": [],
"sync_on_migrate": 1
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
class InventoryToolsPurchaseInvoice(PurchaseInvoice):
def validate_with_previous_doc(self):
"""
HASH: 4668a2d7d825450818e04a1b785deb61d861ed29
HASH: e7432fc60d4b5b82363212ae003cb7d2d4e8f294
REPO: https://github.com/frappe/erpnext/
PATH: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
METHOD: validate_with_previous_doc
Expand Down
99 changes: 66 additions & 33 deletions inventory_tools/inventory_tools/overrides/purchase_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,22 @@ def validate_with_previous_doc(self):
super(PurchaseOrder, self).validate_with_previous_doc(config)

def validate_warehouse(self):
warehouses = list({d.warehouse for d in self.get("items") if getattr(d, "warehouse", None)})

warehouses.extend(
list({d.target_warehouse for d in self.get("items") if getattr(d, "target_warehouse", None)})
)

warehouses.extend(
list({d.from_warehouse for d in self.get("items") if getattr(d, "from_warehouse", None)})
)
warehouses = []
inventory_tools_settings = frappe.get_doc("Inventory Tools Settings", self.company)

for d in self.get("items"):
if (
self.multi_company_purchase_order
and not inventory_tools_settings.aggregated_purchasing_warehouse
):
validate_warehouse_company(d.warehouse, d.material_request_company)
continue
if getattr(d, "warehouse", None):
warehouses.append(d.warehouse)
if getattr(d, "target_warehouse", None):
warehouses.append(d.warehouse)
if getattr(d, "from_warehouse", None):
warehouses.append(d.warehouse)

for w in warehouses:
validate_disabled_warehouse(w)
Expand Down Expand Up @@ -111,46 +118,72 @@ def validate_subcontracting_fg_qty(self):
def make_purchase_invoices(docname: str, rows: Union[list, str]) -> None:
rows = json.loads(rows) if isinstance(rows, str) else rows
doc = frappe.get_doc("Purchase Order", docname)
inventory_tools_settings = frappe.get_doc("Inventory Tools Settings", doc.company)
forwarding = frappe._dict()
for row in doc.items:
if row.name in rows:
if row.company in forwarding:
forwarding[row.company].append(row.name)
else:
forwarding[row.company] = [row.name]
for row_name in rows:
for row in doc.items:
if row_name == row.name:
company = frappe.get_value("Material Request", row.material_request, "company")
if company in forwarding:
forwarding[company].append(row.name)
else:
forwarding[company] = [row.name]

for company, rows in forwarding.items():
for company, _rows in forwarding.items():
pi = make_purchase_invoice(docname)
pi.company = company
pi.credit_to = frappe.get_value("Company", pi.company, "default_payable_account")
filtered_rows = []
for row in pi.items:
if row.po_detail in rows:
continue
else:
pi.items.remove(row)
if row.po_detail in _rows:
if inventory_tools_settings.aggregated_purchasing_warehouse is not None:
row.warehouse = inventory_tools_settings.aggregated_purchasing_warehouse
else:
material_request_item = frappe.get_value(
"Purchase Order Item", row.po_detail, "material_request_item"
)
warehouse, cost_center = frappe.get_value(
"Material Request Item", material_request_item, ["warehouse", "cost_center"]
)
row.warehouse = warehouse
row.cost_center = cost_center
filtered_rows.append(row)
pi.items = filtered_rows
pi.save()


@frappe.whitelist()
def make_purchase_receipts(docname: str, rows: Union[list, str]) -> None:
rows = json.loads(rows) if isinstance(rows, str) else rows
doc = frappe.get_doc("Purchase Order", docname)
inventory_tools_settings = frappe.get_doc("Inventory Tools Settings", doc.company)

forwarding = frappe._dict()
for row in doc.items:
if row.name in rows:
if row.company in forwarding:
forwarding[row.company].append(row.name)
else:
forwarding[row.company] = [row.name]
for row_name in rows:
for row in doc.items:
if row_name == row.name:
company = frappe.get_value("Material Request", row.material_request, "company")
if company in forwarding:
forwarding[company].append(row.name)
else:
forwarding[company] = [row.name]

for company, rows in forwarding.items():
for company, _rows in forwarding.items():
pr = make_purchase_receipt(docname)
pr.company = company
filtered_rows = []
for row in pr.items:
if row.purchase_order_item in rows:
continue
else:
pr.items.remove(row)
if row.purchase_order_item in _rows:
if inventory_tools_settings.aggregated_purchasing_warehouse is not None:
row.warehouse = inventory_tools_settings.aggregated_purchasing_warehouse
else:
warehouse, cost_center = frappe.get_value(
"Material Request Item", row.material_request_item, ["warehouse", "cost_center"]
)
row.warehouse = warehouse
row.cost_center = cost_center
filtered_rows.append(row)
pr.items = filtered_rows
pr.save()


Expand Down Expand Up @@ -225,7 +258,7 @@ def make_sales_invoices(docname: str, rows: Union[list, str]) -> None:
@frappe.whitelist()
def get_item_details(args, doc=None, for_validate=False, overwrite_warehouse=True):
"""
HASH: 4d6a71ab4ba0f008e1a6816ed99e890fae347016
HASH: 53034c332b929a3e40759c9fc9bae82b8365aa57
REPO: https://github.com/frappe/erpnext/
PATH: erpnext/stock/get_item_details.py
METHOD: get_item_details
Expand All @@ -242,7 +275,7 @@ def get_item_details(args, doc=None, for_validate=False, overwrite_warehouse=Tru
@frappe.whitelist()
def validate_item_details(args, item):
"""
HASH: 4d6a71ab4ba0f008e1a6816ed99e890fae347016
HASH: 53034c332b929a3e40759c9fc9bae82b8365aa57
REPO: https://github.com/frappe/erpnext/
PATH: erpnext/stock/get_item_details.py
METHOD: validate_item_details
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import frappe
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import PurchaseReceipt
from erpnext.stock.utils import validate_disabled_warehouse, validate_warehouse_company
from frappe.utils.data import cint


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,8 @@ def create_pos(company, filters, rows):
return
counter = 0
settings = frappe.get_doc("Inventory Tools Settings", company)
requesting_companies = list({row.company for row in rows})
requesting_companies = list({row.company for row in rows if row.company})

if settings.purchase_order_aggregation_company == company:
requesting_companies = [company]
for requesting_company in requesting_companies:
Expand All @@ -325,9 +326,12 @@ def create_pos(company, filters, rows):
po.schedule_date = po.posting_date = getdate()
po.supplier = supplier
po.buying_price_list = filters.price_list
if len(requesting_companies) == 1:
po.multi_company_purchase_order = True
if (
len(requesting_companies) == 1
and requesting_company == settings.purchase_order_aggregation_company
):
po.company = settings.purchase_order_aggregation_company
po.multi_company_purchase_order = True
else:
po.company = requesting_company
for row in rows:
Expand All @@ -349,6 +353,7 @@ def create_pos(company, filters, rows):
"qty": row.get("qty"),
"rate": row.get("supplier_price"),
"uom": row.get("uom"),
"material_request_company": row.get("company"),
"material_request": row.get("material_request"),
"material_request_item": row.get("material_request_item"),
"warehouse": warehouse,
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,21 @@ function show_subcontracting_fields(frm) {
hide_field('subcontracting')
return
}
frappe.db
.get_value('Inventory Tools Settings', { company: frm.doc.company }, 'enable_work_order_subcontracting')
.then(r => {
if (r && r.message && r.message.enable_work_order_subcontracting) {
unhide_field('subcontracting')
hide_field('update_stock')
setTimeout(() => {
frm.remove_custom_button('Purchase Receipt', 'Create')
}, 1000)
} else {
hide_field('subcontracting')
unhide_field('update_stock')
}
toggle_subcontracting_columns(frm)
})
if (
frappe.boot.inventory_tools_settings &&
frappe.boot.inventory_tools_settings[frm.doc.company] &&
frappe.boot.inventory_tools_settings[frm.doc.company].enable_work_order_subcontracting
) {
unhide_field('subcontracting')
hide_field('update_stock')
setTimeout(() => {
frm.remove_custom_button('Purchase Receipt', 'Create')
}, 1000)
} else {
hide_field('subcontracting')
unhide_field('update_stock')
}
toggle_subcontracting_columns(frm)
}

function add_stock_entry_row(frm, row) {
Expand Down Expand Up @@ -188,11 +188,13 @@ function setup_item_queries(frm) {
if (me.frm.doc.is_old_subcontracting_flow) {
filters['is_sub_contracted_item'] = 1
} else {
frappe.db.get_value('Inventory Tools Settings', frm.doc.company, 'enable_work_order_subcontracting').then(r => {
if (!r.message.enable_work_order_subcontracting) {
filters['is_stock_item'] = 0
}
})
if (
frappe.boot.inventory_tools_settings &&
frappe.boot.inventory_tools_settings[frm.doc.company] &&
frappe.boot.inventory_tools_settings[frm.doc.company].enable_work_order_subcontracting
) {
filters['is_stock_item'] = 0
}
}
return {
query: 'erpnext.controllers.queries.item_query',
Expand Down
Loading

0 comments on commit 3515504

Please sign in to comment.