طراحی سیستمهای مالی ایرانی با واحد پولی جدید
نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۵/۱۶ ۰۸:۰۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
| از واحد | به واحد | نرخ تبدیل |
| قِران | ریال جدید | ۱ قِران = ۰.۰۱ ریال جدید |
| قِران | ریال فعلی | ۱ قِران = ۱۰۰ ریال فعلی |
| قِران | تومان | ۱ قِران = ۱۰ تومان |
| ریال جدید | قِران | ۱ ریال جدید = ۱۰۰ قِران |
| ریال فعلی | قِران | ۱ ریال فعلی = ۰.۰۱ قِران |
| تومان | قِران | ۱ تومان = ۰.۱ قِران |
2500 در پایگاه داده ذخیره کنید.decimal استفاده کنید.decimal؟ نوع داده decimal به طور خاص برای محاسبات دقیق مالی طراحی شده و از مشکلات دقت شناور (Floating-point Precision) که در انواع float یا double وجود دارد، جلوگیری میکند. این امر در سیستمهای مالی که حتی کوچکترین خطا نیز میتواند منجر به مشکلات بزرگ شود، حیاتی است.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...
}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 valuedecimal برای تمامی فیلدهای مالی در مدلها و پایگاه داده استفاده کنید.public enum CurrencyUnit
{
Qeran, // قِران
RialNew, // ریال جدید
RialOld, // ریال فعلی
Toman // تومان
}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; } // یادداشتها (اختیاری)
}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); // ۵ ریال جدید = ۵۰۰ قِران
<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>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); // تراکنش با ۵۰۰ قِران به ۵,۰۰۰ تومان تبدیل میشود
@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); // بدون تغییر
}
}CurrencyUnit enum تعریف کنید.CurrencyConversionRates ذخیره کنید.