diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py index bef41394742..c09e89c9c58 100644 --- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py +++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py @@ -64,6 +64,7 @@ class RequestforQuotation(BuyingController): def validate(self): self.validate_duplicate_supplier() self.validate_supplier_list() + super(RequestforQuotation, self).validate_qty_is_not_zero() validate_for_items(self) super().set_qty_as_per_stock_uom() self.update_email_id() diff --git a/erpnext/buying/utils.py b/erpnext/buying/utils.py index d0bf22fde17..259c262d0d7 100644 --- a/erpnext/buying/utils.py +++ b/erpnext/buying/utils.py @@ -44,16 +44,8 @@ def update_last_purchase_rate(doc, is_submit) -> None: def validate_for_items(doc) -> None: - from erpnext.controllers.accounts_controller import InvalidQtyError - items = [] for d in doc.get("items"): - if not d.qty: - if doc.doctype == "Purchase Receipt" and d.rejected_qty: - continue - message = _("Please enter quantity for Item {0}").format(d.item_code) - frappe.throw(message, InvalidQtyError) - set_stock_levels(row=d) # update with latest quantities item = validate_item_and_get_basic_data(row=d) validate_stock_item_warehouse(row=d, item=item) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 247fd5d009b..9e1a05d66a5 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -1252,13 +1252,15 @@ class AccountsController(TransactionBase): ) def validate_qty_is_not_zero(self): - if self.doctype == "Purchase Receipt": - return - for item in self.items: + if self.doctype == "Purchase Receipt" and item.rejected_qty: + continue + if not flt(item.qty): frappe.throw( - msg=_("Row #{0}: Item quantity cannot be zero").format(item.idx), + msg=_("Row #{0}: Quantity for Item {1} cannot be zero.").format( + item.idx, frappe.bold(item.item_code) + ), title=_("Invalid Quantity"), exc=InvalidQtyError, ) @@ -3589,7 +3591,7 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil def validate_quantity(child_item, new_data): if not flt(new_data.get("qty")): frappe.throw( - _("Row # {0}: Quantity for Item {1} cannot be zero").format( + _("Row #{0}: Quantity for Item {1} cannot be zero.").format( new_data.get("idx"), frappe.bold(new_data.get("item_code")) ), title=_("Invalid Qty"), diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index e16f74f3706..26ac65589f1 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -7,7 +7,7 @@ from frappe import _, bold, throw from frappe.utils import cint, flt, get_link_to_form, nowtime from erpnext.accounts.party import render_address -from erpnext.controllers.accounts_controller import InvalidQtyError, get_taxes_and_charges +from erpnext.controllers.accounts_controller import get_taxes_and_charges from erpnext.controllers.sales_and_purchase_return import get_rate_for_return from erpnext.controllers.stock_controller import StockController from erpnext.stock.doctype.item.item import set_item_default @@ -316,10 +316,6 @@ class SellingController(StockController): def get_item_list(self): il = [] for d in self.get("items"): - if d.qty is None: - message = _("Row {0}: Qty is mandatory").format(d.idx) - frappe.throw(message, InvalidQtyError) - 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: diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index b6bd22f7931..a2bca1fb8d7 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -24,10 +24,13 @@ from frappe.utils import ( import erpnext from erpnext.accounts.general_ledger import process_gl_map <<<<<<< HEAD +<<<<<<< HEAD from erpnext.buying.utils import check_on_hold_or_closed_status ======= from erpnext.controllers.accounts_controller import InvalidQtyError >>>>>>> b2d8a44199 (test: Add, expand and refine test-cases for zero-quantity transactions.) +======= +>>>>>>> 4918aeb4c6 (refactor: Consolidate duplicate zero-quantity transaction Items checks.) from erpnext.controllers.taxes_and_totals import init_landed_taxes_and_totals from erpnext.manufacturing.doctype.bom.bom import ( add_additional_cost, @@ -369,10 +372,8 @@ class StockEntry(StockController): frappe.delete_doc("Stock Entry", d.name) def set_transfer_qty(self): + self.validate_qty_is_not_zero() for item in self.get("items"): - if not flt(item.qty): - message = _("Row {0}: Qty is mandatory").format(item.idx) - frappe.throw(message, InvalidQtyError, title=_("Zero quantity")) if not flt(item.conversion_factor): frappe.throw(_("Row {0}: UOM Conversion Factor is mandatory").format(item.idx)) item.transfer_qty = flt(