Browse Source

[fix] Reserved and ordered qty fix for drop ship orders

develop
Saurabh 9 years ago
parent
commit
2e292060c5
  1. 2
      erpnext/accounts/doctype/sales_invoice/sales_invoice.py
  2. 12
      erpnext/buying/doctype/purchase_order/purchase_order.js
  3. 14
      erpnext/buying/doctype/purchase_order/purchase_order.py
  4. 9
      erpnext/controllers/buying_controller.py
  5. 9
      erpnext/controllers/stock_controller.py
  6. 20
      erpnext/patches/v6_8/move_drop_ship_to_po_items.py
  7. 29
      erpnext/selling/doctype/sales_order/sales_order.py
  8. 2
      erpnext/stock/doctype/delivery_note/delivery_note.py
  9. 11
      erpnext/stock/stock_balance.py

2
erpnext/accounts/doctype/sales_invoice/sales_invoice.py

@ -379,6 +379,8 @@ class SalesInvoice(SellingController):
msgprint(_("Item Code required at Row No {0}").format(d.idx), raise_exception=True)
def validate_warehouse(self):
super(SalesInvoice, self).validate_warehouse()
for d in self.get('items'):
if not d.warehouse:
frappe.throw(_("Warehouse required at Row No {0}").format(d.idx))

12
erpnext/buying/doctype/purchase_order/purchase_order.js

@ -19,7 +19,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
this._super();
// this.frm.dashboard.reset();
var allow_receipt = false;
var allow_delivery = false;
var is_drop_ship = false;
for (var i in cur_frm.doc.items) {
var item = cur_frm.doc.items[i];
@ -27,16 +27,16 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
allow_receipt = true;
}
if(item.delivered_by_supplier === 1) {
allow_delivery = true
else {
is_drop_ship = true
}
if(allow_delivery && allow_receipt) {
if(is_drop_ship && allow_receipt) {
break;
}
}
cur_frm.set_df_property("drop_ship", "hidden", !allow_delivery);
cur_frm.set_df_property("drop_ship", "hidden", !is_drop_ship);
if(doc.docstatus == 1 && !in_list(["Stopped", "Closed", "Delivered"], doc.status)) {
if (this.frm.has_perm("submit")) {
@ -47,7 +47,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
cur_frm.add_custom_button(__('Close'), this.close_purchase_order);
}
if(allow_delivery && doc.status!="Delivered"){
if(is_drop_ship && doc.status!="Delivered"){
cur_frm.add_custom_button(__('Mark as Delivered'), this.delivered_by_supplier);
}

14
erpnext/buying/doctype/purchase_order/purchase_order.py

@ -138,9 +138,11 @@ class PurchaseOrder(BuyingController):
"""update requested qty (before ordered_qty is updated)"""
item_wh_list = []
for d in self.get("items"):
if (not po_item_rows or d.name in po_item_rows) and [d.item_code, d.warehouse] not in item_wh_list \
and frappe.db.get_value("Item", d.item_code, "is_stock_item") and d.warehouse:
item_wh_list.append([d.item_code, d.warehouse])
if (not po_item_rows or d.name in po_item_rows) \
and [d.item_code, d.warehouse] not in item_wh_list \
and frappe.db.get_value("Item", d.item_code, "is_stock_item") \
and d.warehouse and not d.delivered_by_supplier:
item_wh_list.append([d.item_code, d.warehouse])
for item_code, warehouse in item_wh_list:
update_bin_qty(item_code, warehouse, {
@ -165,7 +167,7 @@ class PurchaseOrder(BuyingController):
clear_doctype_notifications(self)
def on_submit(self):
if self.is_drop_ship_item():
if self.has_drop_ship_item():
self.update_status_updater()
super(PurchaseOrder, self).on_submit()
@ -182,7 +184,7 @@ class PurchaseOrder(BuyingController):
purchase_controller.update_last_purchase_rate(self, is_submit = 1)
def on_cancel(self):
if self.is_drop_ship_item():
if self.has_drop_ship_item():
self.update_status_updater()
pc_obj = frappe.get_doc('Purchase Common')
@ -245,7 +247,7 @@ class PurchaseOrder(BuyingController):
so.set_status(update=True)
so.notify_update()
def is_drop_ship_item(self):
def has_drop_ship_item(self):
is_drop_ship = False
for item in self.items:

9
erpnext/controllers/buying_controller.py

@ -52,15 +52,6 @@ class BuyingController(StockController):
self.supplier = supplier
break
def validate_warehouse(self):
from erpnext.stock.utils import validate_warehouse_company
warehouses = list(set([d.warehouse for d in
self.get("items") if getattr(d, "warehouse", None)]))
for w in warehouses:
validate_warehouse_company(w, self.company)
def validate_stock_or_nonstock_items(self):
if self.meta.get_field("taxes") and not self.get_stock_items():
tax_for_valuation = [d.account_head for d in self.get("taxes")

9
erpnext/controllers/stock_controller.py

@ -303,6 +303,15 @@ class StockController(AccountsController):
}))
self.make_sl_entries(sl_entries)
def validate_warehouse(self):
from erpnext.stock.utils import validate_warehouse_company
warehouses = list(set([d.warehouse for d in
self.get("items") if getattr(d, "warehouse", None)]))
for w in warehouses:
validate_warehouse_company(w, self.company)
def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None,
warehouse_account=None):

20
erpnext/patches/v6_8/move_drop_ship_to_po_items.py

@ -6,14 +6,14 @@ def execute():
for item in purchase_order.items:
if item.prevdoc_doctype == "Sales Order":
delivered_by_supplier = frappe.get_value("Sales Order Item", {"parent": item.prevdoc_docname,
"item_code": item.item_code}, "delivered_by_supplier")
delivered_by_supplier = frappe.get_value("Sales Order Item", item.prevdoc_detail_docname,
"delivered_by_supplier")
if delivered_by_supplier:
frappe.db.set_value("Purchase Order Item", item.name, "delivered_by_supplier", 1)
frappe.db.set_value("Purchase Order Item", item.name, "billed_amt", item.amount)
frappe.db.set_value("Purchase Order Item", item.name, "received_qty", item.qty)
frappe.db.sql("""update `tabPurchase Order Item`
set delivered_by_supplier=1, billed_amt=amount, received_qty=qty
where name=%s """, item.name)
update_per_received(purchase_order)
update_per_billed(purchase_order)
@ -22,15 +22,15 @@ def update_per_received(po):
set per_received = round((select sum(if(qty > ifnull(received_qty, 0),
ifnull(received_qty, 0), qty)) / sum(qty) *100
from `tabPurchase Order Item`
where parent = "%(name)s"), 2)
where name = "%(name)s" """ % po.as_dict())
where parent = %(name)s), 2)
where name = %(name)s """, {"name": po.name})
def update_per_billed(po):
frappe.db.sql(""" update `tabPurchase Order`
set per_billed = round((select sum( if(amount > ifnull(billed_amt, 0),
ifnull(billed_amt, 0), amount)) / sum(amount) *100
from `tabPurchase Order Item`
where parent = "%(name)s"), 2)
where name = "%(name)s" """ % po.as_dict())
where parent = %(name)s), 2)
where name = %(name)s """, {"name": po.name})

29
erpnext/selling/doctype/sales_order/sales_order.py

@ -66,12 +66,6 @@ class SalesOrder(SellingController):
for d in self.get('items'):
check_list.append(cstr(d.item_code))
if (frappe.db.get_value("Item", d.item_code, "is_stock_item")==1 or
(self.has_product_bundle(d.item_code) and self.product_bundle_has_stock_item(d.item_code))) \
and not d.warehouse and not cint(d.delivered_by_supplier):
frappe.throw(_("Delivery warehouse required for stock item {0}").format(d.item_code),
WarehouseRequired)
# used for production plan
d.transaction_date = self.transaction_date
@ -116,14 +110,15 @@ class SalesOrder(SellingController):
frappe.throw(_("Customer {0} does not belong to project {1}").format(self.customer, self.project_name))
def validate_warehouse(self):
from erpnext.stock.utils import validate_warehouse_company
warehouses = list(set([d.warehouse for d in
self.get("items") if d.warehouse]))
for w in warehouses:
validate_warehouse_company(w, self.company)
super(SalesOrder, self).validate_warehouse()
for d in self.get("items"):
if (frappe.db.get_value("Item", d.item_code, "is_stock_item")==1 or
(self.has_product_bundle(d.item_code) and self.product_bundle_has_stock_item(d.item_code))) \
and not d.warehouse and not cint(d.delivered_by_supplier):
frappe.throw(_("Delivery warehouse required for stock item {0}").format(d.item_code),
WarehouseRequired)
def validate_with_previous_doc(self):
super(SalesOrder, self).validate_with_previous_doc({
"Quotation": {
@ -236,13 +231,13 @@ class SalesOrder(SellingController):
item_wh_list.append([item_code, warehouse])
for d in self.get("items"):
if (not so_item_rows or d.name in so_item_rows):
_valid_for_reserve(d.item_code, d.warehouse)
if (not so_item_rows or d.name in so_item_rows) and not d.delivered_by_supplier:
if self.has_product_bundle(d.item_code):
for p in self.get("packed_items"):
if p.parent_detail_docname == d.name and p.parent_item == d.item_code:
_valid_for_reserve(p.item_code, p.warehouse)
else:
_valid_for_reserve(d.item_code, d.warehouse)
for item_code, warehouse in item_wh_list:
update_bin_qty(item_code, warehouse, {

2
erpnext/stock/doctype/delivery_note/delivery_note.py

@ -170,6 +170,8 @@ class DeliveryNote(SellingController):
chk_dupl_itm.append(f)
def validate_warehouse(self):
super(DeliveryNote, self).validate_warehouse()
for d in self.get_item_list():
if frappe.db.get_value("Item", d['item_code'], "is_stock_item") == 1:
if not d['warehouse']:

11
erpnext/stock/stock_balance.py

@ -76,10 +76,12 @@ def get_reserved_qty(item_code, warehouse):
(
select qty from `tabSales Order Item`
where name = dnpi.parent_detail_docname
and (delivered_by_supplier is null or delivered_by_supplier = 0)
) as so_item_qty,
(
select ifnull(delivered_qty, 0) from `tabSales Order Item`
where name = dnpi.parent_detail_docname
where name = dnpi.parent_detail_docname
and (delivered_by_supplier is null or delivered_by_supplier = 0)
) as so_item_delivered_qty,
parent, name
from
@ -96,7 +98,8 @@ def get_reserved_qty(item_code, warehouse):
(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 warehouse = %s
where item_code = %s and warehouse = %s
and (so_item.delivered_by_supplier is null or so_item.delivered_by_supplier = 0)
and exists(select * from `tabSales Order` so
where so.name = so_item.parent and so.docstatus = 1
and so.status not in ('Stopped','Closed')))
@ -122,7 +125,9 @@ def get_ordered_qty(item_code, warehouse):
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 not in ('Stopped', 'Closed', 'Delivered') and po.docstatus=1""", (item_code, warehouse))
and po.status not in ('Stopped', 'Closed', 'Delivered') and po.docstatus=1
and (po_item.delivered_by_supplier is null or po_item.delivered_by_supplier = 0)
""", (item_code, warehouse))
return flt(ordered_qty[0][0]) if ordered_qty else 0

Loading…
Cancel
Save