عنوان:

‫طراحی سیستم‌های مالی ایرانی با واحد پولی جدید


نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۵/۱۶ ۰۸:۰۵
آدرس: www.dntips.ir
قِران به‌عنوان یک واحد پولی در تاریخ ایران سابقه‌ای طولانی دارد و در گذشته نقش مهمی در سیستم پولی کشور ایفا کرده است. با توجه به مصوبه اخیر کمیته اقتصادی مجلس ایران در سال 1403، قِران دوباره به‌عنوان واحد خرد پولی در کنار ریال جدید احیا شده است.

تعریف و ویژگی‌های قِران
الف. تعریف قِران
واحد خرد پولی: قِران به‌عنوان واحد خرد در کنار ریال جدید تعریف شده است، مشابه نقش سنت در دلار یا دینار در گذشته ایران.
ارتباط با ریال جدید:
  • ۱ ریال جدید = ۱۰۰ قِران.
  • ۱ قِران = ۰.۰۱ ریال جدید.
ارتباط با ریال فعلی:
  • چون ۱ ریال جدید = ۱۰,۰۰۰ ریال فعلی، بنابراین:
  • ۱ قِران = ۱۰۰ ریال فعلی (محاسبه: ۱۰,۰۰۰ ÷ ۱۰۰ = ۱۰۰).
ارتباط با تومان (محاوره‌ای):
  • چون ۱ تومان = ۱۰ ریال فعلی، بنابراین:
  • ۱ قِران = ۱۰ تومان.

ب. نقش قِران
  • تراکنش‌های خرد: قِران برای پرداخت‌های کوچک (مثل خریدهای روزمره، کرایه تاکسی، یا هزینه‌های جزئی) استفاده می‌شود.
  • جایگزینی اعشار: قِران جایگزین اعشار در محاسبات مالی با ریال جدید است، مشابه نقش سنت یا پنی در سیستم‌های پولی دیگر.
  • دوره گذار: در دوره گذار سه‌ساله (تا حدود ۱۴۰۷ شمسی)، قِران در کنار ریال فعلی و ریال جدید استفاده خواهد شد و به‌عنوان واحد خرد در کنار آن‌ها استفاده می‌شود. بنابراین، سیستم باید بتواند تبدیل‌های قِران به هر دو واحد (ریال جدید و ریال فعلی) و همچنین به تومان (به دلیل استفاده محاوره‌ای) را پشتیبانی کند.


ج. نرخ‌های تبدیل قِران
جدول نرخ‌های تبدیل مرتبط با قِران:
از واحدبه واحدنرخ تبدیل
قِرانریال جدید۱ قِران = ۰.۰۱ ریال جدید
قِرانریال فعلی۱ قِران = ۱۰۰ ریال فعلی
قِرانتومان۱ قِران = ۱۰ تومان
ریال جدیدقِران۱ ریال جدید = ۱۰۰ قِران
ریال فعلیقِران۱ ریال فعلی = ۰.۰۱ قِران
تومانقِران۱ تومان = ۰.۱ قِران


در این مطلب، ملاحظات پیاده‌سازی قِران در یک سیستم مالی مبتنی بر دات‌نت و EF Core بررسی می‌شود. برای یک برنامه‌نویس دات‌نت که از EF-Core استفاده می‌کند، این تغییر در واحد پولی ایران یک چالش مهم در طراحی موجودیت‌ها و منطق برنامه (Business Logic) ایجاد می‌کند. کلید اصلی برای مواجهه با این مسئله، ذخیره‌سازی مقادیر پولی در یک واحد پایه و ثابت و انجام تبدیل واحد تنها در لایه نمایش (UI) است.

نکات کلیدی برای طراحی برنامه و موجودیت‌ها

شما باید موجودیت‌های مرتبط با امور مالی خود را به‌گونه‌ای طراحی کنید که در برابر تغییرات آینده واحد پولی نیز انعطاف‌پذیر باشند. بهترین رویکرد این است که از یک واحد پولی پایه و کوچک برای ذخیره‌سازی داده‌ها استفاده کنید تا از خطاهای گرد کردن (Rounding Errors) در محاسبات جلوگیری شود.

۱. انتخاب واحد پایه برای ذخیره‌سازی

با توجه به مصوبه جدید، کوچک‌ترین واحد پولی قران است که هر ریال جدید برابر با ۱۰۰ قران است. بنابراین، توصیه می‌شود تمام مقادیر مالی (مانند قیمت محصولات، مبلغ فاکتور، مانده حساب و ...) را به واحد قران در پایگاه داده ذخیره کنید.
  • مثال: اگر قیمت یک کالا ۲۵۰,۰۰۰ ریال فعلی باشد، معادل ۲۵ ریال جدید یا ۲,۵۰۰ قران است. شما باید این مقدار را به صورت 2500 در پایگاه داده ذخیره کنید.

۲. نوع داده (Data Type) مناسب

برای ذخیره‌سازی مقادیر پولی، همیشه باید از نوع داده decimal استفاده کنید.
  • چرا decimal؟ نوع داده decimal به طور خاص برای محاسبات دقیق مالی طراحی شده و از مشکلات دقت شناور (Floating-point Precision) که در انواع float یا double وجود دارد، جلوگیری می‌کند. این امر در سیستم‌های مالی که حتی کوچک‌ترین خطا نیز می‌تواند منجر به مشکلات بزرگ شود، حیاتی است.

۳. طراحی موجودیت (Entity Design) در EF-Core

در مدل EF-Core خود، پراپرتی‌های مربوط به مبالغ مالی را با نوع decimal تعریف کنید و نام‌گذاری آن‌ها را به‌گونه‌ای انجام دهید که واحد آن مشخص باشد. مثال:
public class Invoice
{
    public int Id { get; set; }
    
    // Store the total amount in Qeran to maintain consistency
    public decimal TotalAmountInQeran { get; set; } 
    
    // Other properties...
}

آیا برنامه باید چند واحد پولی طراحی شود؟

پاسخ این است که خیر، نیازی به طراحی "چند واحد پولی" در لایه ذخیره‌سازی و محاسبات اصلی نیست. در واقع، رویکرد صحیح، طراحی "تک واحدی برای ذخیره‌سازی و چند واحدی برای نمایش" است.
  • لایه منطق برنامه (Business Logic Layer): تمامی محاسبات (جمع، تفریق، ضرب، تقسیم) باید با استفاده از واحد پایه (قران) انجام شوند.
  • لایه نمایش (Presentation Layer): در زمان نمایش به کاربر، از توابع کمکی (Helper Functions) برای تبدیل مقدار ذخیره‌شده به واحد مورد نظر کاربر (مثلاً ریال جدید، تومان یا حتی ریال فعلی) استفاده کنید. این توابع تبدیل، فقط برای فرمت‌دهی خروجی هستند و داده‌های اصلی برنامه را تغییر نمی‌دهند.

مثال یک تابع تبدیل در لایه نمایش:
public class CurrencyHelper
{
    // Converts a value from Qeran to Toman for display
    public static string ToTomanString(decimal amountInQeran)
    {
        // 1 New Rial = 100 Qeran, and 1 New Rial is essentially 1 Toman
        // Therefore, 1 Qeran = 0.01 Toman
        decimal amountInToman = amountInQeran / 100;
        
        return $"{amountInToman:N0}"; // N0 for no decimal places, for example
    }
}

// In a UI component:
// var invoice = dbContext.Invoices.Find(1);
// string displayAmount = CurrencyHelper.ToTomanString(invoice.TotalAmountInQeran); 
// // displayAmount will be formatted as a Toman value

خلاصه روش برخورد با این مسئله

  • استانداردسازی: یک واحد پایه و ثابت (مانند قران) برای تمام داده‌های مالی انتخاب کنید.
  • دقت بالا: از نوع داده decimal برای تمامی فیلدهای مالی در مدل‌ها و پایگاه داده استفاده کنید.
  • یکپارچگی در منطق: تمامی محاسبات را با استفاده از واحد پایه انجام دهید.
  • جداسازی لایه‌ها: تبدیل واحد را فقط در زمان نمایش اطلاعات به کاربر و در لایه رابط کاربری انجام دهید.

با پیروی از این اصول، شما یک سیستم مالی پایدار و مقاوم در برابر تغییرات آتی ایجاد می‌کنید که از نظر دقت و صحت داده‌ها قابل اطمینان است. در ادامه سعی می‌کنیم این موارد را با جزئیات بیشتری بررسی کرده و یک روش پیشنهادی را جهت مدیریت این پیچیدگی‌ها ارائه دهیم:

۱. طراحی کلی سیستم
الف. فرضیات
  • نرخ‌های تبدیل ثابت: طبق مصوبه، نرخ‌های تبدیل بین قِران، ریال جدید، ریال فعلی، و تومان ثابت هستند (۱ قِران = ۰.۰۱ ریال جدید = ۱۰۰ ریال فعلی = ۱۰ تومان).
  • ذخیره در قِران: تمام مقادیر مالی در پایگاه داده به قِران ذخیره می‌شوند تا پیچیدگی کاهش یابد.
  • تبدیل در رابط کاربری: تبدیل به واحدهای دیگر (ریال جدید، ریال فعلی، تومان) فقط در زمان نمایش یا گزارش‌گیری انجام می‌شود.
  • انتخاب واحد توسط کاربر: کاربر از طریق یک منوی کشویی (Dropdown) واحد پولی موردنظر را انتخاب می‌کند، و مقادیر در رابط کاربری به واحد انتخاب‌شده نمایش داده می‌شوند.

ب. مزایا
  • سادگی پایگاه داده: ذخیره فقط به قِران، نیاز به مدیریت چندین واحد در پایگاه داده را حذف می‌کند.
  • کاهش پیچیدگی: استفاده از enum و دیکشنری به جای جداول پایگاه داده، پیچیدگی کدها و پرس‌وجوها را کاهش می‌دهد.
  • انعطاف‌پذیری در نمایش: تبدیل‌ها در زمان گزارش‌گیری یا نمایش در رابط کاربری انجام می‌شوند، که تجربه کاربری را بهبود می‌بخشد.

۲. تعریف واحدهای پولی با Enum
از یک enum برای تعریف واحدها استفاده می‌کنیم:
public enum CurrencyUnit
{
    Qeran,      // قِران
    RialNew,    // ریال جدید
    RialOld,    // ریال فعلی
    Toman       // تومان
}
نکات:
  • نام‌های enum کوتاه و معنادار هستند.
  • این enum شامل تمام واحدهای موردنیاز (قِران، ریال جدید، ریال فعلی، تومان) است.

۳. تعریف دیکشنری نرخ‌های تبدیل
این دیکشنری نرخ‌های تبدیل را بر اساس جفت واحدهای مبدا و مقصد نگه می‌دارد.
public static class CurrencyConversionRates
{
    private static readonly Dictionary<(CurrencyUnit From, CurrencyUnit To), decimal> Rates = new()
    {
        // قِران به سایر واحدها
        { (CurrencyUnit.Qeran, CurrencyUnit.RialNew), 0.01m },  // ۱ قِران = ۰.۰۱ ریال جدید
        { (CurrencyUnit.Qeran, CurrencyUnit.RialOld), 100m },   // ۱ قِران = ۱۰۰ ریال فعلی
        { (CurrencyUnit.Qeran, CurrencyUnit.Toman), 10m },      // ۱ قِران = ۱۰ تومان

        // ریال جدید به سایر واحدها
        { (CurrencyUnit.RialNew, CurrencyUnit.Qeran), 100m },   // ۱ ریال جدید = ۱۰۰ قِران
        { (CurrencyUnit.RialNew, CurrencyUnit.RialOld), 10000m }, // ۱ ریال جدید = ۱۰,۰۰۰ ریال فعلی
        { (CurrencyUnit.RialNew, CurrencyUnit.Toman), 1000m },  // ۱ ریال جدید = ۱,۰۰۰ تومان

        // ریال فعلی به سایر واحدها
        { (CurrencyUnit.RialOld, CurrencyUnit.Qeran), 0.01m },  // ۱ ریال فعلی = ۰.۰۱ قِران
        { (CurrencyUnit.RialOld, CurrencyUnit.RialNew), 0.0001m }, // ۱ ریال فعلی = ۰.۰۰۰۱ ریال جدید
        { (CurrencyUnit.RialOld, CurrencyUnit.Toman), 0.1m },   // ۱ ریال فعلی = ۰.۱ تومان

        // تومان به سایر واحدها
        { (CurrencyUnit.Toman, CurrencyUnit.Qeran), 0.1m },     // ۱ تومان = ۰.۱ قِران
        { (CurrencyUnit.Toman, CurrencyUnit.RialNew), 0.001m }, // ۱ تومان = ۰.۰۰۱ ریال جدید
        { (CurrencyUnit.Toman, CurrencyUnit.RialOld), 10m }     // ۱ تومان = ۱۰ ریال فعلی
    };

    public static decimal GetRate(CurrencyUnit from, CurrencyUnit to)
    {
        if (from == to)
            return 1m;

        if (Rates.TryGetValue((from, to), out var rate))
            return rate;

        throw new InvalidOperationException($"نرخ تبدیل از {from} به {to} تعریف نشده است.");
    }
}
نکات:
  • کلید دیکشنری: از یک تاپل (CurrencyUnit From, CurrencyUnit To) برای شناسایی جفت واحدهای مبدا و مقصد استفاده شده است.
  • ثابت بودن نرخ‌ها: این دیکشنری نرخ‌های ثابت را نگه می‌دارد، که با فرض عدم تغییر نرخ‌ها در دوره گذار سازگار است.
  • مدیریت خطا: اگر نرخ تبدیل برای یک جفت واحد وجود نداشته باشد، خطا تولید می‌شود.
  • دقت: از نوع decimal برای جلوگیری از خطاهای گرد کردن استفاده شده است.

۴. تهیه سرویس تبدیل
سرویس تبدیل با استفاده از دیکشنری تهیه می‌شود تا نرخ‌ها را از CurrencyConversionRates بخواند:
public class CurrencyService
{
    public decimal Convert(decimal amount, CurrencyUnit fromCurrency, CurrencyUnit toCurrency)
    {
        if (fromCurrency == toCurrency)
            return amount;

        var rate = CurrencyConversionRates.GetRate(fromCurrency, toCurrency);
        return amount * rate;
    }

    public decimal ConvertToQeran(decimal amount, CurrencyUnit fromCurrency)
    {
        return Convert(amount, fromCurrency, CurrencyUnit.Qeran);
    }

    public decimal ConvertFromQeran(decimal amountInQeran, CurrencyUnit toCurrency)
    {
        return Convert(amountInQeran, CurrencyUnit.Qeran, toCurrency);
    }
}
ویژگی‌ها:
  • سادگی: نیازی به اتصال به پایگاه داده نیست، و نرخ‌ها مستقیماً از دیکشنری خوانده می‌شوند.
  • عملکرد بالا: حذف پرس‌وجوهای پایگاه داده و کش کردن (که در این حالت نیازی نیست، زیرا دیکشنری در حافظه است) باعث بهبود عملکرد می‌شود.
  • مدیریت تبدیل به/از قِران: متدهای اختصاصی برای تبدیل به قِران و از قِران برای راحتی استفاده اضافه شده‌اند.

۵. مدل‌سازی در پایگاه داده
برای کاهش پیچیدگی، تمام مقادیر مالی در پایگاه داده به قِران ذخیره می‌شوند. مدل تراکنش به‌صورت زیر تعریف می‌شود:
public class Transaction
{
    public int Id { get; set; }
    public decimal AmountInQeran { get; set; } // مقدار به قِران
    public DateTime Date { get; set; }
    public string Notes { get; set; } // یادداشت‌ها (اختیاری)
}
پیکربندی با EF Core:
modelBuilder.Entity<Transaction>()
    .Property(t => t.AmountInQeran)
    .HasColumnType("decimal(18,4)"); // دقت بالا برای مقادیر خرد
نکات:
  • واحد پایه قِران: تمام مقادیر مالی به قِران ذخیره می‌شوند، که نیاز به ذخیره واحد پولی در هر تراکنش را حذف می‌کند.
  • دقت اعشاری: نوع decimal(18,4) برای پشتیبانی از مقادیر خرد (مثلاً ۰.۰۱ قِران) مناسب است.

۶. ثبت تراکنش
برای ثبت تراکنش، مقدار ورودی کاربر (در هر واحدی) به قِران تبدیل شده و ذخیره می‌شود:
public class TransactionService
{
    private readonly AppDbContext _context;
    private readonly CurrencyService _currencyService;

    public TransactionService(AppDbContext context, CurrencyService currencyService)
    {
        _context = context;
        _currencyService = currencyService;
    }

    public async Task RecordTransaction(decimal amount, CurrencyUnit currency, DateTime transactionDate, string notes = null)
    {
        var amountInQeran = _currencyService.ConvertToQeran(amount, currency);
        var transaction = new Transaction
        {
            AmountInQeran = amountInQeran,
            Date = transactionDate,
            Notes = notes ?? "تراکنش ثبت‌شده به قِران"
        };

        _context.Transactions.Add(transaction);
        await _context.SaveChangesAsync();
    }
}
مثال استفاده:
var transactionService = new TransactionService(dbContext, currencyService);
await transactionService.RecordTransaction(5000m, CurrencyUnit.Toman, DateTime.Now); // ۵,۰۰۰ تومان = ۵۰۰ قِران
await transactionService.RecordTransaction(5m, CurrencyUnit.RialNew, DateTime.Now); // ۵ ریال جدید = ۵۰۰ قِران

۷. رابط کاربری و گزارش‌گیری
الف. منوی کشویی (Dropdown)
در رابط کاربری، یک منوی کشویی برای انتخاب واحد پولی توسط کاربر ارائه می‌شود. مثال در ASP.NET Core Razor:
<select name="currency" asp-items="@Enum.GetValues(typeof(CurrencyUnit)).Cast<CurrencyUnit>().Select(c => new SelectListItem { Value = c.ToString(), Text = c.ToString() })">
    <option value="">انتخاب واحد پولی</option>
</select>

ب. نمایش چندواحدی در گزارش‌گیری
هنگام گزارش‌گیری یا نمایش تراکنش‌ها، مقدار ذخیره‌شده (به قِران) به واحد انتخاب‌شده توسط کاربر تبدیل می‌شود. مدل نمایشی (ViewModel) برای گزارش‌گیری:
public class TransactionViewModel
{
    public int Id { get; set; }
    public decimal Amount { get; set; }
    public CurrencyUnit Currency { get; set; }
    public DateTime Date { get; set; }
    public string Notes { get; set; }
}
سرویس گزارش‌گیری:
public class ReportService
{
    private readonly AppDbContext _context;
    private readonly CurrencyService _currencyService;

    public ReportService(AppDbContext context, CurrencyService currencyService)
    {
        _context = context;
        _currencyService = currencyService;
    }

    public List<TransactionViewModel> GetTransactions(CurrencyUnit displayCurrency)
    {
        return _context.Transactions
            .Select(t => new TransactionViewModel
            {
                Id = t.Id,
                Amount = _currencyService.ConvertFromQeran(t.AmountInQeran, displayCurrency),
                Currency = displayCurrency,
                Date = t.Date,
                Notes = t.Notes
            })
            .ToList();
    }
}
مثال استفاده:
var reportService = new ReportService(dbContext, currencyService);
var transactions = reportService.GetTransactions(CurrencyUnit.Toman);
// تراکنش با ۵۰۰ قِران به ۵,۰۰۰ تومان تبدیل می‌شود
نمایش در رابط کاربری (Razor):
@foreach (var transaction in Model.Transactions)
{
    <tr>
        <td>@transaction.Amount.ToString("N2") @transaction.Currency</td>
        <td>@transaction.Date.ToString("yyyy-MM-dd")</td>
        <td>@transaction.Notes</td>
    </tr>
}
ویژگی‌ها:
  • تبدیل در زمان نمایش: مقادیر به قِران ذخیره می‌شوند و فقط در زمان نمایش یا گزارش‌گیری به واحد انتخاب‌شده تبدیل می‌شوند.
  • انعطاف‌پذیری: کاربر می‌تواند واحد نمایش (قِران، ریال جدید، ریال فعلی، تومان) را از منوی کشویی انتخاب کند.

۸. تست‌های واحد
تست‌های واحد برای اطمینان از صحت تبدیل‌ها:
public class CurrencyServiceTests
{
    private readonly CurrencyService _service = new();

    [Fact]
    public void ConvertFromQeran_ToRialNew_ReturnsCorrectValue()
    {
        var result = _service.ConvertFromQeran(500m, CurrencyUnit.RialNew);
        Assert.Equal(5m, result); // ۵۰۰ قِران = ۵ ریال جدید
    }

    [Fact]
    public void ConvertToQeran_FromToman_ReturnsCorrectValue()
    {
        var result = _service.ConvertToQeran(5000m, CurrencyUnit.Toman);
        Assert.Equal(500m, result); // ۵,۰۰۰ تومان = ۵۰۰ قِران
    }

    [Fact]
    public void Convert_SameCurrency_ReturnsSameAmount()
    {
        var result = _service.Convert(500m, CurrencyUnit.Qeran, CurrencyUnit.Qeran);
        Assert.Equal(500m, result); // بدون تغییر
    }
}

۹. ملاحظات اضافی
الف. انطباق با دوره گذار
  • در دوره گذار (تا ۱۴۰۷)، کاربران ممکن است از ریال فعلی یا تومان برای ورودی استفاده کنند. سیستم با تبدیل همه ورودی‌ها به قِران، این نیاز را برآورده می‌کند.
  • نمایش چندواحدی در رابط کاربری به کاربران کمک می‌کند تا با واحدهای مختلف (مثل تومان) راحت‌تر کار کنند.

ب. رابط کاربری کاربرپسند
برای جلوگیری از سردرگمی، در کنار منوی کشویی، یک جدول تبدیل در رابط کاربری نمایش دهید؛ مثال: “۵۰۰ قِران = ۵ ریال جدید = ۵۰,۰۰۰ ریال فعلی = ۵,۰۰۰ تومان”


ج. انطباق با قوانین
  • اطمینان حاصل کنید که گزارش‌های مالی به ریال جدید (واحد رسمی) ارائه می‌شوند، اما پشتیبانی از قِران و تومان در رابط کاربری حفظ شود.
  • تاریخچه تراکنش‌ها (به قِران) برای حسابرسی قانونی ذخیره شود.

۱۰. جمع‌بندی
با استفاده از enum برای واحدهای پولی و دیکشنری برای نرخ‌های تبدیل، سیستم شما ساده‌تر و کارآمدتر خواهد بود. این رویکرد با فرض ثابت بودن نرخ‌های تبدیل و ذخیره صرفاً قِران در پایگاه داده، پیچیدگی را به حداقل می‌رساند. برای پیاده‌سازی:
  • واحدهای پولی را با CurrencyUnit enum تعریف کنید.
  • نرخ‌های تبدیل را در دیکشنری CurrencyConversionRates ذخیره کنید.
  • سرویس تبدیل را برای استفاده از دیکشنری تهیه کنید.
  • تراکنش‌ها را فقط به قِران در پایگاه داده ذخیره کنید.
  • رابط کاربری را با منوی کشویی و نمایش چندواحدی در زمان گزارش‌گیری طراحی کنید.
  • تست‌های واحد برای اطمینان از صحت تبدیل‌ها بنویسید.

نظرات

  • مرتضی قلمبر در ۱۴۰۴/۰۵/۱۶ ۱۱:۰۹
    تشکر بخاطر مطلبتون
    گفتید که مثال: اگر قیمت یک کالا ۲۵۰,۰۰۰ ریال فعلی باشد، معادل ۲۵,۰۰۰ ریال جدید یا ۲۵۰ قران است.
    که ۲۵۰,۰۰۰ ریال فعلی معادل جدیدش 25 ریال میشه و....

    و اینکه تو لینک خبرگزاری گفته شده :
    ظرف دو سال زیرساخت‌های لازم برای اجرای این اصلاحات را فراهم کند و دوره سه ساله‌ای نیز به عنوان دوره گذار در نظر گرفته شده .... و درنهایت پس از پنج سال ...
    یعنی از سال 1407 دوره گذار شروع میشه (برداشت من این هستش)
    • وحید نصیری در ۱۴۰۴/۰۵/۱۶ ۱۱:۴۷
      بله. ممنون از اصلاح؛ برای قیمت کالا (۲۵۰,۰۰۰ ریال فعلی یا 250000 RialOld)، معادل:
      • ریال جدید: ۲۵۰,۰۰۰ ÷ ۱۰,۰۰۰ = ۲۵ ریال جدید (RialNew).
      • قِران: ۲۵۰,۰۰۰ ÷ ۱۰۰ = ۲,۵۰۰ قِران (Qeran).
      • تومان: ۲۵۰,۰۰۰ ÷ ۱۰ = ۲۵,۰۰۰ تومان (Toman).

      البته جدول و دیکشنری تبدیلات CurrencyConversionRates.Rates ارائه شده در مطلب، درست است و نیازی به تغییری ندارد.