[production] update planned and produced ty
diff --git a/manufacturing/doctype/production_order/production_order.py b/manufacturing/doctype/production_order/production_order.py
index 719d149..b29b0f1 100644
--- a/manufacturing/doctype/production_order/production_order.py
+++ b/manufacturing/doctype/production_order/production_order.py
@@ -18,6 +18,9 @@
self.doclist = doclist
def validate(self):
+ if self.doc.docstatus == 0:
+ self.doc.status = "Draft"
+
import utilities
utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Stopped",
"In Process", "Completed", "Cancelled"])
@@ -149,12 +152,6 @@
@webnotes.whitelist()
def make_stock_entry(production_order_id, purpose):
production_order = webnotes.bean("Production Order", production_order_id)
-
- # validate already existing
- ste = webnotes.conn.get_value("Stock Entry", {
- "production_order":production_order_id,
- "purpose": purpose
- }, "name")
stock_entry = webnotes.new_bean("Stock Entry")
stock_entry.doc.purpose = purpose
@@ -171,4 +168,4 @@
stock_entry.doc.to_warehouse = production_order.doc.fg_warehouse
stock_entry.run_method("get_items")
- return [d.fields for d in stock_entry.doclist]
+ return [d.fields for d in stock_entry.doclist]
\ No newline at end of file
diff --git a/manufacturing/doctype/production_order/test_production_order.py b/manufacturing/doctype/production_order/test_production_order.py
new file mode 100644
index 0000000..9a75762
--- /dev/null
+++ b/manufacturing/doctype/production_order/test_production_order.py
@@ -0,0 +1,75 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
+# License: GNU General Public License v3. See license.txt
+
+
+from __future__ import unicode_literals
+import unittest
+import webnotes
+from stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
+from manufacturing.doctype.production_order.production_order import make_stock_entry
+
+
+class TestProductionOrder(unittest.TestCase):
+ def test_planned_qty(self):
+ set_perpetual_inventory(0)
+ webnotes.conn.sql("delete from `tabStock Ledger Entry`")
+ webnotes.conn.sql("""delete from `tabBin`""")
+ webnotes.conn.sql("""delete from `tabGL Entry`""")
+
+ pro_bean = webnotes.bean(copy = test_records[0])
+ pro_bean.insert()
+ pro_bean.submit()
+
+ from stock.doctype.stock_entry.test_stock_entry import test_records as se_test_records
+ mr1 = webnotes.bean(copy = se_test_records[0])
+ mr1.insert()
+ mr1.submit()
+
+ mr2 = webnotes.bean(copy = se_test_records[0])
+ mr2.doclist[1].item_code = "_Test Item Home Desktop 100"
+ mr2.insert()
+ mr2.submit()
+
+ stock_entry = make_stock_entry(pro_bean.doc.name, "Manufacture/Repack")
+ stock_entry = webnotes.bean(stock_entry)
+
+ stock_entry.doc.fg_completed_qty = 4
+ stock_entry.run_method("get_items")
+ stock_entry.submit()
+
+ self.assertEqual(webnotes.conn.get_value("Production Order", pro_bean.doc.name,
+ "produced_qty"), 4)
+ self.assertEqual(webnotes.conn.get_value("Bin", {"item_code": "_Test FG Item",
+ "warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty"), 6)
+
+ return pro_bean.doc.name
+
+ def test_over_production(self):
+ from stock.doctype.stock_entry.stock_entry import StockOverProductionError
+ pro_order = self.test_planned_qty()
+
+ stock_entry = make_stock_entry(pro_order, "Manufacture/Repack")
+ stock_entry = webnotes.bean(stock_entry)
+
+ stock_entry.doc.fg_completed_qty = 15
+ stock_entry.run_method("get_items")
+ stock_entry.insert()
+
+ self.assertRaises(StockOverProductionError, stock_entry.submit)
+
+
+
+test_records = [
+ [
+ {
+ "bom_no": "BOM/_Test FG Item/001",
+ "company": "_Test Company",
+ "doctype": "Production Order",
+ "production_item": "_Test FG Item",
+ "qty": 10.0,
+ "fg_warehouse": "_Test Warehouse 1 - _TC",
+ "wip_warehouse": "_Test Warehouse - _TC",
+ "stock_uom": "Nos"
+ }
+ ]
+]
\ No newline at end of file
diff --git a/patches/december_2012/repost_ordered_qty.py b/patches/december_2012/repost_ordered_qty.py
index e73b726..4c1d11d 100644
--- a/patches/december_2012/repost_ordered_qty.py
+++ b/patches/december_2012/repost_ordered_qty.py
@@ -3,19 +3,9 @@
def execute():
import webnotes
- from webnotes.utils import flt
-
- for d in webnotes.conn.sql("select name, item_code, warehouse, ordered_qty from tabBin",
- as_dict=1):
- ordered_qty = webnotes.conn.sql("""
- select sum((po_item.qty - po_item.received_qty)*po_item.conversion_factor)
- from `tabPurchase Order Item` po_item, `tabPurchase Order` po
- where po_item.item_code=%s and po_item.warehouse=%s
- and po_item.qty > po_item.received_qty and po_item.parent=po.name
- and po.status!='Stopped' and po.docstatus=1""", (d.item_code, d.warehouse))
+ from utilities.repost_stock import get_ordered_qty, update_bin
- if flt(d.ordered_qty) != flt(ordered_qty[0][0]):
- webnotes.conn.set_value("Bin", d.name, "ordered_qty", flt(ordered_qty[0][0]))
-
- webnotes.conn.sql("""update tabBin set projected_qty = actual_qty + planned_qty +
- indented_qty + ordered_qty - reserved_qty where name = %s""", d.name)
\ No newline at end of file
+ for d in webnotes.conn.sql("select item_code, warehouse from tabBin"):
+ update_bin(d[0], d[1], {
+ "ordered_qty": get_ordered_qty(d[0], d[1])
+ })
\ No newline at end of file
diff --git a/patches/february_2013/repost_reserved_qty.py b/patches/february_2013/repost_reserved_qty.py
index 3a3353f..5c41266 100644
--- a/patches/february_2013/repost_reserved_qty.py
+++ b/patches/february_2013/repost_reserved_qty.py
@@ -4,54 +4,10 @@
import webnotes
def execute():
webnotes.conn.auto_commit_on_many_writes = 1
- repost_reserved_qty()
- webnotes.conn.auto_commit_on_many_writes = 0
+ from utilities.repost_stock import get_reserved_qty, update_bin
-def repost_reserved_qty():
- from webnotes.utils import flt
- bins = webnotes.conn.sql("select item_code, warehouse, name, reserved_qty from `tabBin`")
- i = 0
- for d in bins:
- i += 1
- reserved_qty = webnotes.conn.sql("""
- select
- sum((dnpi_qty / so_item_qty) * (so_item_qty - so_item_delivered_qty))
- from
- (
- (select
- qty as dnpi_qty,
- (
- select qty from `tabSales Order Item`
- where name = dnpi.parent_detail_docname
- ) as so_item_qty,
- (
- select ifnull(delivered_qty, 0) from `tabSales Order Item`
- where name = dnpi.parent_detail_docname
- ) as so_item_delivered_qty,
- parent, name
- from
- (
- select qty, parent_detail_docname, parent, name
- from `tabDelivery Note Packing Item` dnpi_in
- where item_code = %s and warehouse = %s
- and parenttype="Sales Order"
- and item_code != parent_item
- and exists (select * from `tabSales Order` so
- where name = dnpi_in.parent and docstatus = 1 and status != 'Stopped')
- ) dnpi)
- union
- (select qty as dnpi_qty, qty as so_item_qty,
- ifnull(delivered_qty, 0) as so_item_delivered_qty, parent, name
- from `tabSales Order Item` so_item
- where item_code = %s and reserved_warehouse = %s
- and exists(select * from `tabSales Order` so
- where so.name = so_item.parent and so.docstatus = 1
- and so.status != 'Stopped'))
- ) tab
- where
- so_item_qty >= so_item_delivered_qty
- """, (d[0], d[1], d[0], d[1]))
-
- if flt(d[3]) != flt(reserved_qty[0][0]):
- webnotes.conn.sql("""update `tabBin` set reserved_qty = %s where name = %s""",
- (reserved_qty and reserved_qty[0][0] or 0, d[2]))
\ No newline at end of file
+ for d in webnotes.conn.sql("select item_code, warehouse from tabBin"):
+ update_bin(d[0], d[1], {
+ "reserved_qty": get_reserved_qty(d[0], d[1])
+ })
+ webnotes.conn.auto_commit_on_many_writes = 0
\ No newline at end of file
diff --git a/patches/october_2013/repost_planned_qty.py b/patches/october_2013/repost_planned_qty.py
new file mode 100644
index 0000000..cfe47ca
--- /dev/null
+++ b/patches/october_2013/repost_planned_qty.py
@@ -0,0 +1,11 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
+# License: GNU General Public License v3. See license.txt
+
+def execute():
+ import webnotes
+ from utilities.repost_stock import get_planned_qty, update_bin
+
+ for d in webnotes.conn.sql("select item_code, warehouse from tabBin"):
+ update_bin(d[0], d[1], {
+ "planned_qty": get_planned_qty(d[0], d[1])
+ })
\ No newline at end of file
diff --git a/patches/patch_list.py b/patches/patch_list.py
index 6a5d0f4..59e0b0c 100644
--- a/patches/patch_list.py
+++ b/patches/patch_list.py
@@ -221,4 +221,5 @@
"patches.september_2013.p05_fix_customer_in_pos",
"patches.october_2013.fix_is_cancelled_in_sle",
"patches.october_2013.repost_ordered_qty",
+ "patches.october_2013.repost_planned_qty",
]
\ No newline at end of file
diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py
index 8d2e764..7d8130c 100644
--- a/stock/doctype/stock_entry/stock_entry.py
+++ b/stock/doctype/stock_entry/stock_entry.py
@@ -6,7 +6,7 @@
import webnotes.defaults
from webnotes.utils import cstr, cint, flt, comma_or, nowdate
-from webnotes.model.doc import Document, addchild
+from webnotes.model.doc import addchild
from webnotes.model.bean import getlist
from webnotes.model.code import get_obj
from webnotes import msgprint, _
@@ -21,6 +21,7 @@
class StockOverReturnError(webnotes.ValidationError): pass
class IncorrectValuationRateError(webnotes.ValidationError): pass
class DuplicateEntryForProductionOrderError(webnotes.ValidationError): pass
+class StockOverProductionError(webnotes.ValidationError): pass
from controllers.stock_controller import StockController
@@ -56,12 +57,12 @@
from stock.doctype.serial_no.serial_no import update_serial_nos_after_submit
update_serial_nos_after_submit(self, "Stock Entry", "mtn_details")
- self.update_production_order(1)
+ self.update_production_order()
self.make_gl_entries()
def on_cancel(self):
self.update_stock_ledger()
- self.update_production_order(0)
+ self.update_production_order()
self.make_cancel_gl_entries()
def validate_fiscal_year(self):
@@ -326,37 +327,44 @@
self.make_sl_entries(sl_entries, self.doc.amended_from and 'Yes' or 'No')
- def update_production_order(self, is_submit):
+ def update_production_order(self):
+ def _validate_production_order(pro_bean):
+ if flt(pro_bean.doc.docstatus) != 1:
+ webnotes.throw(_("Production Order must be submitted") + ": " +
+ self.doc.production_order)
+
+ if pro_bean.doc.status == 'Stopped':
+ msgprint(_("Transaction not allowed against stopped Production Order") + ": " +
+ self.doc.production_order)
+
if self.doc.production_order:
- # first perform some validations
- # (they are here coz this fn is also called during on_cancel)
- pro_obj = get_obj("Production Order", self.doc.production_order)
- if flt(pro_obj.doc.docstatus) != 1:
- msgprint("""You cannot do any transaction against
- Production Order : %s, as it's not submitted"""
- % (pro_obj.doc.name), raise_exception=1)
-
- if pro_obj.doc.status == 'Stopped':
- msgprint("""You cannot do any transaction against Production Order : %s,
- as it's status is 'Stopped'"""% (pro_obj.doc.name), raise_exception=1)
-
- # update bin
- if self.doc.purpose == "Manufacture/Repack":
- from stock.utils import update_bin
- pro_obj.doc.produced_qty = flt(pro_obj.doc.produced_qty) + \
- (is_submit and 1 or -1 ) * flt(self.doc.fg_completed_qty)
- args = {
- "item_code": pro_obj.doc.production_item,
- "warehouse": pro_obj.doc.fg_warehouse,
- "posting_date": self.doc.posting_date,
- "planned_qty": (is_submit and -1 or 1 ) * flt(self.doc.fg_completed_qty)
- }
- update_bin(args)
+ pro_bean = webnotes.bean("Production Order", self.doc.production_order)
+ _validate_production_order(pro_bean)
+ self.update_produced_qty(pro_bean)
+ self.update_planned_qty(pro_bean)
- # update production order status
- pro_obj.doc.status = (flt(pro_obj.doc.qty)==flt(pro_obj.doc.produced_qty)) \
- and 'Completed' or 'In Process'
- pro_obj.doc.save()
+ def update_produced_qty(self, pro_bean):
+ if self.doc.purpose == "Manufacture/Repack":
+ produced_qty = flt(pro_bean.doc.produced_qty) + \
+ (self.doc.docstatus==1 and 1 or -1 ) * flt(self.doc.fg_completed_qty)
+
+ if produced_qty > flt(pro_bean.doc.qty):
+ webnotes.throw(_("Production Order") + ": " + self.doc.production_order + "\n" +
+ _("Total Manufactured Qty can not be greater than Planned qty to manufacture")
+ + "(%s/%s)" % (produced_qty, flt(pro_bean.doc.qty)), StockOverProductionError)
+
+ status = 'Completed' if flt(produced_qty) >= flt(pro_bean.doc.qty) else 'In Process'
+ webnotes.conn.sql("""update `tabProduction Order` set status=%s, produced_qty=%s
+ where name=%s""", (status, produced_qty, self.doc.production_order))
+
+ def update_planned_qty(self, pro_bean):
+ from stock.utils import update_bin
+ update_bin({
+ "item_code": pro_bean.doc.production_item,
+ "warehouse": pro_bean.doc.fg_warehouse,
+ "posting_date": self.doc.posting_date,
+ "planned_qty": (self.doc.docstatus==1 and -1 or 1 ) * flt(self.doc.fg_completed_qty)
+ })
def get_item_details(self, arg):
arg = json.loads(arg)
@@ -415,7 +423,8 @@
return ret
def get_items(self):
- self.doclist = self.doc.clear_table(self.doclist, 'mtn_details', 1)
+ self.doclist = filter(lambda d: d.parentfield!="mtn_details", self.doclist)
+ # self.doclist = self.doc.clear_table(self.doclist, 'mtn_details')
pro_obj = None
if self.doc.production_order:
@@ -454,7 +463,7 @@
"stock_uom": pro_obj.doc.stock_uom
}
}, bom_no=pro_obj.doc.bom_no)
-
+
elif self.doc.purpose in ["Material Receipt", "Manufacture/Repack"]:
if self.doc.purpose=="Material Receipt":
self.doc.from_warehouse = ""
@@ -471,6 +480,7 @@
}, bom_no=self.doc.bom_no)
self.get_stock_and_rate()
+
def get_bom_raw_materials(self, qty):
"""
diff --git a/stock/doctype/warehouse/warehouse.py b/stock/doctype/warehouse/warehouse.py
index 58cf11b..476a6f6 100644
--- a/stock/doctype/warehouse/warehouse.py
+++ b/stock/doctype/warehouse/warehouse.py
@@ -5,7 +5,6 @@
import webnotes
from webnotes.utils import cint, flt, validate_email_add
-from webnotes.model.code import get_obj
from webnotes import msgprint, _
sql = webnotes.conn.sql
@@ -83,103 +82,15 @@
webnotes.conn.delete_doc("Account", old_warehouse_account)
+ from utilities.repost_stock import repost
for item_code in items:
- self.repost(item_code[0], self.doc.merge_with)
+ repost(item_code[0], self.doc.merge_with)
webnotes.conn.auto_commit_on_many_writes = 0
msgprint("Warehouse %s merged into %s. Now you can delete warehouse: %s"
% (self.doc.name, self.doc.merge_with, self.doc.name))
-
- def repost(self, item_code, warehouse=None):
- from stock.utils import get_bin
- self.repost_actual_qty(item_code, warehouse)
-
- bin = get_bin(item_code, warehouse)
- self.repost_reserved_qty(bin)
- self.repost_indented_qty(bin)
- self.repost_ordered_qty(bin)
- self.repost_planned_qty(bin)
- bin.doc.projected_qty = flt(bin.doc.actual_qty) + flt(bin.doc.planned_qty) \
- + flt(bin.doc.indented_qty) + flt(bin.doc.ordered_qty) - flt(bin.doc.reserved_qty)
- bin.doc.save()
-
-
- def repost_actual_qty(self, item_code, warehouse=None):
- from stock.stock_ledger import update_entries_after
- if not warehouse:
- warehouse = self.doc.name
-
- update_entries_after({ "item_code": item_code, "warehouse": warehouse })
-
- def repost_reserved_qty(self, bin):
- reserved_qty = webnotes.conn.sql("""
- select
- sum((dnpi_qty / so_item_qty) * (so_item_qty - so_item_delivered_qty))
- from
- (
- select
- qty as dnpi_qty,
- (
- select qty from `tabSales Order Item`
- where name = dnpi.parent_detail_docname
- ) as so_item_qty,
- (
- select ifnull(delivered_qty, 0) from `tabSales Order Item`
- where name = dnpi.parent_detail_docname
- ) as so_item_delivered_qty
- from
- (
- select qty, parent_detail_docname
- from `tabDelivery Note Packing Item` dnpi_in
- where item_code = %s and warehouse = %s
- and parenttype="Sales Order"
- and exists (select * from `tabSales Order` so
- where name = dnpi_in.parent and docstatus = 1 and status != 'Stopped')
- ) dnpi
- ) tab
- where
- so_item_qty >= so_item_delivered_qty
- """, (bin.doc.item_code, bin.doc.warehouse))
-
- if flt(bin.doc.reserved_qty) != flt(reserved_qty[0][0]):
- webnotes.conn.set_value("Bin", bin.doc.name, "reserved_qty", flt(reserved_qty[0][0]))
-
-
- def repost_indented_qty(self, bin):
- indented_qty = webnotes.conn.sql("""select sum(pr_item.qty - pr_item.ordered_qty)
- from `tabMaterial Request Item` pr_item, `tabMaterial Request` pr
- where pr_item.item_code=%s and pr_item.warehouse=%s
- and pr_item.qty > pr_item.ordered_qty and pr_item.parent=pr.name
- and pr.status!='Stopped' and pr.docstatus=1"""
- , (bin.doc.item_code, bin.doc.warehouse))
-
- if flt(bin.doc.indented_qty) != flt(indented_qty[0][0]):
- webnotes.conn.set_value("Bin", bin.doc.name, "indented_qty", flt(indented_qty[0][0]))
-
-
- def repost_ordered_qty(self, bin):
- ordered_qty = webnotes.conn.sql("""
- select sum((po_item.qty - po_item.received_qty)*po_item.conversion_factor)
- from `tabPurchase Order Item` po_item, `tabPurchase Order` po
- where po_item.item_code=%s and po_item.warehouse=%s
- and po_item.qty > po_item.received_qty and po_item.parent=po.name
- and po.status!='Stopped' and po.docstatus=1"""
- , (bin.doc.item_code, bin.doc.warehouse))
-
- if flt(bin.doc.ordered_qty) != flt(ordered_qty[0][0]):
- webnotes.conn.set_value("Bin", bin.doc.name, "ordered_qty", flt(ordered_qty[0][0]))
-
- def repost_planned_qty(self, bin):
- planned_qty = webnotes.conn.sql("""
- select sum(qty - produced_qty) from `tabProduction Order`
- where production_item = %s and fg_warehouse = %s and status != "Stopped"
- and docstatus=1""", (bin.doc.item_code, bin.doc.warehouse))
-
- if flt(bin.doc.planned_qty) != flt(planned_qty[0][0]):
- webnotes.conn.set_value("Bin", bin.doc.name, "planned_qty", flt(planned_qty[0][0]))
-
def on_trash(self):
# delete bin
bins = sql("select * from `tabBin` where warehouse = %s", self.doc.name, as_dict=1)
diff --git a/stock/utils.py b/stock/utils.py
index 983ee72..0f801c7 100644
--- a/stock/utils.py
+++ b/stock/utils.py
@@ -393,13 +393,4 @@
Administrator""" % ("\n\n".join(["\n".join(msg) for msg in exceptions_list]),)
from webnotes.profile import get_system_managers
- sendmail(get_system_managers(), subject=subject, msg=msg)
-
-
-def repost():
- """
- Repost everything!
- """
- from webnotes.model.code import get_obj
- for wh in webnotes.conn.sql("select name from tabWarehouse"):
- get_obj('Warehouse', wh[0]).repost_stock()
+ sendmail(get_system_managers(), subject=subject, msg=msg)
\ No newline at end of file
diff --git a/utilities/repost_stock.py b/utilities/repost_stock.py
new file mode 100644
index 0000000..b46aae6
--- /dev/null
+++ b/utilities/repost_stock.py
@@ -0,0 +1,119 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import webnotes
+
+from webnotes.utils import flt
+
+
+def repost():
+ """
+ Repost everything!
+ """
+ webnotes.conn.auto_commit_on_many_writes = 1
+
+ for d in webnotes.conn.sql("select item_code, warehouse from tabBin"):
+ repost_stock(d[0], d[1])
+
+ webnotes.conn.auto_commit_on_many_writes = 0
+
+def repost_stock(item_code, warehouse):
+ repost_actual_qty(item_code, warehouse)
+
+ if item_code and warehouse:
+ update_bin(item_code, warehouse, {
+ "reserved_qty": get_reserved_qty(item_code, warehouse),
+ "indented_qty": get_indented_qty(item_code, warehouse),
+ "ordered_qty": get_ordered_qty(item_code, warehouse),
+ "planned_qty": get_planned_qty(item_code, warehouse)
+ })
+
+def repost_actual_qty(item_code, warehouse):
+ from stock.stock_ledger import update_entries_after
+ update_entries_after({ "item_code": item_code, "warehouse": warehouse })
+
+def get_reserved_qty(item_code, warehouse):
+ reserved_qty = webnotes.conn.sql("""
+ select
+ sum((dnpi_qty / so_item_qty) * (so_item_qty - so_item_delivered_qty))
+ from
+ (
+ (select
+ qty as dnpi_qty,
+ (
+ select qty from `tabSales Order Item`
+ where name = dnpi.parent_detail_docname
+ ) as so_item_qty,
+ (
+ select ifnull(delivered_qty, 0) from `tabSales Order Item`
+ where name = dnpi.parent_detail_docname
+ ) as so_item_delivered_qty,
+ parent, name
+ from
+ (
+ select qty, parent_detail_docname, parent, name
+ from `tabDelivery Note Packing Item` dnpi_in
+ where item_code = %s and warehouse = %s
+ and parenttype="Sales Order"
+ and item_code != parent_item
+ and exists (select * from `tabSales Order` so
+ where name = dnpi_in.parent and docstatus = 1 and status != 'Stopped')
+ ) dnpi)
+ union
+ (select qty as dnpi_qty, qty as so_item_qty,
+ ifnull(delivered_qty, 0) as so_item_delivered_qty, parent, name
+ from `tabSales Order Item` so_item
+ where item_code = %s and reserved_warehouse = %s
+ and exists(select * from `tabSales Order` so
+ where so.name = so_item.parent and so.docstatus = 1
+ and so.status != 'Stopped'))
+ ) tab
+ where
+ so_item_qty >= so_item_delivered_qty
+ """, (item_code, warehouse, item_code, warehouse))
+
+ return flt(reserved_qty[0][0]) if reserved_qty else 0
+
+def get_indented_qty(item_code, warehouse):
+ indented_qty = webnotes.conn.sql("""select sum(pr_item.qty - pr_item.ordered_qty)
+ from `tabMaterial Request Item` pr_item, `tabMaterial Request` pr
+ where pr_item.item_code=%s and pr_item.warehouse=%s
+ and pr_item.qty > pr_item.ordered_qty and pr_item.parent=pr.name
+ and pr.status!='Stopped' and pr.docstatus=1""", (item_code, warehouse))
+
+ return flt(indented_qty[0][0]) if indented_qty else 0
+
+def get_ordered_qty(item_code, warehouse):
+ ordered_qty = webnotes.conn.sql("""
+ select sum((po_item.qty - po_item.received_qty)*po_item.conversion_factor)
+ from `tabPurchase Order Item` po_item, `tabPurchase Order` po
+ where po_item.item_code=%s and po_item.warehouse=%s
+ and po_item.qty > po_item.received_qty and po_item.parent=po.name
+ and po.status!='Stopped' and po.docstatus=1""", (item_code, warehouse))
+
+ return flt(ordered_qty[0][0]) if ordered_qty else 0
+
+def get_planned_qty(item_code, warehouse):
+ planned_qty = webnotes.conn.sql("""
+ select sum(qty - produced_qty) from `tabProduction Order`
+ where production_item = %s and fg_warehouse = %s and status != "Stopped"
+ and docstatus=1 and qty > produced_qty""", (item_code, warehouse))
+
+ return flt(planned_qty[0][0]) if planned_qty else 0
+
+
+def update_bin(item_code, warehouse, qty_dict=None):
+ from stock.utils import get_bin
+ bin = get_bin(item_code, warehouse)
+ mismatch = False
+ for fld, val in qty_dict.items():
+ if flt(bin.doc.fields.get(fld)) != flt(val):
+ bin.doc.fields[fld] = flt(val)
+ mismatch = True
+
+ if mismatch:
+ bin.doc.projected_qty = flt(bin.doc.actual_qty) + flt(bin.doc.ordered_qty) + \
+ flt(bin.doc.indented_qty) + flt(bin.doc.planned_qty) - flt(bin.doc.reserved_qty)
+
+ bin.doc.save()
\ No newline at end of file