Money

Специальный класс-обёртка для семантически-корректной работы с денежными суммами.

Хранит информацию о валюте и сумме с точностью, соответствующей минимальной единицей валюты. Предоставляет методы для операций с денежными суммами с "правильной" точностью и без проблем, связанных с хранением дробных значений в переменных с плавающей запятой.

Экземплярами класса Money представлены runtime-значения полей heap-таблиц, объявленных через Heap. Money.

Класс Money может быть использован для удобной работы с денежными суммами вне контекста хипа.

Применение / сигнатура

import { Money } from '@app/heap'
const moneyVal = new Money(amount, currency)

Свойства и методы

  • constructor(amount: number, currency: Currency)
    constructor(moneyLike: { amount: number, currency: Currency })
    constructor(money: Money)
    constructor(serialized: [amount: number, currency: Currency])
    Конструктор класса. Принимает на вход как другой экземпляр Money , так и другие форматы.

    • amount: number
      сумма в указанной валюте.

    • currency: Currency
      стрёхбуквенный международный код валюты (ISO 4217).

    Сумма может быть передана с любой точностью, но всегда округляется до количества знаков после запятой, указанного в стандарте ISO 4217 для выбранной валюты (используется метаинформация о валюте из встроенной в JS подсистемы Intl. Округление производится по правилу "half away from zero".

  • amount: number
    Количество (сумма) валюты, хранящееся в данном экземпляре. Хранится в виде дробного числа с точностью, соответствующей требованиям валюты по стандарту ISO 4217 (для большинства валют - это 2 знака).

  • currency: Currency
    Строка с трёхбуквенным международным кодом валюты (ISO 4217).

Арифметические операции

  • add(summand: Money): Money
    Операция сложения. Прибавляет переданную денежную сумму к текущей и возвращает результат в виде нового экземпляра Money.

    • При попытке сложить две разные валюты будет брошено исключение.
    • Операция производится с целочисленными значениями и не подвержена проблемам, связанным с операциями над числами с плавающей запятой.
    • Результат округляется в соответствии с правилами для валюты, описанными выше.
    • summand: Money
      Слагаемое - денежная сумма, которая должна быть прибавлена к текущей.
  • substract(subtracted: Money): Money
    Операция вычитания. Вычитает переданную денежную сумму из текущей и возвращает результат в виде нового экземпляра Money.

    • При попытке вычесть валюту, отличную от уменьшаемого, будет брошено исключение.
    • Операция производится с целочисленными значениями и не подвержена проблемам, связанным с операциями над числами с плавающей запятой.
    • Результат округляется в соответствии с правилами для валюты, описанными выше.
    • subtracted: Money
      Вычитаемое - денежная сумма, на которую нужно уменьшить текущую.
  • multiply(multiplier: number): Money
    Операция умножения. Умножает текущую сумму на заданный множитель и возвращает результат в виде нового экземпляра Money с исходной валютой.

    • Операция производится с целочисленными значениями и не подвержена проблемам, связанным с операциями над числами с плавающей запятой.
    • Результат округляется в соответствии с правилами для валюты, описанными выше.
    • multiplier: number
      Множитель - любое дробное или целое число.
  • divide(divider: number): Money
    Операция деления. Делит текущую сумму на заданный делитель и возвращает результат в виде нового экземпляра Money с исходной валютой.

    • Операция производится с целочисленными значениями и не подвержена проблемам, связанным с операциями над числами с плавающей запятой.
    • Результат округляется в соответствии с правилами для валюты, описанными выше.
    • divider: number
      Делитель - любое дробное или целое число, кроме нуля.

Другие методы

  • format(ctx: app. Ctx, options?: MoneyFormatOptions): string
    Возвращает строку с денежной суммой, отформатированной с помощью [Number.toLocaleString()](

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString).

    Правила локализации (по правилам какой страны/языка форматировать валюту) берутся из переданного контекста.

    • ctx: app. Ctx
      Контекст запроса, из которого метод "узнаёт" - какой код локали (в формате en-US ) использовать в конструкторе Intl.NumberFormat .

    • options: {style, currencyDisplay, signDisplay, currencySign, useGrouping, minimumIntegerDigits, minimumFractionDigits, maximumFractionDigits, minimumSignificantDigits, maximumSignificantDigits }
      Параметры форматирования. Поддерживаются почти все параметры Intl.NumberFormat. Параметр currency не поддерживается, поскольку всегда подставляется автоматически из валюты, хранящейся в экземпляре Money.

      • style: 'currency' | 'decimal' (по умолчанию 'currency')
        Выводить в виде обычного числа или числа с валютой.

      • currencyDisplay: 'symbol' | 'code' | 'name' | 'narrowSymbol' (по умолчанию 'symbol' )
        Как выводить знак валюты, если style=currency :

        • 'symbol' - локализованный символ валюты ($, €, ₽)
        • 'code' - трёхбуквенный международный код (USD, EUR, RUB)
        • 'name' - локализованное название валюты (dollar, euro, рубль)
        • 'narrowSymbol' - сокращённый символ валюты - имеет смысл для некоторых валют, которые могут иметь один и тот же символ - например в локали en-AU австралийский и американский доллары будут выводиться по-разному ($ и USD) для symbol и одинаково ($ и $) для narrowSymbol . Также в некоторых локалях по умолчанию используется международный код для иностранных валют, narrowSymbol форсирует использование короткого символа.
      • signDisplay: 'always' | 'auto' | 'exceptZero' | 'never' (по умолчанию 'auto' )
        Когда выводить знак числового значения.

        • 'always' - всегда (для нуля +)
        • 'auto' - только для положительных значений
        • 'exceptZero' - для всего кроме нуля
        • 'never' - не показывать знак
      • currencySign: 'standard' | 'accounting' (по умолчанию 'standard')
        Каким образом форматировать отрицательные значения.

        • 'standard' - использовать знак минус (-)
        • 'accounting' - во многих локалях в этом режиме отрицательные значения выводятся в круглых скобках без знака минус (например в en-US (₽1,234.00) )
      • useGrouping: 'auto' | true | false (по умолчанию 'auto')
        Использовать ли разделитель тысячных разрядов.

        • 'auto' - в соответствие с настройками локали
        • true - всегда
        • false - никогда
      • minimumIntegerDigits: number (по умолчанию 1)
        Минимальное количество выводимых цифр (от 1 до 21) в целочисленной части выводимой суммы. Если количество значимых знаков меньше этого числа, то оно "добивается" нулями слева до нужного количества.

        Свойство игнорируется, если явно заданы minimumSignificantDigits или maximumSignificantDigits.

      • minimumFractionDigits: number (по умолчанию - количество дробных знаков для валюты из ISO 4217)
        Минимальное количество выводимых цифр (от 0 до 20) в дробной части выводимой суммы. Если количество значимых знаков меньше этого числа, то оно "добивается" нулями справа до нужного количества.

        Свойство игнорируется, если явно заданы minimumSignificantDigits или maximumSignificantDigits.

      • maximumFractionDigits: number (по умолчанию max(minimumFractionDigits, количество дробных знаков для валюты из ISO 4217) )
        Максимальное количество выводимых цифр (от 0 до 20) в дробной части выводимой суммы. Если количество значимых знаков больше этого числа, то оно округляется по правилу half-away-from-zero.

        Не может быть меньше, чем minimumFractionDigits.

        Свойство игнорируется, если явно заданы minimumSignificantDigits или maximumSignificantDigits.

      • minimumSignificantDigits: number (по умолчанию 1)
        Минимальное количество выводимых цифр (от 1 до 21) в общем в целочисленной и в дробной части выводимой суммы. Если общее количество значимых знаков меньше этого числа, то оно "добивается" нулями в дробной части справа до нужного количества.

        Использование этого свойства отлючает действие minimumIntegerDigits, minimumFractionDigits и maximumFractionDigits.

      • maximumSignificantDigits: number (по умолчанию 21)
        Максимальное количество выводимых цифр (от 1 до 21) в общем в целочисленной и в дробной части выводимой суммы. Если общее количество значимых знаков больше этого числа, то оно округляется по правилу half-away-from-zero, таким образом, чтобы количество значимых цифр начиная от старшего разряда до последней ненулевой цифры не превышало заданного значения. Округление действует не только для дробной части, но и для целочисленной: например сумма 1251 с maximumSignificantDigits=2 превратится в 1300.

        Не может быть меньше, чем minimumSignificantDigits.

        Использование этого свойства отлючает действие minimumIntegerDigits, minimumFractionDigits и maximumFractionDigits.

Примеры

Добавление бонуса, начисление процентов и вывод результата
const Balances = Heap.Table('balances', {
  amount: Heap.Money(),
})

async function addBonusPlus10Percent(
  ctx: app.Ctx, balanceId: string, bonus: Money,
): Promise<typeof Balances.T> {
  const balance = await Balances.getById(ctx, balanceId)
  return Balances.update({
    id: balance.id,
    amount: balance.amount.add(bonus).multiply(1.1),
  })
}

const balanceWithBonus = await addBonusPlus10Percent(
  ctx, req.params.id, new Money(req.params.bonus, 'USD'),
)
ctx.console.log('new balance', balanceWithBonus.amount.format(ctx, {
  currencyDisplay: 'narrowSymbol',
  minimumFractionDigits: 0,
  maximumFractionDigits: 0,
})

❤️ Made with love on Chatium

ООО "Чатиум"

Информация о компании