mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-28 17:34:47 +00:00
Reduce ordered qty in Purchase Receipt based on PO warehouse
This commit is contained in:
@@ -117,7 +117,7 @@ def check_negative_balance(account, adv_adj=False):
|
|||||||
flt(balance[0][0]) or -1*flt(balance[0][0])
|
flt(balance[0][0]) or -1*flt(balance[0][0])
|
||||||
|
|
||||||
if flt(balance) < 0:
|
if flt(balance) < 0:
|
||||||
webnotes.throw(_("Negative balance is not allowed for account ") + self.doc.account)
|
webnotes.throw(_("Negative balance is not allowed for account ") + account)
|
||||||
|
|
||||||
def check_freezing_date(posting_date, adv_adj=False):
|
def check_freezing_date(posting_date, adv_adj=False):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from __future__ import unicode_literals
|
|||||||
import unittest
|
import unittest
|
||||||
import webnotes
|
import webnotes
|
||||||
import webnotes.defaults
|
import webnotes.defaults
|
||||||
|
from webnotes.utils import flt
|
||||||
|
|
||||||
class TestPurchaseOrder(unittest.TestCase):
|
class TestPurchaseOrder(unittest.TestCase):
|
||||||
def test_make_purchase_receipt(self):
|
def test_make_purchase_receipt(self):
|
||||||
@@ -18,6 +19,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
|
|
||||||
po = webnotes.bean("Purchase Order", po.doc.name)
|
po = webnotes.bean("Purchase Order", po.doc.name)
|
||||||
po.submit()
|
po.submit()
|
||||||
|
|
||||||
pr = make_purchase_receipt(po.doc.name)
|
pr = make_purchase_receipt(po.doc.name)
|
||||||
pr[0]["supplier_warehouse"] = "_Test Warehouse 1 - _TC"
|
pr[0]["supplier_warehouse"] = "_Test Warehouse 1 - _TC"
|
||||||
|
|
||||||
@@ -25,7 +27,52 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
self.assertEquals(len(pr), len(test_records[0]))
|
self.assertEquals(len(pr), len(test_records[0]))
|
||||||
|
|
||||||
pr[0].naming_series = "_T-Purchase Receipt-"
|
pr[0].naming_series = "_T-Purchase Receipt-"
|
||||||
webnotes.bean(pr).insert()
|
pr_bean = webnotes.bean(pr)
|
||||||
|
pr_bean.insert()
|
||||||
|
|
||||||
|
def test_ordered_qty(self):
|
||||||
|
webnotes.conn.sql("delete from tabBin")
|
||||||
|
|
||||||
|
from buying.doctype.purchase_order.purchase_order import make_purchase_receipt
|
||||||
|
|
||||||
|
po = webnotes.bean(copy=test_records[0]).insert()
|
||||||
|
|
||||||
|
self.assertRaises(webnotes.ValidationError, make_purchase_receipt,
|
||||||
|
po.doc.name)
|
||||||
|
|
||||||
|
po = webnotes.bean("Purchase Order", po.doc.name)
|
||||||
|
po.doc.is_subcontracted = "No"
|
||||||
|
po.doclist[1].item_code = "_Test Item"
|
||||||
|
po.submit()
|
||||||
|
|
||||||
|
self.assertEquals(webnotes.conn.get_value("Bin", {"item_code": "_Test Item",
|
||||||
|
"warehouse": "_Test Warehouse - _TC"}, "ordered_qty"), 10)
|
||||||
|
|
||||||
|
pr = make_purchase_receipt(po.doc.name)
|
||||||
|
|
||||||
|
self.assertEquals(pr[0]["doctype"], "Purchase Receipt")
|
||||||
|
self.assertEquals(len(pr), len(test_records[0]))
|
||||||
|
|
||||||
|
pr[0].naming_series = "_T-Purchase Receipt-"
|
||||||
|
pr[1].qty = 4.0
|
||||||
|
pr_bean = webnotes.bean(pr)
|
||||||
|
pr_bean.insert()
|
||||||
|
pr_bean.submit()
|
||||||
|
|
||||||
|
self.assertEquals(flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item",
|
||||||
|
"warehouse": "_Test Warehouse - _TC"}, "ordered_qty")), 6.0)
|
||||||
|
|
||||||
|
webnotes.conn.set_value('Item', '_Test Item', 'tolerance', 50)
|
||||||
|
|
||||||
|
pr1 = make_purchase_receipt(po.doc.name)
|
||||||
|
pr1[0].naming_series = "_T-Purchase Receipt-"
|
||||||
|
pr1[1].qty = 8
|
||||||
|
pr1_bean = webnotes.bean(pr1)
|
||||||
|
pr1_bean.insert()
|
||||||
|
pr1_bean.submit()
|
||||||
|
|
||||||
|
self.assertEquals(flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item",
|
||||||
|
"warehouse": "_Test Warehouse - _TC"}, "ordered_qty")), 0.0)
|
||||||
|
|
||||||
def test_make_purchase_invocie(self):
|
def test_make_purchase_invocie(self):
|
||||||
from buying.doctype.purchase_order.purchase_order import make_purchase_invoice
|
from buying.doctype.purchase_order.purchase_order import make_purchase_invoice
|
||||||
|
|||||||
@@ -117,8 +117,7 @@ class DocType(BuyingController):
|
|||||||
},
|
},
|
||||||
"Purchase Order Item": {
|
"Purchase Order Item": {
|
||||||
"ref_dn_field": "prevdoc_detail_docname",
|
"ref_dn_field": "prevdoc_detail_docname",
|
||||||
"compare_fields": [["project_name", "="], ["warehouse", "="],
|
"compare_fields": [["project_name", "="], ["uom", "="], ["item_code", "="]],
|
||||||
["uom", "="], ["item_code", "="]],
|
|
||||||
"is_child_table": True
|
"is_child_table": True
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -166,33 +165,42 @@ class DocType(BuyingController):
|
|||||||
self.bk_flush_supp_wh(sl_entries)
|
self.bk_flush_supp_wh(sl_entries)
|
||||||
self.make_sl_entries(sl_entries)
|
self.make_sl_entries(sl_entries)
|
||||||
|
|
||||||
def update_ordered_qty(self, is_cancelled="No"):
|
def update_ordered_qty(self):
|
||||||
pc_obj = get_obj('Purchase Common')
|
|
||||||
stock_items = self.get_stock_items()
|
stock_items = self.get_stock_items()
|
||||||
for d in getlist(self.doclist, 'purchase_receipt_details'):
|
for d in self.doclist.get({"parentfield": "purchase_receipt_details"}):
|
||||||
if d.item_code in stock_items and d.warehouse \
|
if d.item_code in stock_items and d.warehouse \
|
||||||
and cstr(d.prevdoc_doctype) == 'Purchase Order':
|
and cstr(d.prevdoc_doctype) == 'Purchase Order':
|
||||||
pr_qty = flt(d.qty) * flt(d.conversion_factor)
|
|
||||||
|
|
||||||
# get qty and pending_qty of prevdoc
|
already_received_qty = self.get_already_received_qty(d.prevdoc_docname,
|
||||||
curr_ref_qty = pc_obj.get_qty(d.doctype, 'prevdoc_detail_docname',
|
d.prevdoc_detail_docname)
|
||||||
d.prevdoc_detail_docname, 'Purchase Order Item',
|
po_qty, ordered_warehouse = self.get_po_qty_and_warehouse(d.prevdoc_detail_docname)
|
||||||
'Purchase Order - Purchase Receipt', self.doc.name)
|
|
||||||
max_qty, qty, curr_qty = flt(curr_ref_qty.split('~~~')[1]), \
|
|
||||||
flt(curr_ref_qty.split('~~~')[0]), 0
|
|
||||||
|
|
||||||
if flt(qty) + flt(pr_qty) > flt(max_qty):
|
if not ordered_warehouse:
|
||||||
curr_qty = (flt(max_qty) - flt(qty)) * flt(d.conversion_factor)
|
webnotes.throw(_("Warehouse is missing in Purchase Order"))
|
||||||
|
|
||||||
|
if already_received_qty + d.qty > po_qty:
|
||||||
|
ordered_qty = - (po_qty - already_received_qty) * flt(d.conversion_factor)
|
||||||
else:
|
else:
|
||||||
curr_qty = flt(pr_qty)
|
ordered_qty = - flt(d.qty) * flt(d.conversion_factor)
|
||||||
|
|
||||||
args = {
|
update_bin({
|
||||||
"item_code": d.item_code,
|
"item_code": d.item_code,
|
||||||
"warehouse": d.warehouse,
|
"warehouse": ordered_warehouse,
|
||||||
"posting_date": self.doc.posting_date,
|
"posting_date": self.doc.posting_date,
|
||||||
"ordered_qty": (is_cancelled=="Yes" and -1 or 1)*flt(curr_qty)
|
"ordered_qty": flt(ordered_qty) if self.doc.docstatus==1 else -flt(ordered_qty)
|
||||||
}
|
})
|
||||||
update_bin(args)
|
|
||||||
|
def get_already_received_qty(self, po, po_detail):
|
||||||
|
qty = webnotes.conn.sql("""select sum(qty) from `tabPurchase Receipt Item`
|
||||||
|
where prevdoc_detail_docname = %s and docstatus = 1
|
||||||
|
and prevdoc_doctype='Purchase Order' and prevdoc_docname=%s
|
||||||
|
and parent != %s""", (po_detail, po, self.doc.name))
|
||||||
|
return qty and flt(qty[0][0]) or 0.0
|
||||||
|
|
||||||
|
def get_po_qty_and_warehouse(self, po_detail):
|
||||||
|
po_qty, po_warehouse = webnotes.conn.get_value("Purchase Order Item", po_detail,
|
||||||
|
["qty", "warehouse"])
|
||||||
|
return po_qty, po_warehouse
|
||||||
|
|
||||||
def bk_flush_supp_wh(self, sl_entries):
|
def bk_flush_supp_wh(self, sl_entries):
|
||||||
for d in getlist(self.doclist, 'pr_raw_material_details'):
|
for d in getlist(self.doclist, 'pr_raw_material_details'):
|
||||||
@@ -201,7 +209,7 @@ class DocType(BuyingController):
|
|||||||
sl_entries.append(self.get_sl_entries(d, {
|
sl_entries.append(self.get_sl_entries(d, {
|
||||||
"item_code": d.rm_item_code,
|
"item_code": d.rm_item_code,
|
||||||
"warehouse": self.doc.supplier_warehouse,
|
"warehouse": self.doc.supplier_warehouse,
|
||||||
"actual_qty": -1*flt(consumed_qty),
|
"actual_qty": -1*flt(d.consumed_qty),
|
||||||
"incoming_rate": 0
|
"incoming_rate": 0
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@@ -281,7 +289,7 @@ class DocType(BuyingController):
|
|||||||
|
|
||||||
webnotes.conn.set(self.doc,'status','Cancelled')
|
webnotes.conn.set(self.doc,'status','Cancelled')
|
||||||
|
|
||||||
self.update_ordered_qty(is_cancelled="Yes")
|
self.update_ordered_qty()
|
||||||
|
|
||||||
self.update_stock()
|
self.update_stock()
|
||||||
self.update_serial_nos(cancel=True)
|
self.update_serial_nos(cancel=True)
|
||||||
|
|||||||
@@ -60,9 +60,6 @@ class DocType:
|
|||||||
webnotes.throw(_("Please enter account group under which account \
|
webnotes.throw(_("Please enter account group under which account \
|
||||||
for warehouse ") + self.doc.name +_(" will be created"))
|
for warehouse ") + self.doc.name +_(" will be created"))
|
||||||
|
|
||||||
def on_rename(self, new, old):
|
|
||||||
webnotes.conn.set_value("Account", {"account_type": "Warehouse", "master_name": old},
|
|
||||||
"master_name", new)
|
|
||||||
|
|
||||||
def merge_warehouses(self):
|
def merge_warehouses(self):
|
||||||
webnotes.conn.auto_commit_on_many_writes = 1
|
webnotes.conn.auto_commit_on_many_writes = 1
|
||||||
@@ -207,6 +204,9 @@ class DocType:
|
|||||||
sql("delete from `tabStock Ledger Entry` where warehouse = %s", self.doc.name)
|
sql("delete from `tabStock Ledger Entry` where warehouse = %s", self.doc.name)
|
||||||
|
|
||||||
def on_rename(self, newdn, olddn, merge=False):
|
def on_rename(self, newdn, olddn, merge=False):
|
||||||
|
webnotes.conn.set_value("Account", {"account_type": "Warehouse", "master_name": olddn},
|
||||||
|
"master_name", newdn)
|
||||||
|
|
||||||
if merge:
|
if merge:
|
||||||
from stock.stock_ledger import update_entries_after
|
from stock.stock_ledger import update_entries_after
|
||||||
for item_code in webnotes.conn.sql("""select item_code from `tabBin`
|
for item_code in webnotes.conn.sql("""select item_code from `tabBin`
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ class TransactionBase(StatusUpdater):
|
|||||||
|
|
||||||
def get_customer_address(self, args):
|
def get_customer_address(self, args):
|
||||||
args = load_json(args)
|
args = load_json(args)
|
||||||
|
webnotes.errprint(args)
|
||||||
ret = {
|
ret = {
|
||||||
'customer_address' : args["address"],
|
'customer_address' : args["address"],
|
||||||
'address_display' : get_address_display(args["address"]),
|
'address_display' : get_address_display(args["address"]),
|
||||||
|
|||||||
Reference in New Issue
Block a user