Money

Introduction

When dealing with money you should install the “Kit.Money” module. This gives you access to an “Amount” type which you should always use for any properties that deal with money.

When displaying an amount you should always use midpoint rounding. For example:

Math.Round(amount, 2, MidpointRounding.AwayFromZero)

Alternatively you can use the following extension method:

amount.Round()

You can say the following to display the currency symbol as well:

amount.ToString()

Or use the following to display in another culture:

amount.ToString(culture)

Note: When saying ToString() it uses midpoint rounding.

Structure

Amount

  • Currency – If the currency is null then you should assume the amount is in the base currency.
  • Value
  • ToString() – This is equivalent to saying amount.Value.ToString(“c”).
  • ToString(CultureInfo culture) – Same as saying amount.Value.ToString(“c”, culture.NumberFormat).
  • ToString(string format) – Allows you to display the amount in your own format.
  • ToString(string format, CultureInfo culture) – Same as saying amount.Value.ToString(format, culture.NumberFormat).

Currency

  • Code
  • ExchangeRate

Note: The base currency is the currency which has an exchange rate of 1.

Amount (Exchange Extensions)

  • ConvertTo(Currency currency, decimal? fromExchangeRate = null) – Converts the amount to another currency. The fromExchangeRate is the exchange rate the money is currently in. If null then it assumes the exchange rate is the currencies’ exchange rate.
  • ConvertToBase(decimal? fromExchangeRate = null) – This calls the above method feeding in the base currency.

Amount (Tax Extensions)

  • GetTax(decimal taxRate) – Get the rounded tax based on the tax rate.
  • GetIncTax(decimal taxRate) – Get the rounded amount including tax based on the tax rate.

Displaying

In the currency set against the amount:

@amount

Or in another currency:

@amount.ConvertTo(currency)

Or you can use the following to convert to the base currency:

@amount.ConvertToBase()

Mapping

Without a currency (there is a convention to automatically map an Amount):

Property(x => x.Amount);

With a currency:

Property(x => x.Amount, m => {
    m.Type<AmountWithCurrencyType>();
    m.Columns(x => x.Name("CurrencyCode"), x => x.Name("Amount"));
});

Note: When mapping using a AmountWithCurrencyType it will order it by the Currency and then the Amount (e.g. “CurrencyCode, Amount ASC/DESC”). This is fine to say if the collection you are ordering by has the same currency.

Where the currency is stored in another table or the currency applies to multiple fields you would change the property to:

private Amount _amount;
public virtual Amount Amount {
    get {
        if (!_amount.Currency.Equals(Currency))
            _amount = _amount.SetCurrency(Currency);
        return _amount;
    }
    set { _amount = value; }
}

When logging the exchange rate at the time of the order you can map this using the above method, however you would need to make sure you always pass the exchange rate when displaying the money in another currency. E.g.:

@amount.ConvertToBase(exchangeRate)

Alternatively, you can make sure when you get the currency you create a copy with the exchange rate. For example:

private Currency _currency;
public virtual Currency Currency {
    get {
        if (_currency == null)
            _currency = Currency.Get(CurrencyCode).Copy(ExchangeRate);
        return _currency;
    }
}

Now you can simply say the following when converting to another currency:

@amount.ConvertToBase()

Client-side

Money is automatically serialized to and from an amount including the currency in the format `${amount} ${currencyCode}`. If the currency is omitted then it is assumed it is in the base currency. To display an amount you simply say:

formatCurrency(amount)

This will automatically display the amount in the correct currency. If you would like to display an amount inclusive of tax then you can pass in the tax rate as the second parameter. For example:

formatCurrency(amount, 20)

If you would like to update the value from an element then first you should make sure it is data-bound (using v-model), now you can say something like:

import { getComponent } from 'component-utils';
import { ready } from 'utils';

ready(context => {
    const listComponent = getComponent(document.getElementById('list'));
    listComponent.products[0].price = '100 USD';
});

If you would like to set the just the currency then you would simply say:

listComponent.products[0].price = `${listComponent.products[0].price} USD`;