feat: client-side currency conversion with admin-configurable rates
Some checks failed
Architecture Governance / architecture (push) Has been cancelled

- CurrencyRatesService: RUB-based rates, persisted via localStorage
- CurrencyConvertPipe: impure pipe converting item price to selected currency
- Admin settings page: editable currency rates form
- Applied conversion to product-card, product-information, quick-view-dialog,
  delivery-information, compare-table, cart totals + payment payload

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
sdarbinyan
2026-08-15 01:45:12 +04:00
parent d8c078ad5a
commit 4510eb769a
20 changed files with 235 additions and 30 deletions

View File

@@ -0,0 +1,53 @@
import { Injectable, Signal, inject, signal } from '@angular/core';
import { LocalStorageService } from '../core/storage/local-storage.service';
const RATES_KEY = 'currencyRates.v1';
/** Fallback rates relative to RUB (1 RUB = rate[code] units of code), used until admin overrides them. */
const DEFAULT_RATES: Record<string, number> = {
RUB: 1,
USD: 0.011,
EUR: 0.01,
AMD: 4.3,
};
@Injectable({ providedIn: 'root' })
export class CurrencyRatesService {
private readonly localStorage = inject(LocalStorageService);
private readonly ratesSignal = signal<Record<string, number>>(this.readStoredRates());
readonly rates: Signal<Record<string, number>> = this.ratesSignal.asReadonly();
/** Base currency all rates are relative to. */
readonly baseCurrency = 'RUB';
getRate(code: string): number {
return this.ratesSignal()[code] ?? DEFAULT_RATES[code] ?? 1;
}
setRate(code: string, rate: number): void {
if (!Number.isFinite(rate) || rate <= 0) {
return;
}
const next = { ...this.ratesSignal(), [code]: rate };
this.ratesSignal.set(next);
this.localStorage.setJSON(RATES_KEY, next);
}
/** Converts an amount expressed in `fromCurrency` into `toCurrency` via the RUB base rate. */
convert(amount: number, fromCurrency: string, toCurrency: string): number {
if (fromCurrency === toCurrency) {
return amount;
}
const fromRate = this.getRate(fromCurrency);
const toRate = this.getRate(toCurrency);
const amountInBase = amount / fromRate;
return amountInBase * toRate;
}
private readStoredRates(): Record<string, number> {
const stored = this.localStorage.getJSON<Record<string, number>>(RATES_KEY);
return { ...DEFAULT_RATES, ...stored };
}
}