[fix] Reserved and ordered qty fix for drop ship orders
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 6abf1ba..b9dfec8 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -379,6 +379,8 @@
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))
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index 3700d96..74936da 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -19,7 +19,7 @@
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 @@
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 @@
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);
}
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 74fe371..4670e35 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -138,9 +138,11 @@
"""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 @@
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 @@
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 @@
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:
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 5ccf29d..69561e1 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -52,15 +52,6 @@
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")
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 2a9fa17..5deb839 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -303,6 +303,15 @@
}))
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):
diff --git a/erpnext/patches/v6_8/move_drop_ship_to_po_items.py b/erpnext/patches/v6_8/move_drop_ship_to_po_items.py
index 8163e8f..44ba3f0 100644
--- a/erpnext/patches/v6_8/move_drop_ship_to_po_items.py
+++ b/erpnext/patches/v6_8/move_drop_ship_to_po_items.py
@@ -6,14 +6,14 @@
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 @@
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})
\ No newline at end of file
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 5ceeea8..d2b1653 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -66,12 +66,6 @@
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 @@
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 @@
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, {
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 60cc430..d653250 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -170,6 +170,8 @@
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']:
diff --git a/erpnext/stock/stock_balance.py b/erpnext/stock/stock_balance.py
index 609c986..87e7fcd 100644
--- a/erpnext/stock/stock_balance.py
+++ b/erpnext/stock/stock_balance.py
@@ -76,10 +76,12 @@
(
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 @@
(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 @@
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