chore: Test and fixes

- Tests as per new design flow
- Fixed duplicate data bug in Warehouse Capacity Summary
- Set Amount currently on applying rule in client side
- Apply rules on server side before validate
This commit is contained in:
marination 2020-12-09 16:27:18 +05:30
parent 0f3cfc502b
commit a5d8d32775
6 changed files with 72 additions and 74 deletions

View File

@ -2050,9 +2050,10 @@ erpnext.apply_putaway_rule = (frm) => {
let items = result.message; let items = result.message;
items.forEach((row) => { items.forEach((row) => {
delete row["name"]; delete row["name"]; // dont overwrite name from server side
let child = frm.add_child("items"); let child = frm.add_child("items");
Object.assign(child, row); Object.assign(child, row);
frm.script_manager.trigger("qty", child.doctype, child.name);
}); });
frm.get_field("items").grid.refresh(); frm.get_field("items").grid.refresh();
} }

View File

@ -69,7 +69,7 @@ erpnext.stock.ItemDashboard = Class.extend({
// more // more
this.content.find('.btn-more').on('click', function() { this.content.find('.btn-more').on('click', function() {
me.start += this.page_length; me.start += me.page_length;
me.refresh(); me.refresh();
}); });

View File

@ -83,7 +83,7 @@ class PurchaseReceipt(BuyingController):
} }
]) ])
def before_save(self): def before_validate(self):
from erpnext.stock.doctype.putaway_rule.putaway_rule import apply_putaway_rule from erpnext.stock.doctype.putaway_rule.putaway_rule import apply_putaway_rule
if self.get("items") and self.apply_putaway_rule: if self.get("items") and self.apply_putaway_rule:

View File

@ -979,6 +979,7 @@ def make_purchase_receipt(**args):
pr.currency = args.currency or "INR" pr.currency = args.currency or "INR"
pr.is_return = args.is_return pr.is_return = args.is_return
pr.return_against = args.return_against pr.return_against = args.return_against
pr.apply_putaway_rule = args.apply_putaway_rule
qty = args.qty or 5 qty = args.qty or 5
received_qty = args.received_qty or qty received_qty = args.received_qty or qty
rejected_qty = args.rejected_qty or flt(received_qty) - flt(qty) rejected_qty = args.rejected_qty or flt(received_qty) - flt(qty)
@ -994,6 +995,7 @@ def make_purchase_receipt(**args):
"rejected_warehouse": args.rejected_warehouse or "_Test Rejected Warehouse - _TC" if rejected_qty != 0 else "", "rejected_warehouse": args.rejected_warehouse or "_Test Rejected Warehouse - _TC" if rejected_qty != 0 else "",
"rate": args.rate if args.rate != None else 50, "rate": args.rate if args.rate != None else 50,
"conversion_factor": args.conversion_factor or 1.0, "conversion_factor": args.conversion_factor or 1.0,
"stock_qty": flt(qty) * (flt(args.conversion_factor) or 1.0),
"serial_no": args.serial_no, "serial_no": args.serial_no,
"stock_uom": args.stock_uom or "_Test UOM", "stock_uom": args.stock_uom or "_Test UOM",
"uom": uom, "uom": uom,

View File

@ -9,8 +9,8 @@ from erpnext.stock.doctype.item.test_item import make_item
from erpnext.stock.get_item_details import get_conversion_factor from erpnext.stock.get_item_details import get_conversion_factor
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
class TestPutawayRule(unittest.TestCase): class TestPutawayRule(unittest.TestCase):
def setUp(self): def setUp(self):
@ -42,17 +42,15 @@ class TestPutawayRule(unittest.TestCase):
rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=300, rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=300,
uom="Kg", priority=2) uom="Kg", priority=2)
po = create_purchase_order(item_code="_Rice", qty=300) pr = make_purchase_receipt(item_code="_Rice", qty=300, apply_putaway_rule=1,
self.assertEqual(len(po.items), 1) do_not_submit=1)
pr = make_purchase_receipt(po.name)
self.assertEqual(len(pr.items), 2) self.assertEqual(len(pr.items), 2)
self.assertEqual(pr.items[0].qty, 200) self.assertEqual(pr.items[0].qty, 200)
self.assertEqual(pr.items[0].warehouse, warehouse_1) self.assertEqual(pr.items[0].warehouse, warehouse_1)
self.assertEqual(pr.items[1].qty, 100) self.assertEqual(pr.items[1].qty, 100)
self.assertEqual(pr.items[1].warehouse, warehouse_2) self.assertEqual(pr.items[1].warehouse, warehouse_2)
po.cancel() pr.delete()
rule_1.delete() rule_1.delete()
rule_2.delete() rule_2.delete()
@ -70,10 +68,8 @@ class TestPutawayRule(unittest.TestCase):
# out of 500 kg capacity, occupy 100 kg in warehouse_1 # out of 500 kg capacity, occupy 100 kg in warehouse_1
stock_receipt = make_stock_entry(item_code="_Rice", target=warehouse_1, qty=100, basic_rate=50) stock_receipt = make_stock_entry(item_code="_Rice", target=warehouse_1, qty=100, basic_rate=50)
po = create_purchase_order(item_code="_Rice", qty=700) pr = make_purchase_receipt(item_code="_Rice", qty=700, apply_putaway_rule=1,
self.assertEqual(len(po.items), 1) do_not_submit=1)
pr = make_purchase_receipt(po.name)
self.assertEqual(len(pr.items), 2) self.assertEqual(len(pr.items), 2)
self.assertEqual(pr.items[0].qty, 500) self.assertEqual(pr.items[0].qty, 500)
# warehouse_2 has 500 kg free space, it is given priority # warehouse_2 has 500 kg free space, it is given priority
@ -82,8 +78,8 @@ class TestPutawayRule(unittest.TestCase):
# warehouse_1 has 400 kg free space, it is given less priority # warehouse_1 has 400 kg free space, it is given less priority
self.assertEqual(pr.items[1].warehouse, warehouse_1) self.assertEqual(pr.items[1].warehouse, warehouse_1)
po.cancel()
stock_receipt.cancel() stock_receipt.cancel()
pr.delete()
rule_1.delete() rule_1.delete()
rule_2.delete() rule_2.delete()
@ -97,21 +93,14 @@ class TestPutawayRule(unittest.TestCase):
rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=200, rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=200,
uom="Kg") uom="Kg")
po = create_purchase_order(item_code="_Rice", qty=350) pr = make_purchase_receipt(item_code="_Rice", qty=350, apply_putaway_rule=1,
self.assertEqual(len(po.items), 1) do_not_submit=1)
self.assertEqual(len(pr.items), 2)
pr = make_purchase_receipt(po.name)
self.assertEqual(len(pr.items), 3)
self.assertEqual(pr.items[0].qty, 200) self.assertEqual(pr.items[0].qty, 200)
self.assertEqual(pr.items[0].warehouse, warehouse_2) self.assertEqual(pr.items[0].warehouse, warehouse_2)
self.assertEqual(pr.items[1].qty, 100) self.assertEqual(pr.items[1].qty, 100)
self.assertEqual(pr.items[1].warehouse, warehouse_1) self.assertEqual(pr.items[1].warehouse, warehouse_1)
# extra qty has no warehouse assigned pr.delete()
self.assertEqual(pr.items[2].qty, 50)
self.assertEqual(pr.items[2].warehouse, '')
po.cancel()
rule_1.delete() rule_1.delete()
rule_2.delete() rule_2.delete()
@ -135,24 +124,19 @@ class TestPutawayRule(unittest.TestCase):
uom="Bag") uom="Bag")
self.assertEqual(rule_2.stock_capacity, 4000) self.assertEqual(rule_2.stock_capacity, 4000)
# populate 'Rack 1' with 1 Bag, making the free space 2 Bags
stock_receipt = make_stock_entry(item_code="_Rice", target=warehouse_1, qty=1000, basic_rate=50) stock_receipt = make_stock_entry(item_code="_Rice", target=warehouse_1, qty=1000, basic_rate=50)
po = create_purchase_order(item_code="_Rice", qty=6, do_not_save=True) pr = make_purchase_receipt(item_code="_Rice", qty=6, uom="Bag", stock_uom="Kg",
po.items[0].uom = "Bag" conversion_factor=1000, apply_putaway_rule=1, do_not_submit=1)
po.save()
po.submit()
self.assertEqual(po.items[0].stock_qty, 6000)
pr = make_purchase_receipt(po.name)
self.assertEqual(len(pr.items), 2) self.assertEqual(len(pr.items), 2)
self.assertEqual(pr.items[0].qty, 4) self.assertEqual(pr.items[0].qty, 4)
self.assertEqual(pr.items[0].warehouse, warehouse_2) self.assertEqual(pr.items[0].warehouse, warehouse_2)
self.assertEqual(pr.items[1].qty, 2) self.assertEqual(pr.items[1].qty, 2)
self.assertEqual(pr.items[1].warehouse, warehouse_1) self.assertEqual(pr.items[1].warehouse, warehouse_1)
po.cancel()
stock_receipt.cancel() stock_receipt.cancel()
pr.delete()
rule_1.delete() rule_1.delete()
rule_2.delete() rule_2.delete()
@ -180,24 +164,15 @@ class TestPutawayRule(unittest.TestCase):
self.assertEqual(rule_2.stock_capacity, 500) self.assertEqual(rule_2.stock_capacity, 500)
# total capacity is 1500 Kg # total capacity is 1500 Kg
po = create_purchase_order(item_code="_Rice", qty=2, do_not_save=True) pr = make_purchase_receipt(item_code="_Rice", qty=2, uom="Bag", stock_uom="Kg",
# PO for 2 Bags (2000 Kg) conversion_factor=1000, apply_putaway_rule=1, do_not_submit=1)
po.items[0].uom = "Bag" self.assertEqual(len(pr.items), 1)
po.save()
po.submit()
self.assertEqual(po.items[0].stock_qty, 2000)
pr = make_purchase_receipt(po.name)
self.assertEqual(len(pr.items), 2)
self.assertEqual(pr.items[0].qty, 1) self.assertEqual(pr.items[0].qty, 1)
self.assertEqual(pr.items[0].warehouse, warehouse_1) self.assertEqual(pr.items[0].warehouse, warehouse_1)
# leftover space was for 500 kg (0.5 Bag) # leftover space was for 500 kg (0.5 Bag)
# Since Bag is a whole UOM, 1(out of 2) Bag will be unassigned # Since Bag is a whole UOM, 1(out of 2) Bag will be unassigned
self.assertEqual(pr.items[1].qty, 1)
self.assertEqual(pr.items[1].warehouse, '')
po.cancel() pr.delete()
rule_1.delete() rule_1.delete()
rule_2.delete() rule_2.delete()
@ -208,38 +183,58 @@ class TestPutawayRule(unittest.TestCase):
rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=200, rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=200,
uom="Kg") uom="Kg")
rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=100, # total capacity is 200 Kg
uom="Kg", priority=2)
# total capacity is 300 Kg
po = create_purchase_order(item_code="_Rice", qty=200, rate=100, do_not_save=True) pr = make_purchase_receipt(item_code="_Rice", qty=100, apply_putaway_rule=1,
po.append("items", { do_not_submit=1)
"item_code":"_Rice", pr.append("items", {
"item_code": "_Rice",
"warehouse": "_Test Warehouse - _TC", "warehouse": "_Test Warehouse - _TC",
"qty": 300, "qty": 200,
"rate": 120, "uom": "Kg",
"schedule_date": add_days(nowdate(), 1), "stock_uom": "Kg",
}) "stock_qty": 200,
po.save() "received_qty": 200,
po.submit() "rate": 100,
# PO for 500 Kg (two rows of same item, different rates) "conversion_factor": 1.0,
self.assertEqual(len(po.items), 2) }) # same item entered again in PR but with different rate
pr.save()
pr = make_purchase_receipt(po.name) self.assertEqual(len(pr.items), 2)
self.assertEqual(len(pr.items), 3) self.assertEqual(pr.items[0].qty, 100)
self.assertEqual(pr.items[0].qty, 200)
self.assertEqual(pr.items[0].warehouse, warehouse_1) self.assertEqual(pr.items[0].warehouse, warehouse_1)
# same rules applied to second item row self.assertEqual(pr.items[0].putaway_rule, rule_1.name)
# same rule applied to second item row
# with previous assignment considered # with previous assignment considered
self.assertEqual(pr.items[1].qty, 100) self.assertEqual(pr.items[1].qty, 100) # 100 unassigned in second row from 200
self.assertEqual(pr.items[1].warehouse, warehouse_2) self.assertEqual(pr.items[1].warehouse, warehouse_1)
# unassigned 200 Kg self.assertEqual(pr.items[1].putaway_rule, rule_1.name)
self.assertEqual(pr.items[2].qty, 200)
self.assertEqual(pr.items[2].warehouse, '')
po.cancel() pr.delete()
rule_1.delete()
def test_validate_over_receipt_in_warehouse(self):
"""Test if overreceipt is blocked in the presence of putaway rules."""
warehouse_1 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 1"})
warehouse_2 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 2"})
rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=200,
uom="Kg")
pr = make_purchase_receipt(item_code="_Rice", qty=300, apply_putaway_rule=1,
do_not_submit=1)
self.assertEqual(len(pr.items), 1)
self.assertEqual(pr.items[0].qty, 200) # 100 is unassigned fro 300 Kg
self.assertEqual(pr.items[0].warehouse, warehouse_1)
self.assertEqual(pr.items[0].putaway_rule, rule_1.name)
# force overreceipt and disable apply putaway rule in PR
pr.items[0].qty = 300
pr.items[0].stock_qty = 300
pr.apply_putaway_rule = 0
self.assertRaises(frappe.ValidationError, pr.save)
pr.delete()
rule_1.delete() rule_1.delete()
rule_2.delete()
def create_putaway_rule(**args): def create_putaway_rule(**args):
args = frappe._dict(args) args = frappe._dict(args)

View File

@ -42,7 +42,7 @@ class StockEntry(StockController):
for item in self.get("items"): for item in self.get("items"):
item.update(get_bin_details(item.item_code, item.s_warehouse)) item.update(get_bin_details(item.item_code, item.s_warehouse))
def before_save(self): def before_validate(self):
from erpnext.stock.doctype.putaway_rule.putaway_rule import apply_putaway_rule from erpnext.stock.doctype.putaway_rule.putaway_rule import apply_putaway_rule
apply_rule = self.apply_putaway_rule and (self.purpose in ["Material Transfer", "Material Receipt"]) apply_rule = self.apply_putaway_rule and (self.purpose in ["Material Transfer", "Material Receipt"])