Documentation
¶
Overview ¶
Package money provides functionality for handling monetary values.
It is a value object that represents a monetary value in a specific currency. Invariants:
- Amount is always stored in the smallest currency unit (e.g., cents for USD).
- Currency code must be valid ISO 4217 (3 uppercase letters).
- All arithmetic operations require matching currencies.
Index ¶
- Variables
- type Amount
- type CurrencyConverter
- type ExchangeRate
- type Money
- func ConvertMoney(converter CurrencyConverter, m Money, to string) (Money, *common.ConversionInfo, error)
- func Must(amount float64, currencyCode currency.Code) Money
- func New(amount float64, currencyCode currency.Code) (money Money, err error)
- func NewFromData(amount int64, cc string) Money
- func NewFromSmallestUnit(amount int64, currencyCode currency.Code) (money Money, err error)
- func Zero(cur currency.Code) Money
- func (m Money) Abs() Money
- func (m Money) Add(other Money) (Money, error)
- func (m Money) Amount() Amount
- func (m Money) AmountFloat() float64
- func (m Money) Currency() currency.Code
- func (m Money) Divide(divisor float64) (Money, error)
- func (m Money) Equals(other Money) bool
- func (m Money) GreaterThan(other Money) (bool, error)
- func (m Money) IsCurrency(code string) bool
- func (m Money) IsNegative() bool
- func (m Money) IsPositive() bool
- func (m Money) IsSameCurrency(other Money) bool
- func (m Money) IsZero() bool
- func (m Money) LessThan(other Money) (bool, error)
- func (m Money) MarshalJSON() ([]byte, error)
- func (m Money) Multiply(factor float64) (Money, error)
- func (m Money) Negate() Money
- func (m Money) String() string
- func (m Money) Subtract(other Money) (Money, error)
- func (m *Money) UnmarshalJSON(data []byte) error
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrExchangeRateUnavailable = errors.New("exchange rate service unavailable") // ErrUnsupportedCurrencyPair indicates the currency pair is not supported. ErrUnsupportedCurrencyPair = errors.New("unsupported currency pair") // ErrExchangeRateExpired indicates the exchange rate data is stale or expired. ErrExchangeRateExpired = errors.New("exchange rate has expired") // ErrExchangeRateInvalid indicates the received exchange rate is invalid. ErrExchangeRateInvalid = errors.New("invalid exchange rate received") )
Functions ¶
This section is empty.
Types ¶
type Amount ¶
type Amount = int64
Amount represents a monetary amount as an integer in the smallest currency unit (e.g., cents for USD).
type CurrencyConverter ¶
type CurrencyConverter interface {
// Convert converts an amount from one currency to another.
// Returns the converted amount and the rate used, or an error if conversion is not possible.
Convert(amount float64, from, to string) (*common.ConversionInfo, error)
// GetRate returns the current exchange rate between two currencies.
// This is useful for displaying rates without performing a conversion.
GetRate(from, to string) (float64, error)
// IsSupported checks if a currency pair is supported by the converter.
IsSupported(from, to string) bool
}
CurrencyConverter defines the interface for converting amounts between currencies.
type ExchangeRate ¶
type ExchangeRate struct {
FromCurrency string
ToCurrency string
Rate float64
LastUpdated time.Time
Source string
ExpiresAt time.Time
}
ExchangeRate represents a single exchange rate with metadata.
type Money ¶
type Money struct {
// contains filtered or unexported fields
}
Money represents a monetary value in a specific currency. Invariants:
- Amount is always stored in the smallest currency unit (e.g., cents for USD).
- Currency code must be valid ISO 4217 (3 uppercase letters).
- All arithmetic operations require matching currencies.
Example (Comparison) ¶
ExampleMoney_Comparison demonstrates comparing money values
// Create two USD amounts
money1, _ := New(100.50, currency.USD)
money2, _ := New(75.25, currency.USD)
// Compare them
greater, _ := money1.GreaterThan(money2)
equal := money1.Equals(money2)
less, _ := money1.LessThan(money2)
fmt.Printf("Greater than: %t\n", greater)
fmt.Printf("Equal: %t\n", equal)
fmt.Printf("Less than: %t\n", less)
Output: Greater than: true Equal: false Less than: false
func ConvertMoney ¶
func ConvertMoney( converter CurrencyConverter, m Money, to string, ) (Money, *common.ConversionInfo, error)
ConvertMoney converts a Money value object to the target currency using the converter. Returns a new Money object in the target currency and the conversion info.
func Must ¶
Must creates a Money object from the given amount and currency code. Invariants enforced:
- Currency code must be valid ISO 4217 (3 uppercase letters).
- Amount must not have more decimal places than allowed by the currency.
- Amount is converted to the smallest currency unit.
Panics if any invariant is violated.
func New ¶
New creates a new Money value object with the given amount and currency code. Invariants enforced:
- Currency code must be valid ISO 4217 (3 uppercase letters).
- Amount must not have more decimal places than allowed by the currency.
- Amount is converted to the smallest currency unit.
Returns Money or an error if any invariant is violated.
Example ¶
ExampleNew demonstrates how to create a new Money instance
// Create money with USD
usdMoney, err := New(100.50, currency.USD)
if err != nil {
log.Fatal(err)
}
fmt.Printf("USD Money: %s\n", usdMoney.String())
// Create money with EUR
eurMoney, err := New(75.25, currency.EUR)
if err != nil {
log.Fatal(err)
}
fmt.Printf("EUR Money: %s\n", eurMoney.String())
// Create money with JPY (0 decimals)
jpyMoney, err := New(1000, currency.Code("JPY"))
if err != nil {
log.Fatal(err)
}
fmt.Printf("JPY Money: %s\n", jpyMoney.String())
Output: USD Money: 100.50 USD EUR Money: 75.25 EUR JPY Money: 1000 JPY
func NewFromData ¶
NewFromData creates a Money object from raw data (used for DB hydration). This bypasses invariants and should only be used for repository hydration or tests. Deprecated: use NewFromSmallestUnit instead.
func NewFromSmallestUnit ¶
NewFromSmallestUnit creates a new Money object from the smallest currency unit. Invariants enforced:
- Currency code must be valid ISO 4217 (3 uppercase letters).
Returns Money or an error if any invariant is violated.
Example ¶
ExampleNewFromSmallestUnit demonstrates creating money from smallest unit
// Create USD money from cents (smallest unit)
usdMoney, err := NewFromSmallestUnit(10050, currency.USD) // 100.50 USD
if err != nil {
log.Fatal(err)
}
fmt.Printf("USD from cents: %s\n", usdMoney.String())
// Create JPY money from yen (smallest unit)
jpyMoney, err := NewFromSmallestUnit(1000, currency.Code("JPY")) // 1000 JPY
if err != nil {
log.Fatal(err)
}
fmt.Printf("JPY from yen: %s\n", jpyMoney.String())
Output: USD from cents: 100.50 USD JPY from yen: 1000 JPY
func (Money) Add ¶
Add adds another Money object to the current Money object. Invariants enforced:
- Currencies must match.
Returns Money or an error if currencies do not match.
Example ¶
ExampleMoney_Add demonstrates adding money values
// Create two USD amounts
money1, _ := New(100.50, currency.USD)
money2, _ := New(25.75, currency.USD)
// Add them together
result, err := money1.Add(money2)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Result: %s\n", result.String())
Output: Result: 126.25 USD
func (Money) Amount ¶
Amount returns the amount of the Money object in the smallest currency unit.
Example ¶
ExampleMoney_Amount demonstrates getting the amount
// Create money with different amounts
money1, _ := New(100.50, currency.USD)
money2, _ := New(1000, currency.Code("JPY"))
fmt.Printf("USD amount: %.2f\n", money1.AmountFloat())
fmt.Printf("JPY amount: %.0f\n", money2.AmountFloat())
Output: USD amount: 100.50 JPY amount: 1000
func (Money) AmountFloat ¶
AmountFloat returns the amount as a float64 in the main currency unit (e.g., dollars for USD). Invariants enforced:
- Currency metadata must be valid.
Example ¶
ExampleMoney_AmountFloat demonstrates getting the amount as float64
// Create money with different amounts
money1, _ := New(100.50, currency.USD)
money2, _ := New(1000, currency.Code("JPY"))
fmt.Printf("USD amount float: %.2f\n", money1.AmountFloat())
fmt.Printf("JPY amount float: %.0f\n", money2.AmountFloat())
Output: USD amount float: 100.50 JPY amount float: 1000
func (Money) Currency ¶
Currency returns the currency of the Money object.
Example ¶
ExampleMoney_Currency demonstrates getting the currency
// Create money with different currencies
usdMoney, _ := New(100.50, currency.USD)
eurMoney, _ := New(75.25, currency.EUR)
jpyMoney, _ := New(1000, currency.Code("JPY"))
fmt.Printf("USD Money currency: %s\n", usdMoney.Currency())
fmt.Printf("EUR Money currency: %s\n", eurMoney.Currency())
fmt.Printf("JPY Money currency: %s\n", jpyMoney.Currency())
Output: USD Money currency: USD EUR Money currency: EUR JPY Money currency: JPY
func (Money) Divide ¶
Divide divides the Money amount by a scalar divisor. Invariants enforced:
- Divisor must not be zero.
- Result must not overflow int64.
- Division must not lose precision.
Returns Money or an error if any invariant is violated.
Example ¶
ExampleMoney_Divide demonstrates dividing money by a factor
// Create USD amount
money, _ := New(100.50, currency.USD)
// Divide by 2
result, err := money.Divide(2)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Result: %s\n", result.String())
Output: Result: 50.25 USD
func (Money) Equals ¶
Equals checks if the current Money object is equal to another Money object. Invariants enforced:
- Currencies must match.
Returns false if currencies do not match.
func (Money) GreaterThan ¶
GreaterThan checks if the current Money object is greater than another Money object. Invariants enforced:
- Currencies must match.
Returns an error if currencies do not match.
func (Money) IsCurrency ¶
Is checks the currency code if the same as money object
func (Money) IsNegative ¶
IsNegative returns true if the amount is less than zero.
func (Money) IsPositive ¶
IsPositive returns true if the amount is greater than zero.
Example ¶
ExampleMoney_IsPositive demonstrates checking if money is positive
// Create positive and negative amounts
positive, _ := New(100.50, currency.USD)
negative, _ := New(-25.75, currency.USD)
zero, _ := New(0, currency.USD)
fmt.Printf("Positive amount is positive: %t\n", positive.IsPositive())
fmt.Printf("Negative amount is positive: %t\n", negative.IsPositive())
fmt.Printf("Zero amount is positive: %t\n", zero.IsPositive())
Output: Positive amount is positive: true Negative amount is positive: false Zero amount is positive: false
func (Money) IsSameCurrency ¶
IsSameCurrency checks if the current Money object has the same currency as another Money object.
func (Money) IsZero ¶
IsZero returns true if the amount is zero.
Example ¶
ExampleMoney_IsZero demonstrates checking if money is zero
// Create positive and zero amounts
positive, _ := New(100.50, currency.USD)
zero, _ := New(0, currency.USD)
fmt.Printf("Positive amount is zero: %t\n", positive.IsZero())
fmt.Printf("Zero amount is zero: %t\n", zero.IsZero())
Output: Positive amount is zero: false Zero amount is zero: true
func (Money) LessThan ¶
LessThan checks if the current Money object is less than another Money object. Invariants enforced:
- Currencies must match.
Returns an error if currencies do not match.
func (Money) MarshalJSON ¶
MarshalJSON implements json.Marshaler interface.
func (Money) Multiply ¶
Multiply multiplies the Money amount by a scalar factor. Invariants enforced:
- Result must not overflow int64.
Returns Money or an error if overflow would occur.
Example ¶
ExampleMoney_Multiply demonstrates multiplying money by a factor
// Create USD amount
money, _ := New(100.50, currency.USD)
// Multiply by 2.5
result, err := money.Multiply(2.5)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Result: %s\n", result.String())
Output: Result: 251.25 USD
func (Money) String ¶
String returns a string representation of the Money object.
Example ¶
ExampleMoney_String demonstrates string representation
// Create money with different currencies
usdMoney, _ := New(100.50, currency.USD)
eurMoney, _ := New(75.25, currency.EUR)
jpyMoney, _ := New(1000, currency.Code("JPY"))
fmt.Printf("USD: %s\n", usdMoney.String())
fmt.Printf("EUR: %s\n", eurMoney.String())
fmt.Printf("JPY: %s\n", jpyMoney.String())
Output: USD: 100.50 USD EUR: 75.25 EUR JPY: 1000 JPY
func (Money) Subtract ¶
Subtract subtracts another Money object from the current Money object. Invariants enforced:
- Currencies must match.
Returns Money or an error if currencies do not match.
Example ¶
ExampleMoney_Subtract demonstrates subtracting money values
// Create two USD amounts
money1, _ := New(100.50, currency.USD)
money2, _ := New(25.75, currency.USD)
// Subtract the second from the first
result, err := money1.Subtract(money2)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Result: %s\n", result.String())
Output: Result: 74.75 USD
func (*Money) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler interface.