| # 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 - ifnull(pr_item.ordered_qty, 0)) |
| from `tabMaterial Request Item` pr_item, `tabMaterial Request` pr |
| where pr_item.item_code=%s and pr_item.warehouse=%s |
| and pr_item.qty > ifnull(pr_item.ordered_qty, 0) 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 - ifnull(po_item.received_qty, 0))*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 > ifnull(po_item.received_qty, 0) 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(ifnull(qty, 0) - ifnull(produced_qty, 0)) from `tabProduction Order` |
| where production_item = %s and fg_warehouse = %s and status != "Stopped" |
| and docstatus=1 and ifnull(qty, 0) > ifnull(produced_qty, 0)""", (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() |