twmbx / go-money

Go implementation of Fowler's Money pattern

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Money

alt text

Go Report Card Coverage Status Build Status GoDoc License: MIT

GoMoney provides ability to work with monetary value using a currency's smallest unit. Package allows you to use basic Money operations like rounding, splitting or allocating without losing a penny. You shouldn't use float for monetary values, since they always carry small rounding differences.

package main

import "github.com/rhymond/go-money"

func main() {
	pound := money.New(100, "GBP")
	twoPounds := pound.Add(pound)

	parties, _ := twoPounds.Split(3)
	parties[0].Display() // £0.67
	parties[1].Display() // £0.67
	parties[2].Display() // £0.66
}

Quick start

Get the package via

$ go get github.com/rhymond/go-money

Features

  • Provides a Money struct which stores information about an Money amount value and it's currency.
  • Provides a Money.Amount struct which encapsulates all information about a monetary unit.
  • Represents monetary values as integers, in cents. This avoids floating point rounding errors.
  • Represents currency as Money.Currency instances providing a high level of flexibility.

Usage

Instantiation

Initialise Money by using smallest unit value (e.g 100 represents 1 pound). Use ISO 4217 Currency Code to set money Currency

pound := money.New(100, "GBP")

Comparison

Go-money lets you to use base compare operations like:

  • Equals
  • GreaterThan
  • GreaterThanOrEqual
  • LessThan
  • LessThanOrEqual

In order to use them currencies must be equal

pound := money.New(100, "GBP")
twoPounds := money.New(200, "GBP")
twoEuros := money.New(200, "EUR")

pound.GreaterThan(twoPounds) // false, nil
pound.LessThan(twoPounds) // true, nil
twoPounds.Equals(twoEuros) // false, error: Currencies don't match

Asserts

  • IsZero
  • IsNegative
  • IsPositive

Zero value

To assert if Money value is equal zero use IsZero()

pound := money.New(100, "GBP")
result := pound.IsZero(pound) // false

Positive value

To assert if Money value is more than zero IsPositive()

pound := money.New(100, "GBP")
pound.IsPositive(pound) // true

Negative value

To assert if Money value is less than zero IsNegative()

pound := money.New(100, "GBP")
pound.IsNegative(pound) // false

Operations

  • Add
  • Subtract
  • Divide
  • Multiply
  • Absolute
  • Negative

In Order to use operations between Money structures Currencies must be equal

Addition

Additions can be performed using Add().

pound := money.New(100, "GBP")
twoPounds := money.New(200, "GBP")
 
result, err := pound.Add(twoPounds).Display() // £3.00, nil

Subtraction

Subtraction can be performed using Subtract().

pound := money.New(100, "GBP")
twoPounds := money.New(200, "GBP")
 
result, err := pound.Subtract(twoPounds).Display() // -£1.00, nil

Multiplication

Multiplication can be performed using Multiply().

pound := money.New(100, "GBP")
 
result, err := pound.Multiply(2).Display() // £2.00, nil

Division

Division can be performed using Divide().

pound := money.New(100, "GBP")
 
result, err := pound.Divide(2).Display() // £0.50, nil

There is possibilities to lose pennies by using division operation e.g:

money.New(100, "GBP").Divide(3).Display() // £0.33

In order to split amount without losing pennies use Split() operation.

Absolute

Return absolute value of Money structure

pound := money.New(-100, "GBP")
 
result, err := pound.Absolute().Display() // £1.00

Negative

Return negative value of Money structure

pound := money.New(100, "GBP")
 
result, err := pound.Negative().Display() // -£1.00

Allocation

  • Split
  • Allocate

Splitting

In order to split Money for parties without losing any penny use Split().

After division leftover pennies will be distributed round-robin amongst the parties. This means that parties listed first will likely receive more pennies than ones that are listed later

pound := money.New(100, "GBP")
parties, err := pound.Split(3)

parties[0].Display() // £0.34
parties[1].Display() // £0.33
parties[2].Display() // £0.33

Allocation

To perform allocation operation use Allocate().

It lets split money by given ratios without losing pennies and as Split operations distributes leftover pennies amongst the parties with round-robin principle.

pound := money.New(100, "GBP")
parties, err := pound.Split([]int{33, 33, 33})

parties[0].Display() // £0.34
parties[1].Display() // £0.33
parties[2].Display() // £0.33

Format

To format and return Money as string use Display().

money.New(123456789, "EUR").Display() // €1,234,567.89

Contributing

Thank you for considering contributing! Please use GitHub issues and Pull Requests for Contributing.

License

The MIT License (MIT). Please see License File for more information.

forthebadge

About

Go implementation of Fowler's Money pattern

License:MIT License


Languages

Language:Go 100.0%