feat: Putaway
This commit is contained in:
parent
29a8994506
commit
c1b0e65f9f
0
erpnext/stock/doctype/putaway_rule/__init__.py
Normal file
0
erpnext/stock/doctype/putaway_rule/__init__.py
Normal file
18
erpnext/stock/doctype/putaway_rule/putaway_rule.js
Normal file
18
erpnext/stock/doctype/putaway_rule/putaway_rule.js
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Putaway Rule', {
|
||||
setup: function(frm) {
|
||||
frm.set_query("warehouse", function() {
|
||||
return {
|
||||
"filters": {
|
||||
"company": frm.doc.company,
|
||||
"is_group": 0
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
// refresh: function(frm) {
|
||||
|
||||
// }
|
||||
});
|
111
erpnext/stock/doctype/putaway_rule/putaway_rule.json
Normal file
111
erpnext/stock/doctype/putaway_rule/putaway_rule.json
Normal file
@ -0,0 +1,111 @@
|
||||
{
|
||||
"actions": [],
|
||||
"autoname": "format:{item_code}-{warehouse}",
|
||||
"creation": "2020-11-09 11:39:46.489501",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"disable",
|
||||
"item_code",
|
||||
"item_name",
|
||||
"warehouse",
|
||||
"col_break_capacity",
|
||||
"company",
|
||||
"capacity",
|
||||
"priority",
|
||||
"stock_uom"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Item",
|
||||
"options": "Item",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "item_code.item_name",
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Item Name",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "warehouse",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Warehouse",
|
||||
"options": "Warehouse",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "col_break_capacity",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "capacity",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Capacity",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "item_code.stock_uom",
|
||||
"fieldname": "stock_uom",
|
||||
"fieldtype": "Link",
|
||||
"label": "Stock UOM",
|
||||
"options": "UOM",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "priority",
|
||||
"fieldtype": "Int",
|
||||
"label": "Priority"
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"in_standard_filter": 1,
|
||||
"label": "Company",
|
||||
"options": "Company",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "eval:!doc.__islocal",
|
||||
"fieldname": "disable",
|
||||
"fieldtype": "Check",
|
||||
"label": "Disable"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2020-11-10 17:06:27.151335",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Putaway Rule",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
93
erpnext/stock/doctype/putaway_rule/putaway_rule.py
Normal file
93
erpnext/stock/doctype/putaway_rule/putaway_rule.py
Normal file
@ -0,0 +1,93 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import copy
|
||||
from frappe import _
|
||||
from frappe.utils import flt
|
||||
from frappe.model.document import Document
|
||||
|
||||
class PutawayRule(Document):
|
||||
def validate(self):
|
||||
self.validate_duplicate_rule()
|
||||
self.validate_warehouse_and_company()
|
||||
self.validate_capacity()
|
||||
self.validate_priority()
|
||||
|
||||
def validate_duplicate_rule(self):
|
||||
existing_rule = frappe.db.exists("Putaway Rule", {"item_code": self.item_code, "warehouse": self.warehouse})
|
||||
if existing_rule and existing_rule != self.name:
|
||||
frappe.throw(_("Putaway Rule already exists for Item {0} in Warehouse {1}.")
|
||||
.format(frappe.bold(self.item_code), frappe.bold(self.warehouse)),
|
||||
title=_("Duplicate"))
|
||||
|
||||
def validate_priority(self):
|
||||
if self.priority < 1:
|
||||
frappe.throw(_("Priority cannot be lesser than 1."), title=_("Invalid Priority"))
|
||||
|
||||
def validate_warehouse_and_company(self):
|
||||
company = frappe.db.get_value("Warehouse", self.warehouse, "company")
|
||||
if company != self.company:
|
||||
frappe.throw(_("Warehouse {0} does not belong to Company {1}.")
|
||||
.format(frappe.bold(self.warehouse), frappe.bold(self.company)),
|
||||
title=_("Invalid Warehouse"))
|
||||
|
||||
def validate_capacity(self):
|
||||
# check if capacity is lesser than current balance in warehouse
|
||||
pass
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_ordered_putaway_rules(item_code, company, qty):
|
||||
"""Returns an ordered list of putaway rules to apply on an item."""
|
||||
|
||||
# get enabled putaway rules for this item code in this company that have pending capacity
|
||||
# order the rules by priority first
|
||||
# if same priority, order by pending capacity (capacity - get how much stock is in the warehouse)
|
||||
# return this list
|
||||
# [{'name': "something", "free space": 20}, {'name': "something", "free space": 10}]
|
||||
|
||||
@frappe.whitelist()
|
||||
def apply_putaway_rule(items, company):
|
||||
""" Applies Putaway Rule on line items.
|
||||
|
||||
items: List of line items in a Purchase Receipt
|
||||
company: Company in Purchase Receipt
|
||||
"""
|
||||
items_not_accomodated = []
|
||||
for item in items:
|
||||
item_qty = item.qty
|
||||
at_capacity, rules = get_ordered_putaway_rules(item.item_code, company, item_qty)
|
||||
|
||||
if not rules:
|
||||
if at_capacity:
|
||||
items_not_accomodated.append([item.item_code, item_qty])
|
||||
continue
|
||||
|
||||
item_row_updated = False
|
||||
for rule in rules:
|
||||
while item_qty > 0:
|
||||
if not item_row_updated:
|
||||
# update pre-existing row
|
||||
item.qty = rule.qty
|
||||
item.warehouse = rule.warehouse
|
||||
item_row_updated = True
|
||||
else:
|
||||
# add rows for split quantity
|
||||
added_row = copy.deepcopy(item)
|
||||
added_row.qty = rule.qty
|
||||
added_row.warehouse = rule.warehouse
|
||||
items.append(added_row)
|
||||
|
||||
item_qty -= flt(rule.qty)
|
||||
|
||||
# if pending qty after applying rules, add row without warehouse
|
||||
if item_qty > 0:
|
||||
added_row = copy.deepcopy(item)
|
||||
added_row.qty = item_qty
|
||||
added_row.warehouse = ''
|
||||
items.append(added_row)
|
||||
items_not_accomodated.append([item.item_code, item_qty])
|
||||
|
||||
# need to check pricing rule, item tax impact
|
10
erpnext/stock/doctype/putaway_rule/putaway_rule_list.js
Normal file
10
erpnext/stock/doctype/putaway_rule/putaway_rule_list.js
Normal file
@ -0,0 +1,10 @@
|
||||
frappe.listview_settings['Putaway Rule'] = {
|
||||
add_fields: ["disable"],
|
||||
get_indicator: (doc) => {
|
||||
if (doc.disable) {
|
||||
return [__("Disabled"), "darkgrey", "disable,=,1"];
|
||||
} else {
|
||||
return [__("Active"), "blue", "disable,=,0"];
|
||||
};
|
||||
}
|
||||
};
|
10
erpnext/stock/doctype/putaway_rule/test_putaway_rule.py
Normal file
10
erpnext/stock/doctype/putaway_rule/test_putaway_rule.py
Normal file
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
class TestPutawayRule(unittest.TestCase):
|
||||
pass
|
Loading…
Reference in New Issue
Block a user