mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-14 18:51:21 +00:00
fix: Duplicate items check in sales Invoice (#18662)
* fix: Duplicate items check in sales Invoice * fix: Commonified function for duplicate items check in selling controller * fix: Set valuation rate and transaction date in child tabel * fix: Code cleanup
This commit is contained in:
@@ -45,6 +45,7 @@ class SellingController(StockController):
|
|||||||
self.set_gross_profit()
|
self.set_gross_profit()
|
||||||
set_default_income_account_for_item(self)
|
set_default_income_account_for_item(self)
|
||||||
self.set_customer_address()
|
self.set_customer_address()
|
||||||
|
self.validate_for_duplicate_items()
|
||||||
|
|
||||||
def set_missing_values(self, for_validate=False):
|
def set_missing_values(self, for_validate=False):
|
||||||
|
|
||||||
@@ -381,6 +382,34 @@ class SellingController(StockController):
|
|||||||
if self.get(address_field):
|
if self.get(address_field):
|
||||||
self.set(address_display_field, get_address_display(self.get(address_field)))
|
self.set(address_display_field, get_address_display(self.get(address_field)))
|
||||||
|
|
||||||
|
def validate_for_duplicate_items(self):
|
||||||
|
check_list, chk_dupl_itm = [], []
|
||||||
|
if cint(frappe.db.get_single_value("Selling Settings", "allow_multiple_items")):
|
||||||
|
return
|
||||||
|
|
||||||
|
for d in self.get('items'):
|
||||||
|
if self.doctype == "Sales Invoice":
|
||||||
|
e = [d.item_code, d.description, d.warehouse, d.sales_order or d.delivery_note, d.batch_no or '']
|
||||||
|
f = [d.item_code, d.description, d.sales_order or d.delivery_note]
|
||||||
|
elif self.doctype == "Delivery Note":
|
||||||
|
e = [d.item_code, d.description, d.warehouse, d.against_sales_order or d.against_sales_invoice, d.batch_no or '']
|
||||||
|
f = [d.item_code, d.description, d.against_sales_order or d.against_sales_invoice]
|
||||||
|
elif self.doctype == "Sales Order":
|
||||||
|
e = [d.item_code, d.description, d.warehouse, d.batch_no or '']
|
||||||
|
f = [d.item_code, d.description]
|
||||||
|
|
||||||
|
if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1:
|
||||||
|
if e in check_list:
|
||||||
|
frappe.throw(_("Note: Item {0} entered multiple times").format(d.item_code))
|
||||||
|
else:
|
||||||
|
check_list.append(e)
|
||||||
|
else:
|
||||||
|
if f in chk_dupl_itm:
|
||||||
|
frappe.throw(_("Note: Item {0} entered multiple times").format(d.item_code))
|
||||||
|
else:
|
||||||
|
chk_dupl_itm.append(f)
|
||||||
|
|
||||||
|
|
||||||
def validate_items(self):
|
def validate_items(self):
|
||||||
# validate items to see if they have is_sales_item enabled
|
# validate items to see if they have is_sales_item enabled
|
||||||
from erpnext.controllers.buying_controller import validate_item_type
|
from erpnext.controllers.buying_controller import validate_item_type
|
||||||
|
|||||||
@@ -69,9 +69,7 @@ class SalesOrder(SellingController):
|
|||||||
frappe.msgprint(_("Warning: Sales Order {0} already exists against Customer's Purchase Order {1}").format(so[0][0], self.po_no))
|
frappe.msgprint(_("Warning: Sales Order {0} already exists against Customer's Purchase Order {1}").format(so[0][0], self.po_no))
|
||||||
|
|
||||||
def validate_for_items(self):
|
def validate_for_items(self):
|
||||||
check_list = []
|
|
||||||
for d in self.get('items'):
|
for d in self.get('items'):
|
||||||
check_list.append(cstr(d.item_code))
|
|
||||||
|
|
||||||
# used for production plan
|
# used for production plan
|
||||||
d.transaction_date = self.transaction_date
|
d.transaction_date = self.transaction_date
|
||||||
@@ -80,13 +78,6 @@ class SalesOrder(SellingController):
|
|||||||
where item_code = %s and warehouse = %s", (d.item_code, d.warehouse))
|
where item_code = %s and warehouse = %s", (d.item_code, d.warehouse))
|
||||||
d.projected_qty = tot_avail_qty and flt(tot_avail_qty[0][0]) or 0
|
d.projected_qty = tot_avail_qty and flt(tot_avail_qty[0][0]) or 0
|
||||||
|
|
||||||
# check for same entry multiple times
|
|
||||||
unique_chk_list = set(check_list)
|
|
||||||
if len(unique_chk_list) != len(check_list) and \
|
|
||||||
not cint(frappe.db.get_single_value("Selling Settings", "allow_multiple_items")):
|
|
||||||
frappe.msgprint(_("Same item has been entered multiple times"),
|
|
||||||
title=_("Warning"), indicator='orange')
|
|
||||||
|
|
||||||
def product_bundle_has_stock_item(self, product_bundle):
|
def product_bundle_has_stock_item(self, product_bundle):
|
||||||
"""Returns true if product bundle has stock item"""
|
"""Returns true if product bundle has stock item"""
|
||||||
ret = len(frappe.db.sql("""select i.name from tabItem i, `tabProduct Bundle Item` pbi
|
ret = len(frappe.db.sql("""select i.name from tabItem i, `tabProduct Bundle Item` pbi
|
||||||
|
|||||||
@@ -111,7 +111,6 @@ class DeliveryNote(SellingController):
|
|||||||
self.so_required()
|
self.so_required()
|
||||||
self.validate_proj_cust()
|
self.validate_proj_cust()
|
||||||
self.check_close_sales_order("against_sales_order")
|
self.check_close_sales_order("against_sales_order")
|
||||||
self.validate_for_items()
|
|
||||||
self.validate_warehouse()
|
self.validate_warehouse()
|
||||||
self.validate_uom_is_integer("stock_uom", "stock_qty")
|
self.validate_uom_is_integer("stock_uom", "stock_qty")
|
||||||
self.validate_uom_is_integer("uom", "qty")
|
self.validate_uom_is_integer("uom", "qty")
|
||||||
@@ -165,25 +164,6 @@ class DeliveryNote(SellingController):
|
|||||||
if not res:
|
if not res:
|
||||||
frappe.throw(_("Customer {0} does not belong to project {1}").format(self.customer, self.project))
|
frappe.throw(_("Customer {0} does not belong to project {1}").format(self.customer, self.project))
|
||||||
|
|
||||||
def validate_for_items(self):
|
|
||||||
check_list, chk_dupl_itm = [], []
|
|
||||||
if cint(frappe.db.get_single_value("Selling Settings", "allow_multiple_items")):
|
|
||||||
return
|
|
||||||
|
|
||||||
for d in self.get('items'):
|
|
||||||
e = [d.item_code, d.description, d.warehouse, d.against_sales_order or d.against_sales_invoice, d.batch_no or '']
|
|
||||||
f = [d.item_code, d.description, d.against_sales_order or d.against_sales_invoice]
|
|
||||||
|
|
||||||
if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1:
|
|
||||||
if e in check_list:
|
|
||||||
frappe.msgprint(_("Note: Item {0} entered multiple times").format(d.item_code))
|
|
||||||
else:
|
|
||||||
check_list.append(e)
|
|
||||||
else:
|
|
||||||
if f in chk_dupl_itm:
|
|
||||||
frappe.msgprint(_("Note: Item {0} entered multiple times").format(d.item_code))
|
|
||||||
else:
|
|
||||||
chk_dupl_itm.append(f)
|
|
||||||
|
|
||||||
def validate_warehouse(self):
|
def validate_warehouse(self):
|
||||||
super(DeliveryNote, self).validate_warehouse()
|
super(DeliveryNote, self).validate_warehouse()
|
||||||
|
|||||||
Reference in New Issue
Block a user