app/webpacker/js/services/option_value_namer.js
import VariantUnitManager from "../../js/services/variant_unit_manager";
// Javascript clone of VariantUnits::OptionValueNamer, for bulk product editing.
export default class OptionValueNamer {
constructor(variant) {
this.variant = variant;
this.variantUnitManager = new VariantUnitManager();
}
name() {
const [value, unit] = this.option_value_value_unit();
const separator = this.value_scaled() ? '' : ' ';
const name_fields = [];
if (value && unit) {
name_fields.push(`${value}${separator}${unit}`);
} else if (value) {
name_fields.push(value);
}
if (this.variant.unit_description) {
name_fields.push(this.variant.unit_description);
}
return name_fields.join(' ');
}
value_scaled() {
return !!this.variant.product.variant_unit_scale;
}
option_value_value_unit() {
let value, unit_name;
if (this.variant.unit_value) {
if (this.variant.product.variant_unit === "weight" || this.variant.product.variant_unit === "volume") {
[value, unit_name] = this.option_value_value_unit_scaled();
} else {
value = this.variant.unit_value;
unit_name = this.pluralize(this.variant.product.variant_unit_name, value);
}
if (value == parseInt(value, 10)) {
value = parseInt(value, 10);
}
} else {
value = unit_name = null;
}
return [value, unit_name];
}
pluralize(unit_name, count) {
if (count == null) {
return unit_name;
}
const unit_key = this.unit_key(unit_name);
if (!unit_key) {
return unit_name;
}
return I18n.t(["inflections", unit_key], {
count: count,
defaultValue: unit_name
});
}
unit_key(unit_name) {
if (!I18n.unit_keys) {
I18n.unit_keys = {};
for (const [key, translations] of Object.entries(I18n.t("inflections"))) {
for (const [quantifier, translation] of Object.entries(translations)) {
I18n.unit_keys[translation.toLowerCase()] = key;
}
}
}
return I18n.unit_keys[unit_name.toLowerCase()];
}
option_value_value_unit_scaled() {
const [unit_scale, unit_name] = this.scale_for_unit_value();
const value = Math.round((this.variant.unit_value / unit_scale) * 100) / 100;
return [value, unit_name];
}
scale_for_unit_value() {
// Find the largest available and compatible unit where unit_value comes
// to >= 1 when expressed in it.
// If there is none available where this is true, use the smallest
// available unit.
const product = this.variant.product;
const scales = this.variantUnitManager.compatibleUnitScales(product.variant_unit_scale, product.variant_unit);
const variantUnitValue = this.variant.unit_value;
// sets largestScale = last element in filtered scales array
const largestScale = scales.filter(s => variantUnitValue / s >= 1).slice(-1)[0];
if (largestScale) {
return [largestScale, this.variantUnitManager.getUnitName(largestScale, product.variant_unit)];
} else {
return [scales[0], this.variantUnitManager.getUnitName(scales[0], product.variant_unit)];
}
}
}