mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-28 09:24:45 +00:00
Merge pull request #55289 from frappe/mergify/bp/version-16-hotfix/pr-55286
fix: single variant creation error (backport #55286)
This commit is contained in:
@@ -209,7 +209,9 @@ def create_variant(item, args, use_template_image=False):
|
|||||||
variant_attributes = []
|
variant_attributes = []
|
||||||
|
|
||||||
for d in template.attributes:
|
for d in template.attributes:
|
||||||
variant_attributes.append({"attribute": d.attribute, "attribute_value": args.get(_(d.attribute))})
|
attribute_value = args.get(_(d.attribute)) or args.get(d.attribute)
|
||||||
|
if attribute_value:
|
||||||
|
variant_attributes.append({"attribute": d.attribute, "attribute_value": attribute_value})
|
||||||
|
|
||||||
variant.set("attributes", variant_attributes)
|
variant.set("attributes", variant_attributes)
|
||||||
copy_attributes_to_variant(template, variant)
|
copy_attributes_to_variant(template, variant)
|
||||||
@@ -228,6 +230,12 @@ def enqueue_multiple_variant_creation(item, args, use_template_image=False):
|
|||||||
# There can be innumerable attribute combinations, enqueue
|
# There can be innumerable attribute combinations, enqueue
|
||||||
if isinstance(args, str):
|
if isinstance(args, str):
|
||||||
variants = json.loads(args)
|
variants = json.loads(args)
|
||||||
|
else:
|
||||||
|
variants = args
|
||||||
|
variants = {key: values for key, values in variants.items() if values}
|
||||||
|
if not variants:
|
||||||
|
frappe.throw(_("Please select at least one attribute value"))
|
||||||
|
|
||||||
total_variants = 1
|
total_variants = 1
|
||||||
for key in variants:
|
for key in variants:
|
||||||
total_variants *= len(variants[key])
|
total_variants *= len(variants[key])
|
||||||
@@ -251,6 +259,7 @@ def create_multiple_variants(item, args, use_template_image=False):
|
|||||||
count = 0
|
count = 0
|
||||||
if isinstance(args, str):
|
if isinstance(args, str):
|
||||||
args = json.loads(args)
|
args = json.loads(args)
|
||||||
|
args = {key: values for key, values in args.items() if values}
|
||||||
|
|
||||||
template_item = frappe.get_doc("Item", item)
|
template_item = frappe.get_doc("Item", item)
|
||||||
args_set = generate_keyed_value_combinations(args)
|
args_set = generate_keyed_value_combinations(args)
|
||||||
@@ -285,6 +294,9 @@ def generate_keyed_value_combinations(args):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
# Return empty list if empty
|
# Return empty list if empty
|
||||||
|
if not args:
|
||||||
|
return []
|
||||||
|
args = {key: values for key, values in args.items() if values}
|
||||||
if not args:
|
if not args:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,11 @@ import unittest
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
|
||||||
from erpnext.controllers.item_variant import copy_attributes_to_variant, make_variant_item_code
|
from erpnext.controllers.item_variant import (
|
||||||
|
copy_attributes_to_variant,
|
||||||
|
generate_keyed_value_combinations,
|
||||||
|
make_variant_item_code,
|
||||||
|
)
|
||||||
from erpnext.stock.doctype.item.test_item import set_item_variant_settings
|
from erpnext.stock.doctype.item.test_item import set_item_variant_settings
|
||||||
from erpnext.stock.doctype.quality_inspection.test_quality_inspection import (
|
from erpnext.stock.doctype.quality_inspection.test_quality_inspection import (
|
||||||
create_quality_inspection_parameter,
|
create_quality_inspection_parameter,
|
||||||
@@ -18,6 +22,19 @@ class TestItemVariant(ERPNextTestSuite):
|
|||||||
variant = make_item_variant()
|
variant = make_item_variant()
|
||||||
self.assertEqual(variant.get("quality_inspection_template"), "_Test QC Template")
|
self.assertEqual(variant.get("quality_inspection_template"), "_Test QC Template")
|
||||||
|
|
||||||
|
def test_generate_keyed_value_combinations_ignores_empty_attributes(self):
|
||||||
|
combinations = generate_keyed_value_combinations(
|
||||||
|
{"Test Colour": ["Red", "Blue"], "Test Size": ["Small", "Large"], "Test Fit": []}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(len(combinations), 4)
|
||||||
|
self.assertNotIn("Test Fit", combinations[0])
|
||||||
|
|
||||||
|
single_attribute_combinations = generate_keyed_value_combinations(
|
||||||
|
{"Test Colour": ["Red", "Blue"], "Test Size": []}
|
||||||
|
)
|
||||||
|
self.assertEqual(single_attribute_combinations, [{"Test Colour": "Red"}, {"Test Colour": "Blue"}])
|
||||||
|
|
||||||
|
|
||||||
def create_variant_with_tables(item, args):
|
def create_variant_with_tables(item, args):
|
||||||
if isinstance(args, str):
|
if isinstance(args, str):
|
||||||
|
|||||||
@@ -772,11 +772,10 @@ $.extend(erpnext.item, {
|
|||||||
default: 0,
|
default: 0,
|
||||||
onchange: function () {
|
onchange: function () {
|
||||||
let selected_attributes = get_selected_attributes();
|
let selected_attributes = get_selected_attributes();
|
||||||
let lengths = [];
|
let lengths = Object.keys(selected_attributes).map((key) => {
|
||||||
Object.keys(selected_attributes).map((key) => {
|
return selected_attributes[key].length;
|
||||||
lengths.push(selected_attributes[key].length);
|
|
||||||
});
|
});
|
||||||
if (lengths.includes(0)) {
|
if (!lengths.length) {
|
||||||
me.multiple_variant_dialog.get_primary_btn().html(__("Create Variants"));
|
me.multiple_variant_dialog.get_primary_btn().html(__("Create Variants"));
|
||||||
me.multiple_variant_dialog.disable_primary_action();
|
me.multiple_variant_dialog.disable_primary_action();
|
||||||
} else {
|
} else {
|
||||||
@@ -813,7 +812,7 @@ $.extend(erpnext.item, {
|
|||||||
fieldtype: "HTML",
|
fieldtype: "HTML",
|
||||||
fieldname: "help",
|
fieldname: "help",
|
||||||
options: `<label class="control-label">
|
options: `<label class="control-label">
|
||||||
${__("Select at least one value from each of the attributes.")}
|
${__("Select at least one attribute value.")}
|
||||||
</label>`,
|
</label>`,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -875,6 +874,9 @@ $.extend(erpnext.item, {
|
|||||||
selected_attributes[attribute_name].push($(opt).attr("data-fieldname"));
|
selected_attributes[attribute_name].push($(opt).attr("data-fieldname"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (!selected_attributes[attribute_name].length) {
|
||||||
|
delete selected_attributes[attribute_name];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return selected_attributes;
|
return selected_attributes;
|
||||||
|
|||||||
@@ -871,8 +871,13 @@ class Item(Document):
|
|||||||
if disabled:
|
if disabled:
|
||||||
frappe.throw(_("Attribute {0} is disabled.").format(frappe.bold(d.attribute)))
|
frappe.throw(_("Attribute {0} is disabled.").format(frappe.bold(d.attribute)))
|
||||||
|
|
||||||
if not numeric_values and not frappe.db.exists(
|
if (
|
||||||
"Item Attribute Value", {"parent": d.attribute, "attribute_value": d.attribute_value}
|
not numeric_values
|
||||||
|
and d.attribute_value
|
||||||
|
and not frappe.db.exists(
|
||||||
|
"Item Attribute Value",
|
||||||
|
{"parent": d.attribute, "attribute_value": d.attribute_value},
|
||||||
|
)
|
||||||
):
|
):
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
_("Attribute Value {0} is not valid for the selected attribute {1}.").format(
|
_("Attribute Value {0} is not valid for the selected attribute {1}.").format(
|
||||||
|
|||||||
Reference in New Issue
Block a user