def validate_item(self, item_code, row_num): from erpnext.stock.doctype.item.item import validate_end_of_life, \ validate_is_stock_item, validate_cancelled_item # using try except to catch all validation msgs and display together try: item = frappe.get_doc("Item", item_code) # end of life and stock item validate_end_of_life(item_code, item.end_of_life, item.disabled, verbose=0) validate_is_stock_item(item_code, item.is_stock_item, verbose=0) # item should not be serialized if item.has_serial_no == 1: raise frappe.ValidationError, _("Serialized Item {0} cannot be updated \ using Stock Reconciliation").format(item_code) # item managed batch-wise not allowed if item.has_batch_no == 1: raise frappe.ValidationError, _("Item: {0} managed batch-wise, can not be reconciled using \ Stock Reconciliation, instead use Stock Entry").format(item_code) # docstatus should be < 2 validate_cancelled_item(item_code, item.docstatus, verbose=0) except Exception, e: self.validation_messages.append(_("Row # ") + ("%d: " % (row_num)) + cstr(e))
def validate_item_details(args, item): if not args.company: throw(_("Please specify Company")) from erpnext.stock.doctype.item.item import validate_end_of_life validate_end_of_life(item.name, item.end_of_life) if args.transaction_type == "selling": # validate if sales item or service item if args.get("order_type") == "Maintenance": if item.is_service_item != "Yes": throw(_("Item {0} must be a Service Item.").format(item.name)) elif item.is_sales_item != "Yes": throw(_("Item {0} must be a Sales Item").format(item.name)) if cint(item.has_variants): throw(_("Item {0} is a template, please select one of its variants").format(item.name)) elif args.transaction_type == "buying" and args.parenttype != "Material Request": # validate if purchase item or subcontracted item if item.is_purchase_item != "Yes": throw(_("Item {0} must be a Purchase Item").format(item.name)) if args.get("is_subcontracted") == "Yes" and item.is_sub_contracted_item != "Yes": throw(_("Item {0} must be a Sub-contracted Item").format(item.name))
def validate_for_items(self, obj): items = [] for d in obj.get("items"): if not d.qty: frappe.throw(_("Please enter quantity for Item {0}").format(d.item_code)) # udpate with latest quantities bin = frappe.db.sql("""select projected_qty from `tabBin` where item_code = %s and warehouse = %s""", (d.item_code, d.warehouse), as_dict=1) f_lst ={'projected_qty': bin and flt(bin[0]['projected_qty']) or 0, 'ordered_qty': 0, 'received_qty' : 0} if d.doctype == 'Purchase Receipt Item': f_lst.pop('received_qty') for x in f_lst : if d.meta.get_field(x): d.set(x, f_lst[x]) item = frappe.db.sql("""select is_stock_item, is_purchase_item, is_sub_contracted_item, end_of_life from `tabItem` where name=%s""", d.item_code) from erpnext.stock.doctype.item.item import validate_end_of_life validate_end_of_life(d.item_code, item[0][3]) # validate stock item if item[0][0]=='Yes' and d.qty and not d.warehouse: frappe.throw(_("Warehouse is mandatory for stock Item {0} in row {1}").format(d.item_code, d.idx)) # validate purchase item if not (obj.doctype=="Material Request" and getattr(obj, "material_request_type", None)=="Material Transfer"): if item[0][1] != 'Yes' and item[0][2] != 'Yes': frappe.throw(_("{0} must be a Purchased or Sub-Contracted Item in row {1}").format(d.item_code, d.idx)) items.append(cstr(d.item_code)) if items and len(items) != len(set(items)): frappe.msgprint(_("Warning: Same item has been entered multiple times."))
def validate_for_items(self, obj): items = [] for d in obj.get("items"): if not d.qty: if obj.doctype == "Purchase Receipt" and d.rejected_qty: continue frappe.throw(_("Please enter quantity for Item {0}").format(d.item_code)) # udpate with latest quantities bin = frappe.db.sql("""select projected_qty from `tabBin` where item_code = %s and warehouse = %s""", (d.item_code, d.warehouse), as_dict=1) f_lst ={'projected_qty': bin and flt(bin[0]['projected_qty']) or 0, 'ordered_qty': 0, 'received_qty' : 0} if d.doctype in ('Purchase Receipt Item', 'Purchase Invoice Item'): f_lst.pop('received_qty') for x in f_lst : if d.meta.get_field(x): d.set(x, f_lst[x]) item = frappe.db.sql("""select is_stock_item, is_sub_contracted_item, end_of_life, disabled from `tabItem` where name=%s""", d.item_code, as_dict=1)[0] from erpnext.stock.doctype.item.item import validate_end_of_life validate_end_of_life(d.item_code, item.end_of_life, item.disabled) # validate stock item if item.is_stock_item==1 and d.qty and not d.warehouse: frappe.throw(_("Warehouse is mandatory for stock Item {0} in row {1}").format(d.item_code, d.idx)) items.append(cstr(d.item_code)) if items and len(items) != len(set(items)) and \ not cint(frappe.db.get_single_value("Buying Settings", "allow_multiple_items") or 0): frappe.msgprint(_("Warning: Same item has been entered multiple times."), alert=True)
def validate_production_item(self): if not frappe.db.get_value("Item", self.production_item, "is_pro_applicable"): frappe.throw(_("Item is not allowed to have Production Order."), ProductionNotApplicableError) if frappe.db.get_value("Item", self.production_item, "has_variants"): frappe.throw(_("Production Order cannot be raised against a Item Template"), ItemHasVariantError) validate_end_of_life(self.production_item)
def validate_for_items(self, obj): check_list, chk_dupl_itm=[],[] for d in obj.get(obj.fname): # validation for valid qty if flt(d.qty) < 0 or (d.parenttype != 'Purchase Receipt' and not flt(d.qty)): frappe.throw(_("Please enter quantity for Item {0}").format(d.item_code)) # udpate with latest quantities bin = frappe.db.sql("""select projected_qty from `tabBin` where item_code = %s and warehouse = %s""", (d.item_code, d.warehouse), as_dict=1) f_lst ={'projected_qty': bin and flt(bin[0]['projected_qty']) or 0, 'ordered_qty': 0, 'received_qty' : 0} if d.doctype == 'Purchase Receipt Item': f_lst.pop('received_qty') for x in f_lst : if d.meta.get_field(x): d.set(x, f_lst[x]) item = frappe.db.sql("""select is_stock_item, is_purchase_item, is_sub_contracted_item, end_of_life from `tabItem` where name=%s""", d.item_code) from erpnext.stock.doctype.item.item import validate_end_of_life validate_end_of_life(d.item_code, item[0][3]) # validate stock item if item[0][0]=='Yes' and d.qty and not d.warehouse: frappe.throw(_("Warehouse is mandatory for stock Item {0} in row {1}").format(d.item_code, d.idx)) # validate purchase item if not (obj.doctype=="Material Request" and getattr(obj, "material_request_type", None)=="Transfer"): if item[0][1] != 'Yes' and item[0][2] != 'Yes': frappe.throw(_("{0} must be a Purchased or Sub-Contracted Item in row {1}").format(d.item_code, d.idx)) # list criteria that should not repeat if item is stock item e = [getattr(d, "schedule_date", None), d.item_code, d.description, d.warehouse, d.uom, d.meta.get_field('prevdoc_docname') and d.prevdoc_docname or d.meta.get_field('sales_order_no') and d.sales_order_no or '', d.meta.get_field('prevdoc_detail_docname') and d.prevdoc_detail_docname or '', d.meta.get_field('batch_no') and d.batch_no or ''] # if is not stock item f = [getattr(d, "schedule_date", None), d.item_code, d.description] ch = frappe.db.sql("""select is_stock_item from `tabItem` where name = %s""", d.item_code) if ch and ch[0][0] == 'Yes': # check for same items if e in check_list: frappe.throw(_("Item {0} has been entered multiple times with same description or date or warehouse").format(d.item_code)) else: check_list.append(e) elif ch and ch[0][0] == 'No': # check for same items if f in chk_dupl_itm: frappe.throw(_("Item {0} has been entered multiple times with same description or date").format(d.item_code)) else: chk_dupl_itm.append(f)
def validate_item_details(args, item): if not args.company: throw(_("Please specify Company")) from erpnext.stock.doctype.item.item import validate_end_of_life validate_end_of_life(item.name, item.end_of_life, item.disabled) if args.transaction_type=="selling" and cint(item.has_variants): throw(_("Item {0} is a template, please select one of its variants").format(item.name)) elif args.transaction_type=="buying" and args.doctype != "Material Request": if args.get("is_subcontracted") == "Yes" and item.is_sub_contracted_item != 1: throw(_("Item {0} must be a Sub-contracted Item").format(item.name))
def validate_for_items(doc): items = [] for d in doc.get("items"): if not d.qty: if doc.doctype == "Purchase Receipt" and d.rejected_qty: continue if doc.doctype == "Purchase Invoice" and int( d.update_inventory) == 0 and doc.is_return: continue frappe.throw( _("Please enter quantity for Item {0}").format(d.item_code)) # update with latest quantities bin = frappe.db.sql("""select projected_qty from `tabBin` where item_code = %s and warehouse = %s""", (d.item_code, d.warehouse), as_dict=1) f_lst = { 'projected_qty': bin and flt(bin[0]['projected_qty']) or 0, 'ordered_qty': 0, 'received_qty': 0 } if d.doctype in ('Purchase Receipt Item', 'Purchase Invoice Item'): f_lst.pop('received_qty') for x in f_lst: if d.meta.get_field(x): d.set(x, f_lst[x]) item = frappe.db.sql("""select is_stock_item, is_sub_contracted_item, end_of_life, disabled from `tabItem` where name=%s""", d.item_code, as_dict=1)[0] validate_end_of_life(d.item_code, item.end_of_life, item.disabled) # validate stock item if item.is_stock_item == 1 and d.qty and not d.warehouse and not d.get( "delivered_by_supplier"): frappe.throw( _("Warehouse is mandatory for stock Item {0} in row {1}"). format(d.item_code, d.idx)) items.append(cstr(d.item_code)) if items and len(items) != len(set(items)) and \ not cint(frappe.db.get_single_value("Buying Settings", "allow_multiple_items") or 0): frappe.throw(_("Same item cannot be entered multiple times."))
def validate_item_details(args, item): if not args.company: throw(_("Please specify Company")) from erpnext.stock.doctype.item.item import validate_end_of_life validate_end_of_life(item.name, item.end_of_life, item.disabled) if args.transaction_type == "selling" and cint(item.has_variants): throw( _("Item {0} is a template, please select one of its variants"). format(item.name)) elif args.transaction_type == "buying" and args.doctype != "Material Request": if args.get("is_subcontracted" ) == "Yes" and item.is_sub_contracted_item != 1: throw( _("Item {0} must be a Sub-contracted Item").format(item.name))
def validate_for_items(doc) -> None: items = [] for d in doc.get("items"): if not d.qty: if doc.doctype == "Purchase Receipt" and d.rejected_qty: continue frappe.throw( _("Please enter quantity for Item {0}").format(d.item_code)) 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) validate_end_of_life(d.item_code, item.end_of_life, item.disabled) items.append(cstr(d.item_code)) if (items and len(items) != len(set(items)) and not cint( frappe.db.get_single_value("Buying Settings", "allow_multiple_items") or 0)): frappe.throw(_("Same item cannot be entered multiple times."))
def validate_item(self, item_code, row_num): from erpnext.stock.doctype.item.item import validate_end_of_life, \ validate_is_stock_item, validate_cancelled_item # using try except to catch all validation msgs and display together try: item = frappe.get_doc("Item", item_code) # end of life and stock item validate_end_of_life(item_code, item.end_of_life, verbose=0) validate_is_stock_item(item_code, item.is_stock_item, verbose=0) # item should not be serialized if item.has_serial_no == "Yes": raise frappe.ValidationError, _("Serialized Item {0} cannot be updated using Stock Reconciliation").format(item_code) # docstatus should be < 2 validate_cancelled_item(item_code, item.docstatus, verbose=0) except Exception, e: self.validation_messages.append(_("Row # ") + ("%d: " % (row_num)) + cstr(e))
def validate_item(self, item_code, row): from erpnext.stock.doctype.item.item import ( validate_end_of_life, validate_is_stock_item, validate_cancelled_item, ) # using try except to catch all validation msgs and display together try: item = frappe.get_doc("Item", item_code) # end of life and stock item validate_end_of_life(item_code, item.end_of_life, item.disabled, verbose=0) validate_is_stock_item(item_code, item.is_stock_item, verbose=0) # item should not be serialized if item.has_serial_no and not row.serial_no and not item.serial_no_series: raise frappe.ValidationError( frappe._("Serial no(s) required for serialized item {0}").format( item_code ) ) # item managed batch-wise not allowed if item.has_batch_no and not row.batch_no and not item.create_new_batch: raise frappe.ValidationError( frappe._("Batch no is required for batched item {0}").format( item_code ) ) # docstatus should be < 2 validate_cancelled_item(item_code, item.docstatus, verbose=0) except Exception as e: self.validation_messages.append( frappe._("Row # ") + ("%d: " % (row.idx)) + frappe.utils.cstr(e) )
def validate_item(self, item_code, row): from erpnext.stock.doctype.item.item import validate_end_of_life, \ validate_is_stock_item, validate_cancelled_item # using try except to catch all validation msgs and display together try: item = frappe.get_doc("Item", item_code) # end of life and stock item validate_end_of_life(item_code, item.end_of_life, item.disabled, verbose=0) validate_is_stock_item(item_code, item.is_stock_item, verbose=0) # item should not be serialized if item.has_serial_no and not row.serial_no and not item.serial_no_series and flt( row.qty) > 0: raise frappe.ValidationError( _("Serial no(s) required for serialized item {0}").format( item_code)) if flt(row.qty) == 0 and row.serial_no: row.serial_no = '' # item managed batch-wise not allowed if item.has_batch_no and not row.batch_no and not frappe.flags.in_test: if not item.create_new_batch or self.purpose != 'Opening Stock': raise frappe.ValidationError( _("Batch no is required for the batched item {0}"). format(item_code)) # docstatus should be < 2 validate_cancelled_item(item_code, item.docstatus, verbose=0) except Exception as e: self.validation_messages.append( _("Row # ") + ("%d: " % (row.idx)) + cstr(e))
def validate_item_details(args, item): if not args.company: throw(_("Please specify Company")) from erpnext.stock.doctype.item.item import validate_end_of_life validate_end_of_life(item.name, item.end_of_life) if args.transaction_type == "selling": # validate if sales item or service item if args.get("order_type") == "Maintenance": if item.is_service_item != "Yes": throw(_("Item {0} must be a Service Item.").format(item.name)) elif item.is_sales_item != "Yes": throw(_("Item {0} must be a Sales Item").format(item.name)) elif args.transaction_type == "buying" and args.doctype != "Material Request": # validate if purchase item or subcontracted item if item.is_purchase_item != "Yes": throw(_("Item {0} must be a Purchase Item").format(item.name)) if args.get("is_subcontracted") == "Yes" and item.is_sub_contracted_item != "Yes": throw(_("Item {0} must be a Sub-contracted Item").format(item.name))
def validate_for_items(self, obj): items = [] for d in obj.get("items"): if not d.qty: frappe.throw(_("Please enter quantity for Item {0}").format(d.item_code)) # udpate with latest quantities bin = frappe.db.sql("""select projected_qty from `tabBin` where item_code = %s and warehouse = %s""", (d.item_code, d.warehouse), as_dict=1) f_lst ={'projected_qty': bin and flt(bin[0]['projected_qty']) or 0, 'ordered_qty': 0, 'received_qty' : 0} if d.doctype == 'Purchase Receipt Item': f_lst.pop('received_qty') for x in f_lst : if d.meta.get_field(x): d.set(x, f_lst[x]) item = frappe.db.sql("""select is_stock_item, is_purchase_item, is_sub_contracted_item, end_of_life from `tabItem` where name=%s""", d.item_code, as_dict=1)[0] from erpnext.stock.doctype.item.item import validate_end_of_life validate_end_of_life(d.item_code, item.end_of_life) # validate stock item if item.is_stock_item==1 and d.qty and not d.warehouse: frappe.throw(_("Warehouse is mandatory for stock Item {0} in row {1}").format(d.item_code, d.idx)) # validate purchase item if not (obj.doctype=="Material Request" and getattr(obj, "material_request_type", None)=="Material Transfer"): if item.is_purchase_item != 1 and item.is_sub_contracted_item != 1: frappe.throw(_("{0} must be a Purchased or Sub-Contracted Item in row {1}").format(d.item_code, d.idx)) items.append(cstr(d.item_code)) if items and len(items) != len(set(items)) and \ not cint(frappe.db.get_single_value("Buying Settings", "allow_multiple_items") or 0): frappe.msgprint(_("Warning: Same item has been entered multiple times."))
def validate_production_item(self): if frappe.db.get_value("Item", self.production_item, "has_variants"): frappe.throw(_("Work Order cannot be raised against a Item Template"), ItemHasVariantError) if self.production_item: validate_end_of_life(self.production_item)
def validate_production_item(self): if frappe.db.get_value("Item", self.production_item, "has_variants"): frappe.throw(_("Production Order cannot be raised against a Item Template"), ItemHasVariantError) if self.production_item: validate_end_of_life(self.production_item)
def validate_for_items(self, obj): check_list, chk_dupl_itm = [], [] for d in obj.get("items"): # validation for valid qty if flt(d.qty) < 0 or (d.parenttype != 'Purchase Receipt' and not flt(d.qty)): frappe.throw( _("Please enter quantity for Item {0}").format( d.item_code)) # udpate with latest quantities bin = frappe.db.sql("""select projected_qty from `tabBin` where item_code = %s and warehouse = %s""", (d.item_code, d.warehouse), as_dict=1) f_lst = { 'projected_qty': bin and flt(bin[0]['projected_qty']) or 0, 'ordered_qty': 0, 'received_qty': 0 } if d.doctype == 'Purchase Receipt Item': f_lst.pop('received_qty') for x in f_lst: if d.meta.get_field(x): d.set(x, f_lst[x]) item = frappe.db.sql( """select is_stock_item, is_purchase_item, is_sub_contracted_item, end_of_life from `tabItem` where name=%s""", d.item_code) from erpnext.stock.doctype.item.item import validate_end_of_life validate_end_of_life(d.item_code, item[0][3]) # validate stock item if item[0][0] == 'Yes' and d.qty and not d.warehouse: frappe.throw( _("Warehouse is mandatory for stock Item {0} in row {1}"). format(d.item_code, d.idx)) # validate purchase item if not (obj.doctype == "Material Request" and getattr(obj, "material_request_type", None) == "Material Transfer"): if item[0][1] != 'Yes' and item[0][2] != 'Yes': frappe.throw( _("{0} must be a Purchased or Sub-Contracted Item in row {1}" ).format(d.item_code, d.idx)) # list criteria that should not repeat if item is stock item e = [ getattr(d, "schedule_date", None), d.item_code, d.description, d.warehouse, d.uom, d.meta.get_field('prevdoc_docname') and d.prevdoc_docname or d.meta.get_field('sales_order_no') and d.sales_order_no or '', d.meta.get_field('prevdoc_detail_docname') and d.prevdoc_detail_docname or '', d.meta.get_field('batch_no') and d.batch_no or '' ] # if is not stock item f = [getattr(d, "schedule_date", None), d.item_code, d.description] ch = frappe.db.sql( """select is_stock_item from `tabItem` where name = %s""", d.item_code) if ch and ch[0][0] == 'Yes': # check for same items if e in check_list: frappe.throw( _("Item {0} has been entered multiple times with same description or date or warehouse" ).format(d.item_code)) else: check_list.append(e) elif ch and ch[0][0] == 'No': # check for same items if f in chk_dupl_itm: frappe.throw( _("Item {0} has been entered multiple times with same description or date" ).format(d.item_code)) else: chk_dupl_itm.append(f)