Giter Club home page Giter Club logo

Comments (5)

kipcole9 avatar kipcole9 commented on May 23, 2024

Good work team. I've implemented the protocol in https://github.com/kipcole9/money in the gringotts branch.

I have a few observations. Some with to_string/1 there are now implications for money and potentially localisation:

  1. value/1 will return the decimal amount. This amount will have an arbitrary number of decimal places. This is because $1.3456 is completely valid (think currency conversion, or financial trading). So value will return a potentially different result to to_integer since to_integer needs to round. This is in part why I return a remainder in to_integer_exp/1. This probably should be made clear in the docs.

  2. to_string/1 is defined to return a formatted string. Separators are locale specific, some are ., some are , and there are others. Is the formatting intended to have other separators? How is 10_000 going to be formatted? 10,000? 10,000.00? I think the protocol documentation needs to be really explicit about expectations for the formatting. What about negative numbers? - to the left, or right or anywhere? String formatting numbers and money amounts is non-trivial unless the use case is well understood. If the intent is entirely related to returning a formatted value to the user then a money packages default is probably ok. In my case, ex_money will format the number with localised separators etc etc.

  3. Rounding needs very careful documentation and handling. Ideally you would support a rounding_mode parameter with a default of :half_even which is what most financial texts recommend. But I think the implications of rounding should be more visible.

from gringotts.

oyeb avatar oyeb commented on May 23, 2024

We've addressed your valid concerns by updating the docs. We've put this in bold:

When this highly precise amount is serialized into the network request, we
use a potentially lossy Gringotts.Money.to_string/1 or
Gringotts.Money.to_integer/1 to perform rounding (if required) using the
half-even strategy.

Hence, to ensure transparency, protect sanity and save real money, we
STRONGLY RECOMMEND that merchants perform any required rounding and handle
remainders in their application logic -- before passing the amount to
Gringotts's API.

After all, the merchant must understand the subtleties of finance and currency conversion to take care of their profits and losses.

  1. to_integer/1
    The perils about implicit rounding and potential loss are made clear. All protocol implementations will round using :half_even strategy.
    • The remainder is not made available by the protocol, because the protocol is "invoked" in the gateway implementation and there's no way to handle this remainder there (apart form returning it -- which does not make sense).
  2. to_string/1
    • All stringified amounts must match this (documented) regex: ~r/-?\d+\.\d\d{n}/, so there's only 1 separator: the decimal point (.).
    • The intent is to serialize the amount to the network request, not to show it to the user.
  3. We want all rounding to happen outside Gringotts in the merchant's business logic. Still, when required, :half_even is the default strategy.

from gringotts.

kipcole9 avatar kipcole9 commented on May 23, 2024

Got it, looks good. Especially helpful to know that to_string/1 is not localised. I've updated my implementation to reflect that. I still need to add tests though.

from gringotts.

oyeb avatar oyeb commented on May 23, 2024

We have some test cases here. I'm sure you'll devise some more test cases than we have! 🙂

from gringotts.

kipcole9 avatar kipcole9 commented on May 23, 2024

And i'm sure you'll tell me if any tests are failing because of my bad code :-)

I'm really enjoying the collaboration - I think this is a great way to leverage the efforts of many in a way that multiplies the benefit for all.

from gringotts.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.