diff --git a/erpnext/controllers/item_variant.py b/erpnext/controllers/item_variant.py index e7908f7675e2b5740d85888e59f0a6751789f363..637fabbefbdbfc0dc52d82e7324625e8cb76ec5e 100644 --- a/erpnext/controllers/item_variant.py +++ b/erpnext/controllers/item_variant.py @@ -41,7 +41,8 @@ def get_variant(template, args=None, variant=None, manufacturer=None, manufactur if isinstance(args, str): args = json.loads(args) - if not args: + attribute_args = {k: v for k, v in args.items() if k != "use_template_image"} + if not attribute_args: frappe.throw(_("Please specify at least one attribute in the Attributes table")) return find_variant(template, args, variant) @@ -64,9 +65,7 @@ def make_variant_based_on_manufacturer(template, manufacturer, manufacturer_part variant.flags.ignore_mandatory = True variant.save() - if not frappe.db.exists( - "Item Manufacturer", {"item_code": variant.name, "manufacturer": manufacturer} - ): + if not frappe.db.exists("Item Manufacturer", {"item_code": variant.name, "manufacturer": manufacturer}): manufacturer_doc = frappe.new_doc("Item Manufacturer") manufacturer_doc.update( { @@ -130,9 +129,7 @@ def validate_is_incremental(numeric_attribute, attribute, value, item): ) -def validate_item_attribute_value( - attributes_list, attribute, attribute_value, item, from_variant=True -): +def validate_item_attribute_value(attributes_list, attribute, attribute_value, item, from_variant=True): allow_rename_attribute_value = frappe.db.get_single_value( "Item Variant Settings", "allow_rename_attribute_value" ) @@ -179,9 +176,7 @@ def get_attribute_values(item): def find_variant(template, args, variant_item_code=None): - possible_variants = [ - i for i in get_item_codes_by_attributes(args, template) if i != variant_item_code - ] + possible_variants = [i for i in get_item_codes_by_attributes(args, template) if i != variant_item_code] for variant in possible_variants: variant = frappe.get_doc("Item", variant) @@ -203,7 +198,8 @@ def find_variant(template, args, variant_item_code=None): @frappe.whitelist() -def create_variant(item, args): +def create_variant(item, args, use_template_image=False): + use_template_image = frappe.parse_json(use_template_image) if isinstance(args, str): args = json.loads(args) @@ -217,13 +213,18 @@ def create_variant(item, args): variant.set("attributes", variant_attributes) copy_attributes_to_variant(template, variant) + + if use_template_image and template.image: + variant.image = template.image + make_variant_item_code(template.item_code, template.item_name, variant) return variant @frappe.whitelist() -def enqueue_multiple_variant_creation(item, args): +def enqueue_multiple_variant_creation(item, args, use_template_image=False): + use_template_image = frappe.parse_json(use_template_image) # There can be innumerable attribute combinations, enqueue if isinstance(args, str): variants = json.loads(args) @@ -234,32 +235,33 @@ def enqueue_multiple_variant_creation(item, args): frappe.throw(_("Please do not create more than 500 items at a time")) return if total_variants < 10: - return create_multiple_variants(item, args) + return create_multiple_variants(item, args, use_template_image) else: frappe.enqueue( "erpnext.controllers.item_variant.create_multiple_variants", item=item, args=args, + use_template_image=use_template_image, now=frappe.flags.in_test, ) return "queued" -def create_multiple_variants(item, args): +def create_multiple_variants(item, args, use_template_image=False): count = 0 if isinstance(args, str): args = json.loads(args) + template_item = frappe.get_doc("Item", item) args_set = generate_keyed_value_combinations(args) for attribute_values in args_set: if not get_variant(item, args=attribute_values): variant = create_variant(item, attribute_values) - try: - variant.save() - count += 1 - except frappe.exceptions.DuplicateEntryError: - continue + if use_template_image and template_item.image: + variant.image = template_item.image + variant.save() + count += 1 return count @@ -360,7 +362,9 @@ def copy_attributes_to_variant(item, variant): if variant.attributes: attributes_description = item.description + " " for d in variant.attributes: - attributes_description += "
" + d.attribute + ": " + cstr(d.attribute_value) + "
" + attributes_description += ( + "
" + d.attribute + ": " + cstr(d.attribute_value) + "
" + ) if attributes_description not in variant.description: variant.description = attributes_description diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index 8a78a7b012e5f0dd4ca6a4783d47f498a23cf4ed..1862258d295673834b2d319cb56d8070f1e8afd8 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -616,25 +616,37 @@ $.extend(erpnext.item, { me.multiple_variant_dialog = new frappe.ui.Dialog({ title: __("Select Attribute Values"), fields: [ + frm.doc.image + ? { + fieldtype: "Check", + label: __("Create a variant with the template image."), + fieldname: "use_template_image", + default: 0, + } + : null, { fieldtype: "HTML", fieldname: "help", options: ``, - } - ].concat(fields) + }, + ] + .concat(fields) + .filter(Boolean), }); me.multiple_variant_dialog.set_primary_action(__('Create Variants'), () => { let selected_attributes = get_selected_attributes(); + let use_template_image = me.multiple_variant_dialog.get_value("use_template_image"); me.multiple_variant_dialog.hide(); frappe.call({ method: "erpnext.controllers.item_variant.enqueue_multiple_variant_creation", args: { - "item": frm.doc.name, - "args": selected_attributes + item: frm.doc.name, + args: selected_attributes, + use_template_image: use_template_image, }, callback: function(r) { if (r.message==='queued') { @@ -741,6 +753,15 @@ $.extend(erpnext.item, { }) } + if (frm.doc.image) { + fields.push({ + fieldtype: "Check", + label: __("Create a variant with the template image."), + fieldname: "use_template_image", + default: 0, + }); + } + var d = new frappe.ui.Dialog({ title: __('Create Variant'), fields: fields @@ -775,8 +796,9 @@ $.extend(erpnext.item, { frappe.call({ method: "erpnext.controllers.item_variant.create_variant", args: { - "item": frm.doc.name, - "args": d.get_values() + item: frm.doc.name, + args: d.get_values(), + use_template_image: args.use_template_image, }, callback: function(r) { var doclist = frappe.model.sync(r.message);