This commit is contained in:
pawan 2017-11-24 11:21:47 +05:30
parent 834541a7e8
commit f5279a0d67
8 changed files with 100 additions and 6 deletions

View File

@ -13,7 +13,7 @@ from erpnext.stock.stock_balance import update_bin_qty, get_ordered_qty
from frappe.desk.notifications import clear_doctype_notifications
from erpnext.buying.utils import (validate_for_items, check_for_closed_status,
update_last_purchase_rate)
from erpnext.stock.utils import get_bin
form_grid_templates = {
"items": "templates/form_grid/item_grid.html"
@ -187,6 +187,8 @@ class PurchaseOrder(BuyingController):
self.update_prevdoc_status()
self.update_requested_qty()
self.update_ordered_qty()
if self.is_subcontracted == "Yes":
self.update_reserved_qty_for_subcontract()
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
self.company, self.base_grand_total)
@ -249,6 +251,17 @@ class PurchaseOrder(BuyingController):
if item.delivered_by_supplier == 1:
item.received_qty = item.qty
def update_reserved_qty_for_subcontract(self):
items = list(set([d.rm_item_code for d in self.get("supplied_items")]))
item_wh = frappe._dict(frappe.db.sql("""select item_code, default_warehouse
from `tabItem` where name in ({0})""".format(", ".join(["%s"] * len(items))), items))
for d in self.supplied_items:
if d.rm_item_code:
warehouse = item_wh.get(d.rm_item_code)
stock_bin = get_bin(d.rm_item_code, warehouse)
stock_bin.update_reserved_qty_for_sub_contracting(self.name, transferred_qty=0, transaction_type = "Reserve")
@frappe.whitelist()
def close_or_unclose_purchase_orders(names, status):
if not frappe.has_permission("Purchase Order", "write"):

View File

@ -89,7 +89,7 @@ erpnext.stock.ItemDashboard = Class.extend({
data.forEach(function(d) {
d.actual_or_pending = d.projected_qty + d.reserved_qty + d.reserved_qty_for_production;
d.pending_qty = 0;
d.total_reserved = d.reserved_qty + d.reserved_qty_for_production;
d.total_reserved = d.reserved_qty + d.reserved_qty_for_production + d.reserved_qty_for_sub_contract;
if(d.actual_or_pending > d.actual_qty) {
d.pending_qty = d.actual_or_pending - d.actual_qty;
}

View File

@ -26,13 +26,14 @@ def get_data(item_code=None, warehouse=None, item_group=None,
return frappe.db.sql('''
select
b.item_code, b.warehouse, b.projected_qty, b.reserved_qty,
b.reserved_qty_for_production, b.actual_qty, b.valuation_rate, i.item_name
b.reserved_qty_for_production, b.reserved_qty_for_sub_contract, b.actual_qty, b.valuation_rate, i.item_name
from
tabBin b, tabItem i
where
b.item_code = i.name
and
(b.projected_qty != 0 or b.reserved_qty != 0 or b.reserved_qty_for_production != 0 or b.actual_qty != 0)
(b.projected_qty != 0 or b.reserved_qty != 0 or b.reserved_qty_for_production != 0
or b.reserved_qty_for_sub_contract != 0 or b.actual_qty != 0)
{conditions}
order by
{sort_by} {sort_order}

View File

@ -296,6 +296,36 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "reserved_qty_for_sub_contract",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Reserved Qty for sub contract",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@ -463,7 +493,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-06-13 13:06:32.601505",
"modified": "2017-11-22 08:14:30.615638",
"modified_by": "Administrator",
"module": "Stock",
"name": "Bin",

View File

@ -94,6 +94,28 @@ class Bin(Document):
self.db_set('reserved_qty_for_production', self.reserved_qty_for_production)
self.db_set('projected_qty', self.projected_qty)
def update_reserved_qty_for_sub_contracting(self, po_name, transferred_qty, transaction_type):
#Update Reserved Quantity for Sub Contracting in Bin
if transaction_type == "Reserve":
required_qty = frappe.db.sql('''select sum(itemsup.required_qty)
from `tabItem` item, `tabPurchase Order` po, `tabPurchase Order Item Supplied` itemsup
where
item.name = itemsup.rm_item_code
and po.name = %s
and itemsup.rm_item_code = %s
and itemsup.parent = po.name
and po.docstatus = 1
and po.is_subcontracted = 'Yes'
and item.default_warehouse = %s''', (po_name, self.item_code, self.warehouse))[0][0]
elif transaction_type == "Transfer":
required_qty = 0
reserved_qty_bin = self.reserved_qty_for_sub_contract
reserved_qty_for_sub_contract = reserved_qty_bin + required_qty - transferred_qty
self.set_projected_qty()
self.db_set('reserved_qty_for_sub_contract', reserved_qty_for_sub_contract)
self.db_set('projected_qty', self.projected_qty)
def update_item_projected_qty(item_code):
'''Set total_projected_qty in Item as sum of projected qty in all warehouses'''

View File

@ -11,6 +11,7 @@ from erpnext.stock.stock_ledger import get_previous_sle, NegativeStockError
from erpnext.stock.get_item_details import get_bin_details, get_default_cost_center, get_conversion_factor
from erpnext.stock.doctype.batch.batch import get_batch_no, set_batch_nos
from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
from erpnext.stock.utils import get_bin
import json
class IncorrectValuationRateError(frappe.ValidationError): pass
@ -64,6 +65,8 @@ class StockEntry(StockController):
update_serial_nos_after_submit(self, "items")
self.update_production_order()
self.validate_purchase_order()
if self.purchase_order and self.purpose == "Subcontract":
self.update_purchase_order_supplied_items()
self.make_gl_entries()
def on_cancel(self):
@ -803,6 +806,30 @@ class StockEntry(StockController):
if getdate(self.posting_date) > getdate(expiry_date):
frappe.throw(_("Batch {0} of Item {1} has expired.").format(item.batch_no, item.item_code))
def update_purchase_order_supplied_items(self):
materials_transferred = frappe._dict(frappe.db.sql("""
select
concat(item_code, sed.s_warehouse), sum(qty)
from
`tabStock Entry` se, `tabStock Entry Detail` sed
where
se.name = sed.parent and se.docstatus=1 and se.purpose='Subcontract'
and se.purchase_order= %s and ifnull(sed.s_warehouse, '') != ''
group by sed.item_code, sed.s_warehouse
""", self.purchase_order))
#Get PO Supplied Items Details
po_doc = frappe.get_doc("Purchase Order",self.purchase_order)
po_supplied_items = po_doc.get("supplied_items")
items = list(set([d.rm_item_code for d in po_supplied_items]))
item_wh = frappe._dict(frappe.db.sql("""select item_code as "item_code", default_warehouse as "warehouse"
from tabItem where name in ({0})""".format(", ".join(["%s"] * len(items))), items))
#Update reserved sub contracted quantity in bin based on Supplied Item Details
for d in po_supplied_items:
warehouse = item_wh.get(d.rm_item_code)
transferred_qty = materials_transferred.get(d.rm_item_code + warehouse)
stock_bin = get_bin(d.rm_item_code, warehouse)
stock_bin.update_reserved_qty_for_sub_contracting(self.purchase_order, transferred_qty, transaction_type = "Transfer")
@frappe.whitelist()
def get_production_order_details(production_order):
production_order = frappe.get_doc("Production Order", production_order)

View File

@ -48,6 +48,7 @@ frappe.pages['stock-balance'].on_page_load = function(wrapper) {
{fieldname: 'projected_qty', label: __('Projected qty')},
{fieldname: 'reserved_qty', label: __('Reserved for sale')},
{fieldname: 'reserved_qty_for_production', label: __('Reserved for manufacturing')},
{fieldname: 'reserved_qty_for_sub_contract', label: __('Reserved for sub contracting')},
{fieldname: 'actual_qty', label: __('Actual qty in stock')},
]
},

View File

@ -150,7 +150,7 @@ def update_bin_qty(item_code, warehouse, qty_dict=None):
if mismatch:
bin.projected_qty = (flt(bin.actual_qty) + flt(bin.ordered_qty) +
flt(bin.indented_qty) + flt(bin.planned_qty) - flt(bin.reserved_qty)
- flt(bin.reserved_qty_for_production))
- flt(bin.reserved_qty_for_production)) - flt(bin.reserved_qty_for_sub_contract)
bin.save()