Browse Source

fix: preserve cryptocurrency quantity precision

pull/7557/head
Sebastian Legarraga 1 day ago
parent
commit
0c0b3e6023
  1. 2
      libs/ui/src/lib/holdings-table/holdings-table.component.html
  2. 5
      libs/ui/src/lib/holdings-table/holdings-table.component.ts
  3. 44
      libs/ui/src/lib/holdings-table/quantity-precision.spec.ts
  4. 17
      libs/ui/src/lib/holdings-table/quantity-precision.ts

2
libs/ui/src/lib/holdings-table/holdings-table.component.html

@ -80,9 +80,9 @@
> >
<div class="d-flex justify-content-end"> <div class="d-flex justify-content-end">
<gf-value <gf-value
[isCurrency]="true"
[isLoading]="isLoading()" [isLoading]="isLoading()"
[locale]="locale()" [locale]="locale()"
[precision]="getQuantityPrecision(element)"
[value]="element.quantity" [value]="element.quantity"
/> />
</div> </div>

5
libs/ui/src/lib/holdings-table/holdings-table.component.ts

@ -28,6 +28,7 @@ import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { GfEntityLogoComponent } from '../entity-logo/entity-logo.component'; import { GfEntityLogoComponent } from '../entity-logo/entity-logo.component';
import { GfValueComponent } from '../value/value.component'; import { GfValueComponent } from '../value/value.component';
import { getHoldingQuantityPrecision } from './quantity-precision';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
@ -103,6 +104,10 @@ export class GfHoldingsTableComponent {
return this.hasPermissionToOpenDetails() && canOpenHoldingDetail(holding); return this.hasPermissionToOpenDetails() && canOpenHoldingDetail(holding);
} }
protected getQuantityPrecision(holding: PortfolioPosition): number {
return getHoldingQuantityPrecision(holding);
}
protected onOpenHoldingDialog({ protected onOpenHoldingDialog({
dataSource, dataSource,
symbol symbol

44
libs/ui/src/lib/holdings-table/quantity-precision.spec.ts

@ -0,0 +1,44 @@
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
import { AssetSubClass } from '@prisma/client';
import { getHoldingQuantityPrecision } from './quantity-precision';
function createHolding(
quantity: number,
assetSubClass: AssetSubClass
): Pick<PortfolioPosition, 'assetProfile' | 'quantity'> {
return {
assetProfile: { assetSubClass } as PortfolioPosition['assetProfile'],
quantity
};
}
describe('getHoldingQuantityPrecision', () => {
it('preserves satoshi precision for fractional cryptocurrency quantities', () => {
expect(
getHoldingQuantityPrecision(
createHolding(0.01525217, AssetSubClass.CRYPTOCURRENCY)
)
).toBe(8);
expect(
getHoldingQuantityPrecision(
createHolding(10.12345678, AssetSubClass.CRYPTOCURRENCY)
)
).toBe(8);
});
it('does not add decimal places to integer cryptocurrency quantities', () => {
expect(
getHoldingQuantityPrecision(
createHolding(12, AssetSubClass.CRYPTOCURRENCY)
)
).toBe(0);
});
it('keeps the existing precision for non-cryptocurrency quantities', () => {
expect(
getHoldingQuantityPrecision(createHolding(12.3456, AssetSubClass.STOCK))
).toBe(2);
});
});

17
libs/ui/src/lib/holdings-table/quantity-precision.ts

@ -0,0 +1,17 @@
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
import { AssetSubClass } from '@prisma/client';
export function getHoldingQuantityPrecision(
holding: Pick<PortfolioPosition, 'assetProfile' | 'quantity'>
): number {
if (Number.isInteger(holding.quantity)) {
return 0;
}
if (holding.assetProfile.assetSubClass === AssetSubClass.CRYPTOCURRENCY) {
return 8;
}
return 2;
}
Loading…
Cancel
Save