I was able to achieve a simple solution for this issue.
If you also plan to try out this solution, You need to override the erpnext.item.show_single_variant_dialog
with the edited function in your custom app’s app_include_js and include some server scripts too:
Edited JS Function
erpnext.item.create_item_attribute_dialog = function (args, callback) {
Object.keys(args).map(function (key) {
args[key] = args[key].toUpperCase().trim();
if (!args[key]) delete args[key];
});
frappe.call({
method: "if_item_attribute_values_exists",
args: {
item_attributes: args
},
callback: function (r) {
console.log(r)
if (!r.message) return;
if (Object.keys(r.message).length) {
var missing_args = r.message;
let message = '';
for (let item_attribute in r.message) {
message += `<li>${item_attribute}: ${r.message[item_attribute]}</li>`
}
frappe.confirm(`The following Item Attribute Values doesn't exist, Would you like to create them?<br>
<ul>${message}</ul>`,
function () {
frappe.call({
method: "add_item_attribute_values",
args: {
item_attributes: missing_args
},
callback: function (r) {
console.log(r)
if (!r.exc) {
callback(args);
}
}
})
})
} else callback(args);
}
})
}
erpnext.item.show_single_variant_dialog = function (frm) {
var fields = []
for (var i = 0; i < frm.doc.attributes.length; i++) {
var fieldtype, desc;
var row = frm.doc.attributes[i];
if (row.numeric_values) {
fieldtype = "Float";
desc = "Min Value: " + row.from_range + " , Max Value: " + row.to_range + ", in Increments of: " + row.increment
}
else {
fieldtype = "Data";
desc = ""
}
fields = fields.concat({
"label": row.attribute,
"fieldname": row.attribute,
"fieldtype": fieldtype,
"reqd": 0,
"description": desc
})
}
var d = new frappe.ui.Dialog({
title: __('Create Variant'),
fields: fields
});
d.set_primary_action(__('Create'), function () {
var args = d.get_values();
if (!args) return;
var create_variant = (args) => {
frappe.call({
method: "erpnext.controllers.item_variant.get_variant",
btn: d.get_primary_btn(),
args: {
"template": frm.doc.name,
"args": args
},
callback: function (r) {
// returns variant item
if (r.message) {
var variant = r.message;
frappe.msgprint_dialog = frappe.msgprint(__("Item Variant {0} already exists with same attributes",
[repl('<a href="#Form/Item/%(item_encoded)s" class="strong variant-click">%(item)s</a>', {
item_encoded: encodeURIComponent(variant),
item: variant
})]
));
frappe.msgprint_dialog.hide_on_page_refresh = true;
frappe.msgprint_dialog.$wrapper.find(".variant-click").on("click", function () {
d.hide();
});
} else {
d.hide();
frappe.call({
method: "erpnext.controllers.item_variant.create_variant",
args: {
"item": frm.doc.name,
"args": args
},
callback: function (r) {
var doclist = frappe.model.sync(r.message);
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
}
});
}
}
});
}
erpnext.item.create_item_attribute_dialog(args, create_variant)
});
d.show();
$.each(d.fields_dict, function (i, field) {
if (field.df.fieldtype !== "Data") {
return;
}
$(field.input_area).addClass("ui-front");
var input = field.$input.get(0);
input.awesomplete = new Awesomplete(input, {
minChars: 0,
maxItems: 99,
autoFirst: true,
list: [],
});
input.field = field;
field.$input
.on('input', function (e) {
var term = e.target.value;
frappe.call({
method: "erpnext.stock.doctype.item.item.get_item_attribute",
args: {
parent: i,
attribute_value: term
},
callback: function (r) {
if (r.message) {
e.target.awesomplete.list = r.message.map(function (d) { return d.attribute_value; });
}
}
});
})
.on('focus', function (e) {
$(e.target).val('').trigger('input');
})
});
}
Server Scripts
API Method: if_item_attribute_values_exists
item_attributes = json.loads(frappe.form_dict.item_attributes)
non_existing_item_attributes = {}
for item_attribute in item_attributes:
item_attribute_value = item_attributes[item_attribute]
get_item_attribute_values = frappe.get_all('Item Attribute Value', filters={'parent': item_attribute}, fields=['attribute_value'])
item_attribute_value_array = []
for item_attribute_value_object in get_item_attribute_values:
item_attribute_value_array.append(item_attribute_value_object.attribute_value)
if not (item_attribute_value in item_attribute_value_array):
non_existing_item_attributes[item_attribute] = item_attribute_value
frappe.response['message'] = non_existing_item_attributes
API Method: add_item_attribute_values
item_attributes = json.loads(frappe.form_dict.item_attributes)
for item_attribute in item_attributes:
item_attribute_value = item_attributes[item_attribute]
item_attribute_doc = frappe.get_doc( "Item Attribute", item_attribute)
row = item_attribute_doc.append('item_attribute_values', {})
row.attribute_value = row.abbr = item_attribute_value.upper().strip()
item_attribute_doc.save()
If you want further details, do ask me.