[fix] Reserved and ordered qty fix for drop ship orders
This commit is contained in:
parent
a4bf02de6c
commit
2e292060c5
@ -379,6 +379,8 @@ class SalesInvoice(SellingController):
|
|||||||
msgprint(_("Item Code required at Row No {0}").format(d.idx), raise_exception=True)
|
msgprint(_("Item Code required at Row No {0}").format(d.idx), raise_exception=True)
|
||||||
|
|
||||||
def validate_warehouse(self):
|
def validate_warehouse(self):
|
||||||
|
super(SalesInvoice, self).validate_warehouse()
|
||||||
|
|
||||||
for d in self.get('items'):
|
for d in self.get('items'):
|
||||||
if not d.warehouse:
|
if not d.warehouse:
|
||||||
frappe.throw(_("Warehouse required at Row No {0}").format(d.idx))
|
frappe.throw(_("Warehouse required at Row No {0}").format(d.idx))
|
||||||
|
|||||||
@ -19,7 +19,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
|||||||
this._super();
|
this._super();
|
||||||
// this.frm.dashboard.reset();
|
// this.frm.dashboard.reset();
|
||||||
var allow_receipt = false;
|
var allow_receipt = false;
|
||||||
var allow_delivery = false;
|
var is_drop_ship = false;
|
||||||
|
|
||||||
for (var i in cur_frm.doc.items) {
|
for (var i in cur_frm.doc.items) {
|
||||||
var item = cur_frm.doc.items[i];
|
var item = cur_frm.doc.items[i];
|
||||||
@ -27,16 +27,16 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
|||||||
allow_receipt = true;
|
allow_receipt = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(item.delivered_by_supplier === 1) {
|
else {
|
||||||
allow_delivery = true
|
is_drop_ship = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if(allow_delivery && allow_receipt) {
|
if(is_drop_ship && allow_receipt) {
|
||||||
break;
|
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(doc.docstatus == 1 && !in_list(["Stopped", "Closed", "Delivered"], doc.status)) {
|
||||||
if (this.frm.has_perm("submit")) {
|
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);
|
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);
|
cur_frm.add_custom_button(__('Mark as Delivered'), this.delivered_by_supplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -138,9 +138,11 @@ class PurchaseOrder(BuyingController):
|
|||||||
"""update requested qty (before ordered_qty is updated)"""
|
"""update requested qty (before ordered_qty is updated)"""
|
||||||
item_wh_list = []
|
item_wh_list = []
|
||||||
for d in self.get("items"):
|
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 \
|
if (not po_item_rows or d.name in po_item_rows) \
|
||||||
and frappe.db.get_value("Item", d.item_code, "is_stock_item") and d.warehouse:
|
and [d.item_code, d.warehouse] not in item_wh_list \
|
||||||
item_wh_list.append([d.item_code, d.warehouse])
|
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:
|
for item_code, warehouse in item_wh_list:
|
||||||
update_bin_qty(item_code, warehouse, {
|
update_bin_qty(item_code, warehouse, {
|
||||||
@ -165,7 +167,7 @@ class PurchaseOrder(BuyingController):
|
|||||||
clear_doctype_notifications(self)
|
clear_doctype_notifications(self)
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
if self.is_drop_ship_item():
|
if self.has_drop_ship_item():
|
||||||
self.update_status_updater()
|
self.update_status_updater()
|
||||||
|
|
||||||
super(PurchaseOrder, self).on_submit()
|
super(PurchaseOrder, self).on_submit()
|
||||||
@ -182,7 +184,7 @@ class PurchaseOrder(BuyingController):
|
|||||||
purchase_controller.update_last_purchase_rate(self, is_submit = 1)
|
purchase_controller.update_last_purchase_rate(self, is_submit = 1)
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
if self.is_drop_ship_item():
|
if self.has_drop_ship_item():
|
||||||
self.update_status_updater()
|
self.update_status_updater()
|
||||||
|
|
||||||
pc_obj = frappe.get_doc('Purchase Common')
|
pc_obj = frappe.get_doc('Purchase Common')
|
||||||
@ -245,7 +247,7 @@ class PurchaseOrder(BuyingController):
|
|||||||
so.set_status(update=True)
|
so.set_status(update=True)
|
||||||
so.notify_update()
|
so.notify_update()
|
||||||
|
|
||||||
def is_drop_ship_item(self):
|
def has_drop_ship_item(self):
|
||||||
is_drop_ship = False
|
is_drop_ship = False
|
||||||
|
|
||||||
for item in self.items:
|
for item in self.items:
|
||||||
|
|||||||
@ -52,15 +52,6 @@ class BuyingController(StockController):
|
|||||||
self.supplier = supplier
|
self.supplier = supplier
|
||||||
break
|
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):
|
def validate_stock_or_nonstock_items(self):
|
||||||
if self.meta.get_field("taxes") and not self.get_stock_items():
|
if self.meta.get_field("taxes") and not self.get_stock_items():
|
||||||
tax_for_valuation = [d.account_head for d in self.get("taxes")
|
tax_for_valuation = [d.account_head for d in self.get("taxes")
|
||||||
|
|||||||
@ -303,6 +303,15 @@ class StockController(AccountsController):
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
self.make_sl_entries(sl_entries)
|
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,
|
def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None,
|
||||||
warehouse_account=None):
|
warehouse_account=None):
|
||||||
|
|||||||
@ -6,14 +6,14 @@ def execute():
|
|||||||
|
|
||||||
for item in purchase_order.items:
|
for item in purchase_order.items:
|
||||||
if item.prevdoc_doctype == "Sales Order":
|
if item.prevdoc_doctype == "Sales Order":
|
||||||
delivered_by_supplier = frappe.get_value("Sales Order Item", {"parent": item.prevdoc_docname,
|
delivered_by_supplier = frappe.get_value("Sales Order Item", item.prevdoc_detail_docname,
|
||||||
"item_code": item.item_code}, "delivered_by_supplier")
|
"delivered_by_supplier")
|
||||||
|
|
||||||
if delivered_by_supplier:
|
if delivered_by_supplier:
|
||||||
frappe.db.set_value("Purchase Order Item", item.name, "delivered_by_supplier", 1)
|
frappe.db.sql("""update `tabPurchase Order Item`
|
||||||
frappe.db.set_value("Purchase Order Item", item.name, "billed_amt", item.amount)
|
set delivered_by_supplier=1, billed_amt=amount, received_qty=qty
|
||||||
frappe.db.set_value("Purchase Order Item", item.name, "received_qty", item.qty)
|
where name=%s """, item.name)
|
||||||
|
|
||||||
update_per_received(purchase_order)
|
update_per_received(purchase_order)
|
||||||
update_per_billed(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),
|
set per_received = round((select sum(if(qty > ifnull(received_qty, 0),
|
||||||
ifnull(received_qty, 0), qty)) / sum(qty) *100
|
ifnull(received_qty, 0), qty)) / sum(qty) *100
|
||||||
from `tabPurchase Order Item`
|
from `tabPurchase Order Item`
|
||||||
where parent = "%(name)s"), 2)
|
where parent = %(name)s), 2)
|
||||||
where name = "%(name)s" """ % po.as_dict())
|
where name = %(name)s """, {"name": po.name})
|
||||||
|
|
||||||
def update_per_billed(po):
|
def update_per_billed(po):
|
||||||
frappe.db.sql(""" update `tabPurchase Order`
|
frappe.db.sql(""" update `tabPurchase Order`
|
||||||
set per_billed = round((select sum( if(amount > ifnull(billed_amt, 0),
|
set per_billed = round((select sum( if(amount > ifnull(billed_amt, 0),
|
||||||
ifnull(billed_amt, 0), amount)) / sum(amount) *100
|
ifnull(billed_amt, 0), amount)) / sum(amount) *100
|
||||||
from `tabPurchase Order Item`
|
from `tabPurchase Order Item`
|
||||||
where parent = "%(name)s"), 2)
|
where parent = %(name)s), 2)
|
||||||
where name = "%(name)s" """ % po.as_dict())
|
where name = %(name)s """, {"name": po.name})
|
||||||
|
|
||||||
|
|
||||||
@ -66,12 +66,6 @@ class SalesOrder(SellingController):
|
|||||||
for d in self.get('items'):
|
for d in self.get('items'):
|
||||||
check_list.append(cstr(d.item_code))
|
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
|
# used for production plan
|
||||||
d.transaction_date = self.transaction_date
|
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))
|
frappe.throw(_("Customer {0} does not belong to project {1}").format(self.customer, self.project_name))
|
||||||
|
|
||||||
def validate_warehouse(self):
|
def validate_warehouse(self):
|
||||||
from erpnext.stock.utils import validate_warehouse_company
|
super(SalesOrder, self).validate_warehouse()
|
||||||
|
|
||||||
warehouses = list(set([d.warehouse for d in
|
for d in self.get("items"):
|
||||||
self.get("items") if d.warehouse]))
|
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))) \
|
||||||
for w in warehouses:
|
and not d.warehouse and not cint(d.delivered_by_supplier):
|
||||||
validate_warehouse_company(w, self.company)
|
frappe.throw(_("Delivery warehouse required for stock item {0}").format(d.item_code),
|
||||||
|
WarehouseRequired)
|
||||||
|
|
||||||
def validate_with_previous_doc(self):
|
def validate_with_previous_doc(self):
|
||||||
super(SalesOrder, self).validate_with_previous_doc({
|
super(SalesOrder, self).validate_with_previous_doc({
|
||||||
"Quotation": {
|
"Quotation": {
|
||||||
@ -236,13 +231,13 @@ class SalesOrder(SellingController):
|
|||||||
item_wh_list.append([item_code, warehouse])
|
item_wh_list.append([item_code, warehouse])
|
||||||
|
|
||||||
for d in self.get("items"):
|
for d in self.get("items"):
|
||||||
if (not so_item_rows or d.name in so_item_rows):
|
if (not so_item_rows or d.name in so_item_rows) and not d.delivered_by_supplier:
|
||||||
_valid_for_reserve(d.item_code, d.warehouse)
|
|
||||||
|
|
||||||
if self.has_product_bundle(d.item_code):
|
if self.has_product_bundle(d.item_code):
|
||||||
for p in self.get("packed_items"):
|
for p in self.get("packed_items"):
|
||||||
if p.parent_detail_docname == d.name and p.parent_item == d.item_code:
|
if p.parent_detail_docname == d.name and p.parent_item == d.item_code:
|
||||||
_valid_for_reserve(p.item_code, p.warehouse)
|
_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:
|
for item_code, warehouse in item_wh_list:
|
||||||
update_bin_qty(item_code, warehouse, {
|
update_bin_qty(item_code, warehouse, {
|
||||||
|
|||||||
@ -170,6 +170,8 @@ class DeliveryNote(SellingController):
|
|||||||
chk_dupl_itm.append(f)
|
chk_dupl_itm.append(f)
|
||||||
|
|
||||||
def validate_warehouse(self):
|
def validate_warehouse(self):
|
||||||
|
super(DeliveryNote, self).validate_warehouse()
|
||||||
|
|
||||||
for d in self.get_item_list():
|
for d in self.get_item_list():
|
||||||
if frappe.db.get_value("Item", d['item_code'], "is_stock_item") == 1:
|
if frappe.db.get_value("Item", d['item_code'], "is_stock_item") == 1:
|
||||||
if not d['warehouse']:
|
if not d['warehouse']:
|
||||||
|
|||||||
@ -76,10 +76,12 @@ def get_reserved_qty(item_code, warehouse):
|
|||||||
(
|
(
|
||||||
select qty from `tabSales Order Item`
|
select qty 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_qty,
|
) as so_item_qty,
|
||||||
(
|
(
|
||||||
select ifnull(delivered_qty, 0) from `tabSales Order Item`
|
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,
|
) as so_item_delivered_qty,
|
||||||
parent, name
|
parent, name
|
||||||
from
|
from
|
||||||
@ -96,7 +98,8 @@ def get_reserved_qty(item_code, warehouse):
|
|||||||
(select qty as dnpi_qty, qty as so_item_qty,
|
(select qty as dnpi_qty, qty as so_item_qty,
|
||||||
ifnull(delivered_qty, 0) as so_item_delivered_qty, parent, name
|
ifnull(delivered_qty, 0) as so_item_delivered_qty, parent, name
|
||||||
from `tabSales Order Item` so_item
|
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
|
and exists(select * from `tabSales Order` so
|
||||||
where so.name = so_item.parent and so.docstatus = 1
|
where so.name = so_item.parent and so.docstatus = 1
|
||||||
and so.status not in ('Stopped','Closed')))
|
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
|
from `tabPurchase Order Item` po_item, `tabPurchase Order` po
|
||||||
where po_item.item_code=%s and po_item.warehouse=%s
|
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_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
|
return flt(ordered_qty[0][0]) if ordered_qty else 0
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user