Documentation ¶
Index ¶
- Constants
- Variables
- func AmountToFloat64(amount Amount) float64
- func NetAmount(gross int64, rate float64) (int64, error)
- func RatNetAmount(gross, rate *big.Rat) (*big.Float, error)
- func TaxAmount(gross, net int64) (int64, error)
- func ValidateFloatIsPrecise(f float64) error
- func ValidateManyFloatsArePrecise(args ...float64) error
- type Amount
- type ErrFloatPrecision
Examples ¶
Constants ¶
const ( // QuadruplePrecision describes 128 bits of precision for IEEE 754 decimals // see: https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format QuadruplePrecision uint = 128 // OctuplePrecision describes 256 bits of precision for for IEEE 754 decimals // see: https://en.wikipedia.org/wiki/Octuple-precision_floating-point_format OctuplePrecision uint = 256 )
Variables ¶
var ( // ErrSubZeroRate happens when a rate is lower than zero. ErrSubZeroRate = errors.New("rate must not be less than zero") // ErrSubZeroGross happens when the gross amount is less than zero. ErrSubZeroGross = errors.New("gross amount must not be less than zero") // ErrSubZeroNet happens when the net amount is less than zero. ErrSubZeroNet = errors.New("net amount must not be less than zero") // ErrNetOverGrossAmount happens when the net amount is higher than the gross amount. ErrNetOverGrossAmount = errors.New("net amount must be equal to or lower than the gross amount") )
Functions ¶
func AmountToFloat64 ¶
AmountToFloat64 returns the currency data as a floating point from it's minor currency unit format.
func RatNetAmount ¶
RatNetAmount applies a VAT rate to a big.Rat value. This method returns a big.Float so it's accuracy can be checked, and it's value applied with .Rat(some.field)
func ValidateFloatIsPrecise ¶
ValidateFloatIsPrecise ensures that a float64 value does not exceed a precision of 2 digits past the decimal period. This ensures we do not store incorrect currency data. NOTE: 2 digits past the decimal period is a business rule.
func ValidateManyFloatsArePrecise ¶
ValidateManyFloatsArePrecise tests that the given float64 arguments have the desired precision, this is a convenience wrapper around ValidateFloatIsPrecise. NOTE: 2 digits past the dot is a business rule.
Types ¶
type Amount ¶
Amount defines an amount in a given currency, in it's minor unit form.
func Exchange ¶
Exchange - Apply currency exchange rates to an amount.
rate - should always be given from the approved finance list. NOTE: A rate of zero will return the amount you put in, unchanged.
Rounding to the nearest even is a defined business rule. Tills may round up to the nearest penny, but for reporting, the rule is always to use banker's rounding.
If unclear, see: // http://wiki.c2.com/?BankersRounding.
Example (Usd_eur) ¶
package main import ( "fmt" "github.com/LUSHDigital/core-lush/accounting" "github.com/LUSHDigital/core-lush/accounting/currency" ) func main() { // 4 May 2020 08:00 UTC - 5 May 2020 08:01 UTC // EUR/USD close:1.08968 low:1.08871 high:1.09479 usd := accounting.Float64ToAmount(currency.USD, 100.0) eur, err := accounting.Exchange(usd, currency.EUR, 1.08968) if err != nil { // handle... } fmt.Println(eur) }
Output: 91.77 EUR
Example (Usd_jpy) ¶
package main import ( "fmt" "github.com/LUSHDigital/core-lush/accounting" "github.com/LUSHDigital/core-lush/accounting/currency" ) func main() { // 4 May 2020 07:40 UTC - 5 May 2020 07:40 UTC // JPY/USD close:0.00937 low:0.00934 high:0.00939 usd := accounting.Float64ToAmount(currency.USD, 100.0) jpy, err := accounting.Exchange(usd, currency.JPY, 0.00937) if err != nil { // handle... } fmt.Println(jpy) }
Output: 10672 JPY
func Float64ToAmount ¶
Float64ToAmount returns an amount from the provided currency and value.
Example (Gbp) ¶
package main import ( "fmt" "github.com/LUSHDigital/core-lush/accounting" "github.com/LUSHDigital/core-lush/accounting/currency" ) func main() { gbp := accounting.Float64ToAmount(currency.GBP, 32.32) fmt.Printf("minor value: %d, stringer: %s", gbp.MinorValue, gbp) }
Output: minor value: 3232, stringer: 32.32 GBP
Example (Jpy) ¶
package main import ( "fmt" "github.com/LUSHDigital/core-lush/accounting" "github.com/LUSHDigital/core-lush/accounting/currency" ) func main() { // JPY doesn't allow for values after the decimal dot, since it has a // minor currency unit of 1. jpy := accounting.Float64ToAmount(currency.JPY, 32.32) fmt.Printf("minor value: %d, stringer: %s", jpy.MinorValue, jpy) }
Output: minor value: 32, stringer: 32 JPY
func MakeAmount ¶
MakeAmount returns an Amount from the provided currency and minor unit value.
func (Amount) String ¶
String implements a default stringer for an Amount Note that the string will be in "human readable" format, rather than using the minor currency unit, this conversion is done using the AmountToFloat64 function, also available within this package. ISO_4217 does not regulate spacing or prefixing vs. suffixing. Strings produced using this method always follow this pattern:
┏━━ always decimal dot separated. ┃ 123.45 GBP ┃ ┗━━ ISO currency code. ┗━━ maximum 2 digits precision.
type ErrFloatPrecision ¶
ErrFloatPrecision happens when a floating point number is not following business precision rules.
func (ErrFloatPrecision) Error ¶
func (e ErrFloatPrecision) Error() string