-# -*- encoding: utf-8 -*-
+# -*- coding: utf-8 -*-
##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
-# $Id$
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# GNU Affero General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
# French
#-------------------------------------------------------------
-unites = {
- 0: '', 1:'un', 2:'deux', 3:'trois', 4:'quatre', 5:'cinq', 6:'six', 7:'sept', 8:'huit', 9:'neuf',
- 10:'dix', 11:'onze', 12:'douze', 13:'treize', 14:'quatorze', 15:'quinze', 16:'seize',
- 21:'vingt et un', 31:'trente et un', 41:'quarante et un', 51:'cinquante et un', 61:'soixante et un',
- 71:'septante et un', 91:'nonante et un', 80:'quatre-vingts'
-}
-
-dizaine = {
- 1: 'dix', 2:'vingt', 3:'trente',4:'quarante', 5:'cinquante', 6:'soixante', 7:'septante', 8:'quatre-vingt', 9:'nonante'
-}
-
-centaine = {
- 0:'', 1: 'cent', 2:'deux cent', 3:'trois cent',4:'quatre cent', 5:'cinq cent', 6:'six cent', 7:'sept cent', 8:'huit cent', 9:'neuf cent'
-}
-mille = {
- 0:'', 1:'mille'
-}
+to_19_fr = ( 'zéro', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six',
+ 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize',
+ 'quatorze', 'quinze', 'seize', 'dix-sept', 'dix-huit', 'dix-neuf' )
+tens_fr = ( 'vingt', 'trente', 'quarante', 'Cinquante', 'Soixante', 'Soixante-dix', 'Quatre-vingts', 'Quatre-vingt Dix')
+denom_fr = ( '',
+ 'Mille', 'Millions', 'Milliards', 'Billions', 'Quadrillions',
+ 'Quintillion', 'Sextillion', 'Septillion', 'Octillion', 'Nonillion',
+ 'Décillion', 'Undecillion', 'Duodecillion', 'Tredecillion', 'Quattuordecillion',
+ 'Sexdecillion', 'Septendecillion', 'Octodecillion', 'Icosillion', 'Vigintillion' )
+
+# convert a value < 100 to French.
+def _convert_nn_fr(val):
+ if val < 20:
+ return to_19_fr[val]
+ for (dcap, dval) in ((k, 20 + (10 * v)) for (v, k) in enumerate(tens_fr)):
+ if dval + 10 > val:
+ if val % 10:
+ return dcap + '-' + to_19_fr[val % 10]
+ return dcap
+
+# convert a value < 1000 to french, special cased because it is the level that kicks
+# off the < 100 special case. The rest are more general. This also allows you to
+# get strings in the form of 'forty-five hundred' if called directly.
+def _convert_nnn_fr(val):
+ word = ''
+ (mod, rem) = (val % 100, val // 100)
+ if rem > 0:
+ word = to_19_fr[rem] + ' Cent'
+ if mod > 0:
+ word = word + ' '
+ if mod > 0:
+ word = word + _convert_nn_fr(mod)
+ return word
+
+def french_number(val):
+ if val < 100:
+ return _convert_nn_fr(val)
+ if val < 1000:
+ return _convert_nnn_fr(val)
+ for (didx, dval) in ((v - 1, 1000 ** v) for v in range(len(denom_fr))):
+ if dval > val:
+ mod = 1000 ** didx
+ l = val // mod
+ r = val - (l * mod)
+ ret = _convert_nnn_fr(l) + ' ' + denom_fr[didx]
+ if r > 0:
+ ret = ret + ', ' + french_number(r)
+ return ret
-def _100_to_text_fr(chiffre):
- if chiffre in unites:
- return unites[chiffre]
- else:
- if chiffre%10>0:
- return dizaine[chiffre / 10]+'-'+unites[chiffre % 10]
- else:
- return dizaine[chiffre / 10]
-
-def _1000_to_text_fr(chiffre):
- d = _100_to_text_fr(chiffre % 100)
- d2 = chiffre/100
- if d2>0 and d:
- return centaine[d2]+' '+d
- elif d2>1 and not(d):
- return centaine[d2]+'s'
- else:
- return centaine[d2] or d
-
-def _10000_to_text_fr(chiffre):
- if chiffre==0:
- return 'zero'
- part1 = _1000_to_text_fr(chiffre % 1000)
- part2 = mille.get(chiffre / 1000, _1000_to_text_fr(chiffre / 1000)+' mille')
- if part2 and part1:
- part1 = ' '+part1
- return part2+part1
-
def amount_to_text_fr(number, currency):
- units_number = int(number)
+ number = '%.2f' % number
units_name = currency
- if units_number > 1:
- units_name += 's'
- units = _10000_to_text_fr(units_number)
- units = units_number and '%s %s' % (units, units_name) or ''
-
- cents_number = int(number * 100) % 100
- cents_name = (cents_number > 1) and 'cents' or 'cent'
- cents = _100_to_text_fr(cents_number)
- cents = cents_number and '%s %s' % (cents, cents_name) or ''
-
- if units and cents:
- cents = ' '+cents
-
- return units + cents
+ list = str(number).split('.')
+ start_word = french_number(abs(int(list[0])))
+ end_word = french_number(int(list[1]))
+ cents_number = int(list[1])
+ cents_name = (cents_number > 1) and ' Cents' or ' Cent'
+ final_result = start_word +' '+units_name+' '+ end_word +' '+cents_name
+ return final_result
#-------------------------------------------------------------
# Dutch
#-------------------------------------------------------------
-units_nl = {
- 0:'', 1:'een', 2:'twee', 3:'drie', 4:'vier', 5:'vijf', 6:'zes', 7:'zeven', 8:'acht', 9:'negen',
- 10:'tien', 11:'elf', 12:'twaalf', 13:'dertien', 14:'veertien'
-}
-
-tens_nl = {
- 1: 'tien', 2:'twintig', 3:'dertig',4:'veertig', 5:'vijftig', 6:'zestig', 7:'zeventig', 8:'tachtig', 9:'negentig'
-}
+to_19_nl = ( 'Nul', 'Een', 'Twee', 'Drie', 'Vier', 'Vijf', 'Zes',
+ 'Zeven', 'Acht', 'Negen', 'Tien', 'Elf', 'Twaalf', 'Dertien',
+ 'Veertien', 'Vijftien', 'Zestien', 'Zeventien', 'Achttien', 'Negentien' )
+tens_nl = ( 'Twintig', 'Dertig', 'Veertig', 'Vijftig', 'Zestig', 'Zeventig', 'Tachtig', 'Negentig')
+denom_nl = ( '',
+ 'Duizend', 'Miljoen', 'Miljard', 'Triljoen', 'Quadriljoen',
+ 'Quintillion', 'Sextiljoen', 'Septillion', 'Octillion', 'Nonillion',
+ 'Decillion', 'Undecillion', 'Duodecillion', 'Tredecillion', 'Quattuordecillion',
+ 'Sexdecillion', 'Septendecillion', 'Octodecillion', 'Novemdecillion', 'Vigintillion' )
+
+# convert a value < 100 to Dutch.
+def _convert_nn_nl(val):
+ if val < 20:
+ return to_19_nl[val]
+ for (dcap, dval) in ((k, 20 + (10 * v)) for (v, k) in enumerate(tens_nl)):
+ if dval + 10 > val:
+ if val % 10:
+ return dcap + '-' + to_19_nl[val % 10]
+ return dcap
+
+# convert a value < 1000 to Dutch, special cased because it is the level that kicks
+# off the < 100 special case. The rest are more general. This also allows you to
+# get strings in the form of 'forty-five hundred' if called directly.
+def _convert_nnn_nl(val):
+ word = ''
+ (mod, rem) = (val % 100, val // 100)
+ if rem > 0:
+ word = to_19_nl[rem] + ' Honderd'
+ if mod > 0:
+ word = word + ' '
+ if mod > 0:
+ word = word + _convert_nn_nl(mod)
+ return word
+
+def dutch_number(val):
+ if val < 100:
+ return _convert_nn_nl(val)
+ if val < 1000:
+ return _convert_nnn_nl(val)
+ for (didx, dval) in ((v - 1, 1000 ** v) for v in range(len(denom_nl))):
+ if dval > val:
+ mod = 1000 ** didx
+ l = val // mod
+ r = val - (l * mod)
+ ret = _convert_nnn_nl(l) + ' ' + denom_nl[didx]
+ if r > 0:
+ ret = ret + ', ' + dutch_number(r)
+ return ret
-hundreds_nl = {
- 0:'', 1: 'honderd',
-}
-
-thousands_nl = {
- 0:'', 1:'duizend'
-}
-
-def _100_to_text_nl(number):
- if number in units_nl:
- return units_nl[number]
- else:
- if number%10 > 0:
- if number>10 and number<20:
- return units_nl[number % 10]+tens_nl[number / 10]
- else:
- units = units_nl[number % 10]
- if units[-1] == 'e':
- joinword = 'ën'
- else:
- joinword = 'en'
- return units+joinword+tens_nl[number / 10]
- else:
- return tens_nl[number / 10]
-
-def _1000_to_text_nl(number):
- part1 = _100_to_text_nl(number % 100)
- part2 = hundreds_nl.get(number / 100, units_nl[number/100] + hundreds_nl[1])
- if part2 and part1:
- part1 = ' ' + part1
- return part2 + part1
-
-def _10000_to_text_nl(number):
- if number==0:
- return 'nul'
- part1 = _1000_to_text_nl(number % 1000)
- if thousands_nl.has_key(number / 1000):
- part2 = thousands_nl[number / 1000]
- else:
- if (number / 1000 % 100 > 0) and (number / 1000 > 100):
- space = ' '
- else:
- space = ''
- part2 = _1000_to_text_nl(number / 1000) + space + thousands_nl[1]
- if part2 and part1:
- part1 = ' ' + part1
- return part2 + part1
-
def amount_to_text_nl(number, currency):
- units_number = int(number)
+ number = '%.2f' % number
units_name = currency
- units = _10000_to_text_nl(units_number)
- units = units_number and '%s %s' % (units, units_name) or ''
-
- cents_number = int(number * 100) % 100
- cents_name = 'cent'
- cents = _100_to_text_nl(cents_number)
- cents = cents_number and '%s %s' % (cents, cents_name) or ''
-
- if units and cents:
- cents = ' ' + cents
-
- return units + cents
+ list = str(number).split('.')
+ start_word = dutch_number(int(list[0]))
+ end_word = dutch_number(int(list[1]))
+ cents_number = int(list[1])
+ cents_name = (cents_number > 1) and 'cent' or 'cent'
+ final_result = start_word +' '+units_name+' '+ end_word +' '+cents_name
+ return final_result
#-------------------------------------------------------------
# Generic functions
Example:
1654: mille six cent cinquante-quatre.
"""
- if nbr > 1000000:
-#TODO: use logger
- print "WARNING: number too large '%d', can't translate it!" % (nbr,)
- return str(nbr)
+# if nbr > 1000000:
+##TODO: use logger
+# print "WARNING: number too large '%d', can't translate it!" % (nbr,)
+# return str(nbr)
if not _translate_funcs.has_key(lang):
#TODO: use logger
print "WARNING: no translation function found for lang: '%s'" % (lang,)
#TODO: (default should be en) same as above
lang = 'fr'
- return _translate_funcs[lang](nbr, currency)
+ return _translate_funcs[lang](abs(nbr), currency)
if __name__=='__main__':
from sys import argv