fix: delivery-selector price/currency not converting on currency switch
Some checks failed
Architecture Governance / architecture (push) Has been cancelled

Component read item.currency (source) as both the display label and the
conversion target, so amounts never actually converted - only the label
technically matched. Now converts deliveryPrice/selectedDeliveryTotal via
CurrencyRatesService and labels with the shopper's selected currency.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
sdarbinyan
2026-08-15 02:01:08 +04:00
parent 4510eb769a
commit 0cadc1a642

View File

@@ -1,8 +1,10 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, inject } from '@angular/core';
import { DecimalPipe } from '@angular/common'; import { DecimalPipe } from '@angular/common';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { CartItem, DeliveryOption } from '../../models'; import { CartItem, DeliveryOption } from '../../models';
import { TranslatePipe } from '../../i18n/translate.pipe'; import { TranslatePipe } from '../../i18n/translate.pipe';
import { LanguageService } from '../../services/language.service';
import { CurrencyRatesService } from '../../services/currency-rates.service';
let nextDeliverySelectorId = 0; let nextDeliverySelectorId = 0;
@@ -15,6 +17,9 @@ let nextDeliverySelectorId = 0;
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class DeliverySelectorComponent { export class DeliverySelectorComponent {
private readonly languageService = inject(LanguageService);
private readonly currencyRates = inject(CurrencyRatesService);
@Input({ required: true }) item: CartItem | null = null; @Input({ required: true }) item: CartItem | null = null;
@Output() selectedDeliveryChange = new EventEmitter<DeliveryOption | null>(); @Output() selectedDeliveryChange = new EventEmitter<DeliveryOption | null>();
@@ -29,10 +34,20 @@ export class DeliverySelectorComponent {
return this.item?.selectedDelivery ?? null; return this.item?.selectedDelivery ?? null;
} }
get currency(): string { /** Source currency the item's prices are stored in. */
get sourceCurrency(): string {
return this.item?.currency || 'RUB'; return this.item?.currency || 'RUB';
} }
/** Currency the shopper has selected for display. */
get currency(): string {
return this.languageService.currentCurrency();
}
private convert(amount: number): number {
return this.currencyRates.convert(amount, this.sourceCurrency, this.currency);
}
get required(): boolean { get required(): boolean {
return this.item?.deliveryMode !== 'digital' return this.item?.deliveryMode !== 'digital'
&& this.options.length > 0 && this.options.length > 0
@@ -48,7 +63,8 @@ export class DeliverySelectorComponent {
} }
get selectedDeliveryTotal(): number { get selectedDeliveryTotal(): number {
return (this.selectedDelivery?.deliveryPrice ?? 0) * (this.item?.quantity ?? 1); const base = (this.selectedDelivery?.deliveryPrice ?? 0) * (this.item?.quantity ?? 1);
return this.convert(base);
} }
optionKey(option: DeliveryOption): string { optionKey(option: DeliveryOption): string {
@@ -57,7 +73,7 @@ export class DeliverySelectorComponent {
optionLabel(option: DeliveryOption): string { optionLabel(option: DeliveryOption): string {
const details = [option.deliveryPlace, option.deliveryTime].filter(Boolean); const details = [option.deliveryPlace, option.deliveryTime].filter(Boolean);
details.push(`${option.deliveryPrice.toFixed(2)} ${this.currency}`); details.push(`${this.convert(option.deliveryPrice).toFixed(2)} ${this.currency}`);
return details.join(' • '); return details.join(' • ');
} }