[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Proposal for 2.0: New monetary data types



Hi Chris,

If I may make a suggestion....

Overall I like this new model, but I would propose that consideration be given to designing the 2 functions with notes and coin in mind.

NOTE: EXAMPLES BELOW assume notes will be whole amounts and coins are fractional amounts, in the real world this may not be true, but the same principles apply just the terms coin and note become meaningless. Also $4/$5 are shown to be simple fractions ie: either the denominator or numerator are equal to 1. this need not be the case, 3/4 would be equally valid.

Change the function definition to something like....
monetary('1000','USD','500','2','1') where
  %1 is the total,
  %2 is the currency
  %3 is the denomination count        (number of coins or notes)
  %4 is the denomination numerator    (1 for coin or facevalue of note)
  %5 is the denomination denominator  (facevalue of coin or 1 for note)

%4 and %5 then act as a fraction that can accurately describe any unit.
For a whole amount like in your example USD$2 you would call
  monetary('1000','USD','500','2','1')
For USD$2.25 in quarters (where a quarter is 0.25 of a dollar) call
  monetary('2.25','USD','9','1','4')
For USD$2.50 and your example coin worth 1/12th of the base unit
  monetary('2.50','USD','30','1','12')

In fact with this function %1 (total) can become a returned variable
as can %3 (coin/note count)

I would consider 3 valid variations when calling the function, anything else should raise an error.

  Result=monetary(Amount,'USD','500','2','1')
    returns Unconverted amount in Amount and converted amount in Result

  Result=monetary('1000','USD',Count,'2','1')
    returns converted amount in Result
    and the expected coin or note count in Count

  Result=monetary('1000','USD',NULL,NULL,NULL)
    returns converted amount in Result USED ONLY FOR
     non-hardcurrency eg:checks and CreditCards

I would further suggest that %2 %3 %4 %5 be passed as
an array of %2 %3 %4 %5
Also all math within the function should be integer math, and the return result should be left as full precision real.
This will avoid all rounding error.
The result can then be rounded at application level.

Passing in an array allows calculating the value in a cash drawer with one call to the function while maintaining precision. An extra element could be added to the array so a Denomination total was available for display purposes.


The next step would be to track in the DB, denomination quantities located in each drawer and safe, possibly with the ability to track for separate bags in the safe. this would be useful where each staff member has their own float that is kept in a common safe when the staffmember is not working a till.

I probably have not explained myself well so please ask questions :)

Regards
David G


Chris Travers wrote:
 > 1)  The value component would be the value of the monetary element, so
monetary('1000', 'USD', '2') would be 1000 USD in $2 bills instead of
2000 USD.  This makes the math a lot easier.  It also allows for NULL
denominations where the money is not in a specific denomination (i.e.
a collection of cash in various denominations, a check, or a credit
card purchase).  The tradeoff is that if you end up with something
like coins worth 1/12 of a base currency rate, one could no longer
keep the precision exact.

2)  Two different currency exchange functions would be added:  The
first (part of the core module) would convert from one currency to
another at a specified rate.  The second (part of the business logic
module) would convert one currency to another as of a stored rate on a
specified date.

Also this will be broken off and implemented in C as a Pg-foundry
project and the goal would be to keep this applicable to other
software projects as well (or rather I am collaborating with someone
to do this).

Best Wishes,
Chris Travers