Skip to content

Commit 08f2382

Browse files
Mateus Jose Milczewski Alves Fariasjhosefmarks
authored andcommitted
fix(decimal): corrige falha no arredondamento dos decimais
Agora o componente passa a tratar o número total de caracteres para que as funcionalidades ocorram dentro das limitações do JavaScript. Fixes DTHFUI-1048
1 parent 65dedd7 commit 08f2382

File tree

4 files changed

+133
-29
lines changed

4 files changed

+133
-29
lines changed

projects/ui/src/lib/components/po-field/po-decimal/po-decimal.component.spec.ts

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,28 +59,41 @@ describe('PoDecimalComponent:', () => {
5959

6060
});
6161

62-
it('should update property `p-decimal-length` with `2` if invalid values', () => {
63-
const invalidValues = [undefined, null, '', true, false, 'string', [], {}];
64-
65-
expectPropertiesValues(component, 'decimalsLength', invalidValues, 2);
62+
it('decimalsLength: should update property with default value if is invalid value.', () => {
63+
const invalidValues = [undefined, null, '', true, false, 'string', [], {}, 16, -1];
64+
const defaultValue = 2;
65+
expectPropertiesValues(component, 'decimalsLength', invalidValues, defaultValue);
6666
});
6767

68-
it('should update property `p-decimals-length` with valid values', () => {
69-
const validValues = [0, 4];
70-
68+
it('decimalsLength: should update property with valid values.', () => {
69+
let validValues = [0, 3];
70+
expectPropertiesValues(component, 'decimalsLength', validValues, validValues);
71+
validValues = [3, 15];
72+
component.thousandMaxlength = 1;
7173
expectPropertiesValues(component, 'decimalsLength', validValues, validValues);
7274
});
7375

74-
it('should update property `p-thousand-maxlength` with `13` if invalid values', () => {
75-
const invalidValues = [undefined, null, '', true, false, 'string', [], {}, 15];
76+
it('thousandMaxlength: should update property with remaining value of total limit minus `decimalsLength`.', () => {
77+
component.decimalsLength = 7;
78+
component.thousandMaxlength = undefined;
79+
const remainingValue = 16 - component.decimalsLength;
7680

77-
expectPropertiesValues(component, 'thousandMaxlength', invalidValues, 13);
81+
expect(component.decimalsLength).toEqual(7);
82+
expect(component.thousandMaxlength).toEqual(remainingValue);
7883
});
7984

80-
it('should update property `p-thousand-maxlength` with valid values', () => {
81-
const validValues = [5, 8];
85+
it('thousandMaxlength: should update property with default value if is invalid values.', () => {
86+
const invalidValues = [undefined, null, '', true, false, 'string', [], {}, 15];
87+
const defaultValue = 13;
88+
expectPropertiesValues(component, 'thousandMaxlength', invalidValues, defaultValue);
89+
});
8290

91+
it('thousandMaxlength: should update property with valid values.', () => {
92+
let validValues = [5, 8];
8393
expectPropertiesValues(component, 'thousandMaxlength', validValues, validValues);
94+
validValues = [13, 21];
95+
component.decimalsLength = 4;
96+
expectPropertiesValues(component, 'thousandMaxlength', validValues, 13);
8497
});
8598

8699
it('should create button clean', () => {
@@ -1251,6 +1264,40 @@ describe('PoDecimalComponent:', () => {
12511264
expect(component.hasLetters(undefined)).toBeFalsy();
12521265
});
12531266

1267+
it('isGreaterThanTotalLengthLimit: should return `false` if total sum is 16.', () => {
1268+
let decimalsMaxLength = 1;
1269+
let thousandMaxlength = 15;
1270+
expect(component['isGreaterThanTotalLengthLimit'](decimalsMaxLength, thousandMaxlength)).toBe(false);
1271+
1272+
decimalsMaxLength = 14;
1273+
thousandMaxlength = 2;
1274+
expect(component['isGreaterThanTotalLengthLimit'](decimalsMaxLength, thousandMaxlength)).toBe(false);
1275+
});
1276+
1277+
it('isGreaterThanTotalLengthLimit: should return `true` if total sum is greater than 16.', () => {
1278+
const decimalsMaxLength = 13;
1279+
const thousandMaxlength = 4;
1280+
expect(component['isGreaterThanTotalLengthLimit'](decimalsMaxLength, thousandMaxlength)).toBe(true);
1281+
});
1282+
1283+
it('isGreaterThanTotalLengthLimit: should return `false` if total sum is less than 16.', () => {
1284+
const decimalsMaxLength = 3;
1285+
const thousandMaxlength = 6;
1286+
expect(component['isGreaterThanTotalLengthLimit'](decimalsMaxLength, thousandMaxlength)).toBe(false);
1287+
});
1288+
1289+
it('isValueBetweenAllowed: should return `true` if is value between allowed.', () => {
1290+
expect(component['isValueBetweenAllowed'](3, 9)).toBe(true);
1291+
});
1292+
1293+
it('isValueBetweenAllowed: should return `false` if is value over allowed.', () => {
1294+
expect(component['isValueBetweenAllowed'](10, 9)).toBe(false);
1295+
});
1296+
1297+
it('isValueBetweenAllowed: should return `false` if is value below allowed.', () => {
1298+
expect(component['isValueBetweenAllowed'](-1, 9)).toBe(false);
1299+
});
1300+
12541301
});
12551302

12561303
describe('Templates:', () => {

projects/ui/src/lib/components/po-field/po-decimal/po-decimal.component.ts

Lines changed: 58 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,28 @@ import { AbstractControl, NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/form
44
import { convertToInt } from '../../../utils/util';
55
import { PoInputBaseComponent } from '../po-input/po-input-base.component';
66

7-
const PO_DECIMAL_DEFAULT_DECIMALS_LENGTH = 2;
8-
const PO_DECIMAL_DEFAULT_THOUSAND_MAXLENGTH = 13;
7+
const poDecimalDefaultDecimalsLength = 2;
8+
const poDecimalDefaultThousandMaxlength = 13;
9+
const poDecimalMaxDecimalsLength = 15;
10+
const poDecimalTotalLengthLimit = 16;
911

1012
/**
1113
*
1214
* @docsExtends PoInputBaseComponent
1315
*
1416
* @description
1517
*
16-
* po-decimal é um input específico para receber apenas números decimais.
17-
* Quando utilizado, o componente terá comportamento de um campo de 'text' com algumas características:
18+
* <br>
19+
* - O `po-decimal` é um *input* específico para receber apenas números decimais, por isso recebe as seguintes características:
20+
* + Aceita apenas números;
21+
* + Utiliza ',' como separador de decimal;
22+
* + Utiliza '.' para separação de milhar;
23+
* + É possível configurar a quantidade de casas decimais e a quantidade de digitos do campo.
1824
*
19-
* - Aceita apenas números;
20-
* - Utiliza ',' como separador de decimal;
21-
* - Utiliza '.' para separação de milhar;
22-
* - É possível configurar a quantidade de casas decimais e a quantidade de digitos do campo.
25+
* > **Importante:**
26+
* Atualmente o JavaScript limita-se a um conjunto de dados de `32 bits`, e para que os valores comportem-se devidamente,
27+
* o `po-decimal` contém um tratamento que limita em 16 o número total de casas antes e após a vírgula.
28+
* Veja abaixo as demais regras nas documentações de `p-decimals-length` e `p-thousand-maxlength`.
2329
*
2430
* @example
2531
*
@@ -61,8 +67,8 @@ const PO_DECIMAL_DEFAULT_THOUSAND_MAXLENGTH = 13;
6167
})
6268
export class PoDecimalComponent extends PoInputBaseComponent implements AfterViewInit {
6369

64-
private _decimalsLength?: number = PO_DECIMAL_DEFAULT_DECIMALS_LENGTH;
65-
private _thousandMaxlength?: number = PO_DECIMAL_DEFAULT_THOUSAND_MAXLENGTH;
70+
private _decimalsLength?: number = poDecimalDefaultDecimalsLength;
71+
private _thousandMaxlength?: number = poDecimalDefaultThousandMaxlength;
6672

6773
private decimalSeparator: string = ',';
6874
private fireChange: boolean = false;
@@ -90,11 +96,25 @@ export class PoDecimalComponent extends PoInputBaseComponent implements AfterVie
9096
*
9197
* Quantidade máxima de casas decimais.
9298
*
99+
* > **Importante:**
100+
* - O valor máximo permitido é 15;
101+
* - A soma total de `p-decimals-length` com `p-thousand-maxlength` limita-se à 16;
102+
* - Esta propriedade sobrepõe apenas o valor **padrão** de `p-thousand-maxlength`;
103+
* - Caso `p-thousand-maxlength` tenha um valor definido, esta propriedade poderá receber apenas o valor restante do limite total (16).
104+
*
93105
* @default `2`
94106
*/
95107
@Input('p-decimals-length') set decimalsLength(value: number) {
96-
this._decimalsLength = convertToInt(value, PO_DECIMAL_DEFAULT_DECIMALS_LENGTH);
108+
let decimalsLength = convertToInt(value);
109+
110+
decimalsLength = this.isValueBetweenAllowed(decimalsLength, poDecimalMaxDecimalsLength) ?
111+
decimalsLength : poDecimalDefaultDecimalsLength;
112+
113+
if (this.isGreaterThanTotalLengthLimit(decimalsLength, this.thousandMaxlength)) {
114+
this.thousandMaxlength = poDecimalTotalLengthLimit - decimalsLength;
115+
}
97116

117+
this._decimalsLength = decimalsLength;
98118
}
99119

100120
get decimalsLength() {
@@ -106,15 +126,30 @@ export class PoDecimalComponent extends PoInputBaseComponent implements AfterVie
106126
*
107127
* @description
108128
*
109-
* Número máximo de dígitos antes do separador de decimal. O valor máximo possível deve ser menor ou igual a 13.
129+
* Quantidade máxima de dígitos antes do separador decimal.
130+
*
131+
* > **Importante:**
132+
* - O valor máximo permitido é 13;
133+
* - A soma total de `p-decimals-length` com `p-thousand-maxlength` limita-se à 16;
134+
* - Esta propriedade sobrepõe o valor definido em `p-decimals-length`.
110135
*
111136
* @default `13`
112137
*/
113138
@Input('p-thousand-maxlength') set thousandMaxlength(value: number) {
114-
const thousandMaxlength = convertToInt(value, PO_DECIMAL_DEFAULT_THOUSAND_MAXLENGTH);
139+
let thousandMaxlength = convertToInt(value);
140+
141+
if (this.decimalsLength > poDecimalDefaultDecimalsLength && !thousandMaxlength) {
142+
thousandMaxlength = poDecimalTotalLengthLimit - this.decimalsLength;
143+
}
115144

116-
this._thousandMaxlength = thousandMaxlength <= PO_DECIMAL_DEFAULT_THOUSAND_MAXLENGTH ?
117-
thousandMaxlength : PO_DECIMAL_DEFAULT_THOUSAND_MAXLENGTH;
145+
thousandMaxlength = this.isValueBetweenAllowed(thousandMaxlength, poDecimalDefaultThousandMaxlength) ?
146+
thousandMaxlength : poDecimalDefaultThousandMaxlength;
147+
148+
if (this.isGreaterThanTotalLengthLimit(this.decimalsLength, thousandMaxlength)) {
149+
this.decimalsLength = poDecimalTotalLengthLimit - thousandMaxlength;
150+
}
151+
152+
this._thousandMaxlength = thousandMaxlength;
118153
}
119154

120155
get thousandMaxlength() {
@@ -414,6 +449,10 @@ export class PoDecimalComponent extends PoInputBaseComponent implements AfterVie
414449
this.validateCursorPositionBeforeSeparator(event) || this.verifyDecimalLengthIsZeroAndKeyPressedIsComma(charCode);
415450
}
416451

452+
private isGreaterThanTotalLengthLimit(decimalsMaxLength: number, thousandMaxlength: number) {
453+
return (decimalsMaxLength + thousandMaxlength) > poDecimalTotalLengthLimit;
454+
}
455+
417456
private isKeyDecimalSeparator(event) {
418457
return event.key === this.decimalSeparator || event.char === this.decimalSeparator;
419458
}
@@ -449,6 +488,10 @@ export class PoDecimalComponent extends PoInputBaseComponent implements AfterVie
449488
return true;
450489
}
451490

491+
private isValueBetweenAllowed(value: number, maxAllowed: number) {
492+
return value >= 0 && value <= maxAllowed;
493+
}
494+
452495
// Quando decimalsLength for 0 não deve permitir informar vírgula (decimalSeparator)
453496
private verifyDecimalLengthIsZeroAndKeyPressedIsComma(charCode: number) {
454497
return (charCode === 44 && this.decimalsLength === 0);

projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-labs/sample-po-decimal-labs.component.html

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,21 @@
6161
name="decimalsLength"
6262
[(ngModel)]="decimalsLength"
6363
p-clean
64-
p-label="Decimals max length">
64+
p-help="By default is equal 2, check the behavior in doc."
65+
p-label="Decimals max length"
66+
p-min="0"
67+
[p-max]="maxDecimalsLength">
6568
</po-number>
6669

6770
<po-number
6871
class="po-md-6"
6972
name="thousandMaxlength"
7073
[(ngModel)]="thousandMaxlength"
7174
p-clean
72-
p-label="Thousand max length">
75+
p-help="By default is equal 13, check the behavior in doc."
76+
p-label="Thousand max length"
77+
p-min="0"
78+
[p-max]="maxThousandMaxlength">
7379
</po-number>
7480
</div>
7581

projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-labs/sample-po-decimal-labs.component.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ export class SamplePoDecimalLabsComponent implements OnInit {
3333
{ value: 'required', label: 'Required' }
3434
];
3535

36+
get maxDecimalsLength() {
37+
return 16 - this.thousandMaxlength || 15;
38+
}
39+
40+
get maxThousandMaxlength() {
41+
return 16 - this.decimalsLength || 13;
42+
}
43+
3644
ngOnInit() {
3745
this.restore();
3846
}

0 commit comments

Comments
 (0)