From f05b4b1ef0c658420e06b63fc3bc38b0aa2c170f Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Wed, 29 Jul 2026 18:00:54 -0700 Subject: [PATCH] Fix: normalize monetary decimal symbol by locale --- ...ustom-fields-query-dropdown.component.html | 5 ++++ ...om-fields-query-dropdown.component.spec.ts | 24 +++++++++++++++++++ .../custom-fields-query-dropdown.component.ts | 22 ++++++++++++++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html b/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html index 225012159..c0c9b0c74 100644 --- a/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html +++ b/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html @@ -68,6 +68,11 @@ > } @else if (getCustomFieldByID(atom.field)?.data_type === CustomFieldDataType.DocumentLink) { + } @else if (getCustomFieldByID(atom.field)?.data_type === CustomFieldDataType.Monetary) { + } @else { } diff --git a/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.spec.ts b/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.spec.ts index a9c161d83..fb305ca1c 100644 --- a/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.spec.ts +++ b/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.spec.ts @@ -1,5 +1,6 @@ import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http' import { provideHttpClientTesting } from '@angular/common/http/testing' +import { LOCALE_ID } from '@angular/core' import { ComponentFixture, TestBed } from '@angular/core/testing' import { FormsModule, ReactiveFormsModule } from '@angular/forms' import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap' @@ -41,6 +42,12 @@ const customFields = [ ], }, }, + { + id: 3, + name: 'Test Monetary Field', + data_type: CustomFieldDataType.Monetary, + extra_data: { default_currency: 'EUR' }, + }, ] describe('CustomFieldsQueryDropdownComponent', () => { @@ -61,6 +68,7 @@ describe('CustomFieldsQueryDropdownComponent', () => { providers: [ provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting(), + { provide: LOCALE_ID, useValue: 'de' }, ], }).compileComponents() @@ -150,6 +158,22 @@ describe('CustomFieldsQueryDropdownComponent', () => { expect(options2).toEqual([]) }) + it('should normalize localized monetary comparison values', () => { + const atom = new CustomFieldQueryAtom([3, 'exact', null]) + + component.setMonetaryComparisonValue(atom, '1.234,56') + + expect(atom.value).toEqual('1234.56') + }) + + it('should preserve API-formatted monetary comparison values', () => { + const atom = new CustomFieldQueryAtom([3, 'exact', null]) + + component.setMonetaryComparisonValue(atom, '1234.56') + + expect(atom.value).toEqual('1234.56') + }) + it('should remove an element from the selection model', () => { const expression = new CustomFieldQueryExpression() const atom = new CustomFieldQueryAtom() diff --git a/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.ts b/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.ts index 1d2ce1f5c..733753b8b 100644 --- a/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.ts +++ b/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.ts @@ -1,9 +1,14 @@ -import { NgTemplateOutlet } from '@angular/common' +import { + getLocaleNumberSymbol, + NgTemplateOutlet, + NumberSymbol, +} from '@angular/common' import { Component, EventEmitter, inject, Input, + LOCALE_ID, Output, QueryList, signal, @@ -212,6 +217,7 @@ export class CustomFieldQueriesModel { }) export class CustomFieldsQueryDropdownComponent extends LoadingComponentWithPermissions { protected customFieldsService = inject(CustomFieldsService) + private locale = inject(LOCALE_ID) public CustomFieldQueryComponentType = CustomFieldQueryElementType public CustomFieldQueryOperator = CustomFieldQueryOperator @@ -376,4 +382,18 @@ export class CustomFieldsQueryDropdownComponent extends LoadingComponentWithPerm } return [] } + + setMonetaryValue(atom: CustomFieldQueryAtom, value: string) { + // Normalize the decimal symbol e.g. . vs , by locale + const decimalSymbol = getLocaleNumberSymbol( + this.locale, + NumberSymbol.Decimal + ) + if (decimalSymbol !== '.' && value.includes(decimalSymbol)) { + const groupSymbol = getLocaleNumberSymbol(this.locale, NumberSymbol.Group) + value = value.split(groupSymbol).join('').split(decimalSymbol).join('.') + } + + atom.value = value + } }