dolibarr  7.0.0-beta
functionsnumtoword.lib.php
1 <?php
2 /* Copyright (C) 2015 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2015 Víctor Ortiz Pérez <victor@accett.com.mx>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  * or see http://www.gnu.org/
18  */
36 function dol_convertToWord($num, $langs, $currency=false, $centimes=false)
37 {
38  global $conf;
39 
40  $num = str_replace(array(',', ' '), '', trim($num));
41  if(! $num) {
42  return false;
43  }
44  if($centimes && strlen($num) == 1) {
45  $num = $num*10;
46  }
47  $TNum = explode('.',$num);
48  $num = (int) $TNum[0];
49  $words = array();
50  $list1 = array(
51  '',
52  $langs->transnoentitiesnoconv('one'),
53  $langs->transnoentitiesnoconv('two'),
54  $langs->transnoentitiesnoconv('three'),
55  $langs->transnoentitiesnoconv('four'),
56  $langs->transnoentitiesnoconv('five'),
57  $langs->transnoentitiesnoconv('six'),
58  $langs->transnoentitiesnoconv('seven'),
59  $langs->transnoentitiesnoconv('eight'),
60  $langs->transnoentitiesnoconv('nine'),
61  $langs->transnoentitiesnoconv('ten'),
62  $langs->transnoentitiesnoconv('eleven'),
63  $langs->transnoentitiesnoconv('twelve'),
64  $langs->transnoentitiesnoconv('thirteen'),
65  $langs->transnoentitiesnoconv('fourteen'),
66  $langs->transnoentitiesnoconv('fifteen'),
67  $langs->transnoentitiesnoconv('sixteen'),
68  $langs->transnoentitiesnoconv('seventeen'),
69  $langs->transnoentitiesnoconv('eighteen'),
70  $langs->transnoentitiesnoconv('nineteen')
71  );
72  $list2 = array(
73  '',
74  $langs->transnoentitiesnoconv('ten'),
75  $langs->transnoentitiesnoconv('twenty'),
76  $langs->transnoentitiesnoconv('thirty'),
77  $langs->transnoentitiesnoconv('forty'),
78  $langs->transnoentitiesnoconv('fifty'),
79  $langs->transnoentitiesnoconv('sixty'),
80  $langs->transnoentitiesnoconv('seventy'),
81  $langs->transnoentitiesnoconv('eighty'),
82  $langs->transnoentitiesnoconv('ninety'),
83  $langs->transnoentitiesnoconv('hundred')
84  );
85  $list3 = array(
86  '',
87  $langs->transnoentitiesnoconv('thousand'),
88  $langs->transnoentitiesnoconv('million'),
89  $langs->transnoentitiesnoconv('billion'),
90  $langs->transnoentitiesnoconv('trillion'),
91  $langs->transnoentitiesnoconv('quadrillion')
92  );
93 
94  $num_length = strlen($num);
95  $levels = (int) (($num_length + 2) / 3);
96  $max_length = $levels * 3;
97  $num = substr('00' . $num, -$max_length);
98  $num_levels = str_split($num, 3);
99  $nboflevels = count($num_levels);
100  for ($i = 0; $i < $nboflevels; $i++) {
101  $levels--;
102  $hundreds = (int) ($num_levels[$i] / 100);
103  $hundreds = ($hundreds ? ' ' . $list1[$hundreds] . ' '.$langs->transnoentities('hundred') . ( $hundreds == 1 ? '' : 's' ) . ' ': '');
104  $tens = (int) ($num_levels[$i] % 100);
105  $singles = '';
106  if ( $tens < 20 ) {
107  $tens = ($tens ? ' ' . $list1[$tens] . ' ' : '' );
108  } else {
109  $tens = (int) ($tens / 10);
110  $tens = ' ' . $list2[$tens] . ' ';
111  $singles = (int) ($num_levels[$i] % 10);
112  $singles = ' ' . $list1[$singles] . ' ';
113  }
114  $words[] = $hundreds . $tens . $singles . ( ( $levels && ( int ) ( $num_levels[$i] ) ) ? ' ' . $list3[$levels] . ' ' : '' );
115  } //end for loop
116  $commas = count($words);
117  if ($commas > 1) {
118  $commas = $commas - 1;
119  }
120  $concatWords = implode(' ', $words);
121  // Delete multi whitespaces
122  $concatWords = trim(preg_replace('/[ ]+/', ' ', $concatWords));
123 
124  if(!empty($currency)) {
125  $concatWords .= ' '.$currency;
126  }
127 
128  // If we need to write cents call again this function for cents
129  if(!empty($TNum[1])) {
130  if(!empty($currency)) $concatWords .= ' '.$langs->transnoentities('and');
131  $concatWords .= ' '.dol_convertToWord($TNum[1], $langs, $currency, true);
132  if(!empty($currency)) $concatWords .= ' '.$langs->transnoentities('centimes');
133  }
134  return $concatWords;
135 }
136 
137 
147 function dolNumberToWord($numero, $langs, $numorcurrency='number')
148 {
149  // If the number is negative convert to positive and return -1 if is too long
150  if ($numero < 0) $numero *= -1;
151  if ($numero >= 1000000000001)
152  return -1;
153  // Get 2 decimals to cents, another functions round or truncate
154  $strnumber = number_format ($numero,10);
155  $len=strlen($strnumber);
156  for ($i=0; $i<$len; $i++)
157  {
158  if ($strnumber[$i]=='.') {
159  $parte_decimal = $strnumber[$i+1].$strnumber[$i+2];
160  break;
161  }
162  }
163 
164  /*In dolibarr 3.6.2 (my current version) doesn't have $langs->default and
165  in case exist why ask $lang like a parameter?*/
166  if (((is_object($langs) && $langs->default == 'es_MX') || (! is_object($langs) && $langs == 'es_MX')) && $numorcurrency == 'currency')
167  {
168  if ($numero>=1 && $numero<2) {
169  return ("UN PESO ".$parte_decimal." / 100 M.N.");
170  }
171  elseif ($numero>=0 && $numero<1){
172  return ("CERO PESOS ".$parte_decimal." / 100 M.N.");
173  }
174  elseif ($numero>=1000000 && $numero<1000001){
175  return ("UN MILL&OacuteN DE PESOS ".$parte_decimal." / 100 M.N.");
176  }
177  elseif ($numero>=1000000000000 && $numero<1000000000001){
178  return ("UN BILL&OacuteN DE PESOS ".$parte_decimal." / 100 M.N.");
179  }
180  else {
181  $entexto ="";
182  $number = $numero;
183  if ($number >= 1000000000){
184  $CdMMillon = (int) ($numero / 100000000000);
185  $numero = $numero - $CdMMillon * 100000000000;
186  $DdMMillon = (int) ($numero / 10000000000);
187  $numero = $numero - $DdMMillon * 10000000000;
188  $UdMMillon = (int) ($numero / 1000000000);
189  $numero = $numero - $UdMMillon * 1000000000;
190  $entexto .= hundreds2text ($CdMMillon, $DdMMillon, $UdMMillon);
191  $entexto .= " MIL ";
192  }
193  if ($number >= 1000000){
194  $CdMILLON = (int) ($numero / 100000000);
195  $numero = $numero - $CdMILLON * 100000000;
196  $DdMILLON = (int) ($numero / 10000000);
197  $numero = $numero - $DdMILLON * 10000000;
198  $udMILLON = (int) ($numero / 1000000);
199  $numero = $numero - $udMILLON * 1000000;
200  $entexto .= hundreds2text ($CdMILLON, $DdMILLON, $udMILLON);
201  if (!$CdMMillon && !$DdMMillon && !$UdMMillon && !$CdMILLON && !$DdMILLON && $udMILLON==1)
202  $entexto .= " MILL&OacuteN ";
203  else
204  $entexto .= " MILLONES ";
205  }
206  if ($number >= 1000) {
207  $cdm = (int) ($numero / 100000);
208  $numero = $numero - $cdm * 100000;
209  $ddm = (int) ($numero / 10000);
210  $numero = $numero - $ddm * 10000;
211  $udm = (int) ($numero / 1000);
212  $numero = $numero - $udm * 1000;
213  $entexto .= hundreds2text ($cdm, $ddm, $udm);
214  if ($cdm || $ddm || $udm)
215  $entexto .= " MIL ";
216  }
217  $c = (int) ($numero / 100);
218  $numero = $numero - $c * 100;
219  $d = (int) ($numero / 10);
220  $u = (int) $numero - $d * 10;
221  $entexto .= hundreds2text ($c, $d, $u);
222  if (!$cdm && !$ddm && !$udm && !$c && !$d && !$u && $number>1000000)
223  $entexto .= " DE";
224  $entexto .= " PESOS ".$parte_decimal." / 100 M.N.";
225  }
226  return $entexto;
227  }
228 }
229 
237 function hundreds2text($hundreds, $tens, $units)
238 {
239  if ($hundreds==1 && $tens==0 && $units==0){
240  return "CIEN";
241  }
242  $centenas = array("CIENTO","DOSCIENTOS","TRESCIENTOS","CUATROCIENTOS","QUINIENTOS","SEISCIENTOS","SETECIENTOS","OCHOCIENTOS","NOVECIENTOS");
243  $decenas = array("","","TREINTA ","CUARENTA ","CINCUENTA ","SESENTA ","SETENTA ","OCHENTA ","NOVENTA ");
244  $veintis = array("VEINTE","VEINTIUN","VEINTID&OacuteS","VEINTITR&EacuteS","VEINTICUATRO","VEINTICINCO","VEINTIS&EacuteIS","VEINTISIETE","VEINTIOCHO","VEINTINUEVE");
245  $diecis = array("DIEZ","ONCE","DOCE","TRECE","CATORCE","QUINCE","DIECIS&EacuteIS","DIECISIETE","DIECIOCHO","DIECINUEVE");
246  $unidades = array("UN","DOS","TRES","CUATRO","CINCO","SEIS","SIETE","OCHO","NUEVE");
247  $entexto = "";
248  if ($hundreds!=0){
249  $entexto .= $centenas[$hundreds-1];
250  }
251  if ($tens>2){
252  if ($hundreds!=0) $entexto .= " ";
253  $entexto .= $decenas[$tens-1];
254  if ($units!=0){
255  $entexto .= " Y ";
256  $entexto .= $unidades[$units-1];
257  }
258  return $entexto;
259  }
260  elseif ($tens==2){
261  if ($hundreds!=0) $entexto .= " ";
262  $entexto .= " ".$veintis[$units];
263  return $entexto;
264  }
265  elseif ($tens==1){
266  if ($hundreds!=0) $entexto .= " ";
267  $entexto .= $diecis[$units];
268  return $entexto;
269  }
270  if ($units!=0) {
271  if ($hundreds!=0 || $tens!=0) $entexto .= " ";
272  $entexto .= $unidades[$units-1];
273  }
274  return $entexto;
275 }