Yimaru-BackEnd/internal/domain/currency.go

142 lines
4.3 KiB
Go

package domain
import (
"errors"
"fmt"
"math"
"time"
)
type Currency int64
// ToCurrency converts a float32 (like 12.34) into Currency (stored in cents).
func ToCurrency(f float32) Currency {
cents := math.Round(float64(f) * 100) // avoid float32 precision issues
return Currency(int64(cents))
}
// Float32 converts a Currency back into float32 (like 12.34).
func (m Currency) Float32() float32 {
return float32(m) / 100
}
// String returns a formatted Currency value for display.
func (m Currency) String() string {
return fmt.Sprintf("$%.2f", m.Float32())
}
// TODO: Change the currency to this format when implementing multi-currency
// type Currency struct {
// Value int64
// Type IntCurrency
// }
// // ToCurrency converts a float32 (like 12.34) into Currency (stored in cents).
// func NewCurrency(f float32, currencyType IntCurrency) Currency {
// cents := math.Round(float64(f) * 100) // avoid float32 precision issues
// return Currency{
// Value: int64(cents),
// Type: currencyType,
// }
// }
// func NewBase(v int64) Currency {
// return Currency{
// Value: v,
// Type: BASE,
// }
// }
// // Float32 converts a Currency back into float32 (like 12.34).
// func (m Currency) Float32() float32 {
// return float32(m.Value) / 100
// }
// // String returns a formatted Currency value for display.
// func (m Currency) String() string {
// return fmt.Sprintf("$%.2f", m.Float32())
// }
type IntCurrency string
const (
BASE IntCurrency = "BASE"
ETB IntCurrency = "ETB" // Ethiopian Birr
NGN IntCurrency = "NGN" // Nigerian Naira
ZAR IntCurrency = "ZAR" // South African Rand
EGP IntCurrency = "EGP" // Egyptian Pound
KES IntCurrency = "KES" // Kenyan Shilling
UGX IntCurrency = "UGX" // Ugandan Shilling
TZS IntCurrency = "TZS" // Tanzanian Shilling
RWF IntCurrency = "RWF" // Rwandan Franc
BIF IntCurrency = "BIF" // Burundian Franc
XOF IntCurrency = "XOF" // West African CFA Franc (BCEAO)
XAF IntCurrency = "XAF" // Central African CFA Franc (BEAC)
GHS IntCurrency = "GHS" // Ghanaian Cedi
SDG IntCurrency = "SDG" // Sudanese Pound
SSP IntCurrency = "SSP" // South Sudanese Pound
DZD IntCurrency = "DZD" // Algerian Dinar
MAD IntCurrency = "MAD" // Moroccan Dirham
TND IntCurrency = "TND" // Tunisian Dinar
LYD IntCurrency = "LYD" // Libyan Dinar
MZN IntCurrency = "MZN" // Mozambican Metical
AOA IntCurrency = "AOA" // Angolan Kwanza
BWP IntCurrency = "BWP" // Botswana Pula
ZMW IntCurrency = "ZMW" // Zambian Kwacha
MWK IntCurrency = "MWK" // Malawian Kwacha
LSL IntCurrency = "LSL" // Lesotho Loti
NAD IntCurrency = "NAD" // Namibian Dollar
SZL IntCurrency = "SZL" // Swazi Lilangeni
CVE IntCurrency = "CVE" // Cape Verdean Escudo
GMD IntCurrency = "GMD" // Gambian Dalasi
SLL IntCurrency = "SLL" // Sierra Leonean Leone
LRD IntCurrency = "LRD" // Liberian Dollar
GNF IntCurrency = "GNF" // Guinean Franc
XCD IntCurrency = "XCD" // Eastern Caribbean Dollar (used in Saint Lucia)
MRU IntCurrency = "MRU" // Mauritanian Ouguiya
KMF IntCurrency = "KMF" // Comorian Franc
DJF IntCurrency = "DJF" // Djiboutian Franc
SOS IntCurrency = "SOS" // Somali Shilling
ERN IntCurrency = "ERN" // Eritrean Nakfa
MGA IntCurrency = "MGA" // Malagasy Ariary
SCR IntCurrency = "SCR" // Seychellois Rupee
MUR IntCurrency = "MUR" // Mauritian Rupee
// International currencies (already listed)
USD IntCurrency = "USD" // US Dollar
EUR IntCurrency = "EUR" // Euro
GBP IntCurrency = "GBP" // British Pound
)
var (
ErrUnsupportedIntCurrency = errors.New("unsupported IntCurrency")
ErrIntCurrencyConversion = errors.New("IntCurrency conversion failed")
)
// IntCurrencyRate represents exchange rate between two currencies
type IntCurrencyRate struct {
From IntCurrency
To IntCurrency
Rate float64
ValidUntil time.Time
}
// Convert converts amount from one IntCurrency to another
func (cr IntCurrencyRate) Convert(amount float64) (float64, error) {
if time.Now().After(cr.ValidUntil) {
return 0, fmt.Errorf("%w: rate expired", ErrIntCurrencyConversion)
}
return amount * cr.Rate, nil
}
// ValidateIntCurrency checks if IntCurrency is supported
func ValidateIntCurrency(c IntCurrency) error {
switch c {
case ETB, USD, EUR, GBP:
return nil
default:
return fmt.Errorf("%w: %s", ErrUnsupportedIntCurrency, c)
}
}