diff --git a/app/assets/javascripts/unit-conversion-field.js b/app/assets/javascripts/unit-conversion-field.js
index 2287b088..7efde41d 100644
--- a/app/assets/javascripts/unit-conversion-field.js
+++ b/app/assets/javascripts/unit-conversion-field.js
@@ -95,6 +95,7 @@
this.quantityInput$ = contents$.find('input.quantity');
this.quantityInput$.val(String(this.field$.val()).replace(',', '.'));
+ this.applyButton$ = contents$.find('input.apply');
this.conversionResult$ = contents$.find('.conversion-result');
this.unitSelect$ = contents$.find('select.unit');
this.unitSelect$.append(this.unitSelectOptions.map(option => $(``)))
@@ -109,20 +110,23 @@
this.unitSelect$.change(() => this.onUnitSelectChanged());
// eslint-disable-next-line no-undef
- mergeJQueryObjects([this.quantityInput$, this.unitSelect$]).change(() => this.showCurrentConversion())
+ mergeJQueryObjects([this.quantityInput$, this.unitSelect$]).change(() => this.prepareConversion())
this.quantityInput$.keyup(() => this.quantityInput$.trigger('change'));
- this.showCurrentConversion();
this.field$.on('change.unit-conversion-field', () => {
this.quantityInput$.val(this.field$.val());
+ this.quantityInput$.trigger('change')
this.unitSelect$.val(initialUnitSelectValue);
});
contents$.find('input.cancel').click(() => this.closePopover());
- contents$.find('input.apply').click(() => {
+ this.applyButton$.click(() => {
this.applyConversion();
this.closePopover();
});
+
+ this.onUnitSelectChanged();
+ this.prepareConversion();
}
getUnitSelectOptions() {
@@ -149,10 +153,19 @@
return options;
}
- showCurrentConversion() {
+ prepareConversion() {
const unit = this.defaultUnit === undefined ? this.supplierOrderUnit : this.defaultUnit;
const unitLabel = this.unitSelectOptions.find(option => option.value === unit).label;
this.conversionResult$.text('= ' + this.getConversionResult() + ' x ' + unitLabel);
+ this.conversionResult$.parent().find('.numeric-step-error').remove();
+ if (this.quantityInput$.is(':invalid')) {
+ this.applyButton$.attr('disabled', 'disabled');
+ const errorSpan$ = $(`
${I18n.t('errors.step_error', {min: 0, granularity: this.quantityInput$.attr('step')})}
`);
+ errorSpan$.show();
+ this.conversionResult$.after(errorSpan$);
+ } else {
+ this.applyButton$.removeAttr('disabled');
+ }
}
applyConversion() {
@@ -176,7 +189,7 @@
getConversionResult() {
const result = this.converter.getUnitRatio(this.getQuantityInputValue(), convertEmptyStringToUndefined(this.unitSelect$.val()), this.getTargetUnit());
- return Math.round(result * 10000) / 10000;
+ return Big(result).round(4).toNumber();
}
onUnitSelectChanged() {
@@ -186,7 +199,7 @@
const selectedUnit = convertEmptyStringToUndefined(this.unitSelect$.val());
this.previousUnitSelectValue = selectedUnit;
- const step = this.useTargetUnitForStep ? this.converter.getUnitRatio(1, this.getTargetUnit(), selectedUnit) : 0.001;
+ const step = this.useTargetUnitForStep ? this.converter.getUnitRatio(this.field$.attr('step'), this.getTargetUnit(), selectedUnit) : 0.001;
this.quantityInput$.attr('step', step);
}
diff --git a/app/assets/javascripts/units-converter.js b/app/assets/javascripts/units-converter.js
index 19699a18..40c65d62 100644
--- a/app/assets/javascripts/units-converter.js
+++ b/app/assets/javascripts/units-converter.js
@@ -19,15 +19,15 @@ class UnitsConverter {
const relatedRatio = this.ratios.find(ratio => this.units[ratio.unit].baseUnit === unit.baseUnit);
if (relatedRatio !== undefined) {
const relatedUnit = this.units[relatedRatio.unit];
- return relatedRatio.quantity / unit.conversionFactor * relatedUnit.conversionFactor;
+ return Big(relatedRatio.quantity).div(unit.conversionFactor).mul(relatedUnit.conversionFactor).toNumber();
}
const supplierOrderUnitConversionFactor = this.units[this.supplierOrderUnit].conversionFactor;
- return supplierOrderUnitConversionFactor / unit.conversionFactor;
+ return Big(supplierOrderUnitConversionFactor).div(unit.conversionFactor).toNumber();
}
getUnitRatio(quantity, inputUnit, outputUnit) {
- return quantity / this.getUnitQuantity(inputUnit) * this.getUnitQuantity(outputUnit);
+ return Big(quantity).div(this.getUnitQuantity(inputUnit)).mul(this.getUnitQuantity(outputUnit)).toNumber();
}
isUnitSiConversible(unitId) {
diff --git a/app/assets/stylesheets/bootstrap_and_overrides.css.less b/app/assets/stylesheets/bootstrap_and_overrides.css.less
index 87c49f57..33ed3777 100644
--- a/app/assets/stylesheets/bootstrap_and_overrides.css.less
+++ b/app/assets/stylesheets/bootstrap_and_overrides.css.less
@@ -647,3 +647,16 @@ td.mr-1 > *:last-child {
.user-select-none {
user-select: none;
}
+
+.numeric-step-error {
+ display: none;
+ color: #b94a48;
+}
+
+.btn-group.numeric-step > input:invalid {
+ border: 1px solid #b94a48;
+}
+
+.btn-group.numeric-step:has(> input:invalid) + .numeric-step-error {
+ display: block;
+}
diff --git a/app/views/group_orders/_form.html.haml b/app/views/group_orders/_form.html.haml
index 2a588de2..7ca9d153 100644
--- a/app/views/group_orders/_form.html.haml
+++ b/app/views/group_orders/_form.html.haml
@@ -120,12 +120,14 @@
%span.used= format_number(@ordering_data[:order_articles][order_article.id][:used_quantity])
+
%span.unused= format_number(@ordering_data[:order_articles][order_article.id][:quantity] - @ordering_data[:order_articles][order_article.id][:used_quantity])
- .btn-group
+ .btn-group.numeric-step
%a.btn.btn-ordering.increase
%i.icon-plus
%input.goa-quantity{type: "number", name: "group_order[group_order_articles_attributes][#{order_article.id}][quantity]", value: @ordering_data[:order_articles][order_article.id][:quantity], data: quantity_data, autocomplete: 'off', class: 'input-mini numeric', min: 0, step: order_article.article_version.group_order_granularity}
%a.btn.btn-ordering.decrease
%i.icon-minus
+ %span.numeric-step-error
+ = t('errors.step_error', granularity: order_article.article_version.group_order_granularity, min: 0)
%td.tolerance.group-order-input{style: ('display:none' if @order.stockit?)}
- if (requires_tolerance_input?(order_article, @ordering_data))
diff --git a/app/views/shared/js_templates/_unit_conversion_popover_template.haml b/app/views/shared/js_templates/_unit_conversion_popover_template.haml
index 06db93b5..69274718 100644
--- a/app/views/shared/js_templates/_unit_conversion_popover_template.haml
+++ b/app/views/shared/js_templates/_unit_conversion_popover_template.haml
@@ -6,7 +6,7 @@
%div.popover_contents.text-right{"data-title" => t('helpers.unit_conversion_fields.title')}
.d-flex
%select.unit.mr-1{"data-ignore-onchange" => true}
- %input.quantity.input-mini.numeric{:type => 'number'}
+ %input.quantity.input-mini.numeric{:type => 'number', :min => 0}
.conversion-result.mt-1.mb-1
%input.cancel.btn{:type => 'button', :value => t('helpers.unit_conversion_fields.cancel')}
%input.apply.btn.btn-primary{:type => 'button', :value => t('helpers.unit_conversion_fields.apply')}
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 18c9ec4d..0bedc246 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -804,6 +804,7 @@ de:
not_found:
text: Diese Seite existiert anscheinend nicht. Entschuldigung!
title: Seite nicht gefunden
+ step_error: Gib eine Zahl >=%{min} ein, die ein Vielfaches von %{granularity} ist.
feedback:
create:
notice: Das Feedback wurde erfolgreich verschickt. Vielen Dank!
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 611074a0..79caf1df 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -804,6 +804,7 @@ en:
not_found:
text: This page does not appear to exist, sorry!
title: Page not found
+ step_error: Enter a number >=%{min}, which is a multiple of %{granularity}.
feedback:
create:
notice: Your feedback was sent successfully. Thanks a lot!