dolibarr  13.0.2
functionsnumtoword.lib.php
Go to the documentation of this file.
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 <https://www.gnu.org/licenses/>.
17  * or see https://www.gnu.org/
18  */
36 function dol_convertToWord($num, $langs, $currency = '', $centimes = false)
37 {
38  global $conf;
39 
40  //$num = str_replace(array(',', ' '), '', trim($num)); This should be useless since $num MUST be a php numeric value
41  if (!$num) {
42  return false;
43  }
44 
45  if ($centimes && strlen($num) == 1) {
46  $num = $num * 10;
47  }
48 
49  if (!empty($conf->global->MAIN_MODULE_NUMBERWORDS)) {
50  if ($currency) {
51  $type = '1';
52  } else {
53  $type = '0';
54  }
55 
56  $concatWords = $langs->getLabelFromNumber($num, $type);
57  return $concatWords;
58  } else {
59  $TNum = explode('.', $num);
60 
61  $num = (int) $TNum[0];
62  $words = array();
63  $list1 = array(
64  '',
65  $langs->transnoentitiesnoconv('one'),
66  $langs->transnoentitiesnoconv('two'),
67  $langs->transnoentitiesnoconv('three'),
68  $langs->transnoentitiesnoconv('four'),
69  $langs->transnoentitiesnoconv('five'),
70  $langs->transnoentitiesnoconv('six'),
71  $langs->transnoentitiesnoconv('seven'),
72  $langs->transnoentitiesnoconv('eight'),
73  $langs->transnoentitiesnoconv('nine'),
74  $langs->transnoentitiesnoconv('ten'),
75  $langs->transnoentitiesnoconv('eleven'),
76  $langs->transnoentitiesnoconv('twelve'),
77  $langs->transnoentitiesnoconv('thirteen'),
78  $langs->transnoentitiesnoconv('fourteen'),
79  $langs->transnoentitiesnoconv('fifteen'),
80  $langs->transnoentitiesnoconv('sixteen'),
81  $langs->transnoentitiesnoconv('seventeen'),
82  $langs->transnoentitiesnoconv('eighteen'),
83  $langs->transnoentitiesnoconv('nineteen')
84  );
85  $list2 = array(
86  '',
87  $langs->transnoentitiesnoconv('ten'),
88  $langs->transnoentitiesnoconv('twenty'),
89  $langs->transnoentitiesnoconv('thirty'),
90  $langs->transnoentitiesnoconv('forty'),
91  $langs->transnoentitiesnoconv('fifty'),
92  $langs->transnoentitiesnoconv('sixty'),
93  $langs->transnoentitiesnoconv('seventy'),
94  $langs->transnoentitiesnoconv('eighty'),
95  $langs->transnoentitiesnoconv('ninety'),
96  $langs->transnoentitiesnoconv('hundred')
97  );
98  $list3 = array(
99  '',
100  $langs->transnoentitiesnoconv('thousand'),
101  $langs->transnoentitiesnoconv('million'),
102  $langs->transnoentitiesnoconv('billion'),
103  $langs->transnoentitiesnoconv('trillion'),
104  $langs->transnoentitiesnoconv('quadrillion')
105  );
106 
107  $num_length = strlen($num);
108  $levels = (int) (($num_length + 2) / 3);
109  $max_length = $levels * 3;
110  $num = substr('00'.$num, -$max_length);
111  $num_levels = str_split($num, 3);
112  $nboflevels = count($num_levels);
113  for ($i = 0; $i < $nboflevels; $i++) {
114  $levels--;
115  $hundreds = (int) ($num_levels[$i] / 100);
116  $hundreds = ($hundreds ? ' '.$list1[$hundreds].' '.$langs->transnoentities('hundred').($hundreds == 1 ? '' : 's').' ' : '');
117  $tens = (int) ($num_levels[$i] % 100);
118  $singles = '';
119  if ($tens < 20) {
120  $tens = ($tens ? ' '.$list1[$tens].' ' : '');
121  } else {
122  $tens = (int) ($tens / 10);
123  $tens = ' '.$list2[$tens].' ';
124  $singles = (int) ($num_levels[$i] % 10);
125  $singles = ' '.$list1[$singles].' ';
126  }
127  $words[] = $hundreds.$tens.$singles.(($levels && (int) ($num_levels[$i])) ? ' '.$list3[$levels].' ' : '');
128  } //end for loop
129  $commas = count($words);
130  if ($commas > 1) {
131  $commas = $commas - 1;
132  }
133  $concatWords = implode(' ', $words);
134  // Delete multi whitespaces
135  $concatWords = trim(preg_replace('/[ ]+/', ' ', $concatWords));
136 
137  if (!empty($currency)) {
138  $concatWords .= ' '.$currency;
139  }
140 
141  // If we need to write cents call again this function for cents
142  $decimalpart = empty($TNum[1]) ? '' : preg_replace('/0+$/', '', $TNum[1]);
143 
144  if ($decimalpart) {
145  if (!empty($currency)) $concatWords .= ' '.$langs->transnoentities('and');
146 
147  $concatWords .= ' '.dol_convertToWord($decimalpart, $langs, '', true);
148  if (!empty($currency)) $concatWords .= ' '.$langs->transnoentities('centimes');
149  }
150  return $concatWords;
151  }
152 }
153 
154 
164 function dolNumberToWord($numero, $langs, $numorcurrency = 'number')
165 {
166  // If the number is negative convert to positive and return -1 if it is too long
167  if ($numero < 0) $numero *= -1;
168  if ($numero >= 1000000000001) {
169  return -1;
170  }
171 
172  // Get 2 decimals to cents, another functions round or truncate
173  $strnumber = number_format($numero, 10);
174  $len = strlen($strnumber);
175  for ($i = 0; $i < $len; $i++)
176  {
177  if ($strnumber[$i] == '.') {
178  $parte_decimal = $strnumber[$i + 1].$strnumber[$i + 2];
179  break;
180  }
181  }
182 
183  /*In dolibarr 3.6.2 (my current version) doesn't have $langs->default and
184  in case exist why ask $lang like a parameter?*/
185  if (((is_object($langs) && $langs->default == 'es_MX') || (!is_object($langs) && $langs == 'es_MX')) && $numorcurrency == 'currency')
186  {
187  if ($numero >= 1 && $numero < 2) {
188  return ("UN PESO ".$parte_decimal." / 100 M.N.");
189  } elseif ($numero >= 0 && $numero < 1) {
190  return ("CERO PESOS ".$parte_decimal." / 100 M.N.");
191  } elseif ($numero >= 1000000 && $numero < 1000001) {
192  return ("UN MILL&OacuteN DE PESOS ".$parte_decimal." / 100 M.N.");
193  } elseif ($numero >= 1000000000000 && $numero < 1000000000001) {
194  return ("UN BILL&OacuteN DE PESOS ".$parte_decimal." / 100 M.N.");
195  } else {
196  $entexto = "";
197  $number = $numero;
198  if ($number >= 1000000000) {
199  $CdMMillon = (int) ($numero / 100000000000);
200  $numero = $numero - $CdMMillon * 100000000000;
201  $DdMMillon = (int) ($numero / 10000000000);
202  $numero = $numero - $DdMMillon * 10000000000;
203  $UdMMillon = (int) ($numero / 1000000000);
204  $numero = $numero - $UdMMillon * 1000000000;
205  $entexto .= hundreds2text($CdMMillon, $DdMMillon, $UdMMillon);
206  $entexto .= " MIL ";
207  }
208  if ($number >= 1000000) {
209  $CdMILLON = (int) ($numero / 100000000);
210  $numero = $numero - $CdMILLON * 100000000;
211  $DdMILLON = (int) ($numero / 10000000);
212  $numero = $numero - $DdMILLON * 10000000;
213  $udMILLON = (int) ($numero / 1000000);
214  $numero = $numero - $udMILLON * 1000000;
215  $entexto .= hundreds2text($CdMILLON, $DdMILLON, $udMILLON);
216  if (!$CdMMillon && !$DdMMillon && !$UdMMillon && !$CdMILLON && !$DdMILLON && $udMILLON == 1)
217  $entexto .= " MILL&OacuteN ";
218  else $entexto .= " MILLONES ";
219  }
220  if ($number >= 1000) {
221  $cdm = (int) ($numero / 100000);
222  $numero = $numero - $cdm * 100000;
223  $ddm = (int) ($numero / 10000);
224  $numero = $numero - $ddm * 10000;
225  $udm = (int) ($numero / 1000);
226  $numero = $numero - $udm * 1000;
227  $entexto .= hundreds2text($cdm, $ddm, $udm);
228  if ($cdm || $ddm || $udm)
229  $entexto .= " MIL ";
230  }
231  $c = (int) ($numero / 100);
232  $numero = $numero - $c * 100;
233  $d = (int) ($numero / 10);
234  $u = (int) $numero - $d * 10;
235  $entexto .= hundreds2text($c, $d, $u);
236  if (!$cdm && !$ddm && !$udm && !$c && !$d && !$u && $number > 1000000)
237  $entexto .= " DE";
238  $entexto .= " PESOS ".$parte_decimal." / 100 M.N.";
239  }
240  return $entexto;
241  }
242 }
243 
252 function hundreds2text($hundreds, $tens, $units)
253 {
254  if ($hundreds == 1 && $tens == 0 && $units == 0) {
255  return "CIEN";
256  }
257  $centenas = array("CIENTO", "DOSCIENTOS", "TRESCIENTOS", "CUATROCIENTOS", "QUINIENTOS", "SEISCIENTOS", "SETECIENTOS", "OCHOCIENTOS", "NOVECIENTOS");
258  $decenas = array("", "", "TREINTA ", "CUARENTA ", "CINCUENTA ", "SESENTA ", "SETENTA ", "OCHENTA ", "NOVENTA ");
259  $veintis = array("VEINTE", "VEINTIUN", "VEINTID&OacuteS", "VEINTITR&EacuteS", "VEINTICUATRO", "VEINTICINCO", "VEINTIS&EacuteIS", "VEINTISIETE", "VEINTIOCHO", "VEINTINUEVE");
260  $diecis = array("DIEZ", "ONCE", "DOCE", "TRECE", "CATORCE", "QUINCE", "DIECIS&EacuteIS", "DIECISIETE", "DIECIOCHO", "DIECINUEVE");
261  $unidades = array("UN", "DOS", "TRES", "CUATRO", "CINCO", "SEIS", "SIETE", "OCHO", "NUEVE");
262  $entexto = "";
263  if ($hundreds != 0) {
264  $entexto .= $centenas[$hundreds - 1];
265  }
266  if ($tens > 2) {
267  if ($hundreds != 0) $entexto .= " ";
268  $entexto .= $decenas[$tens - 1];
269  if ($units != 0) {
270  $entexto .= " Y ";
271  $entexto .= $unidades[$units - 1];
272  }
273  return $entexto;
274  } elseif ($tens == 2) {
275  if ($hundreds != 0) $entexto .= " ";
276  $entexto .= " ".$veintis[$units];
277  return $entexto;
278  } elseif ($tens == 1) {
279  if ($hundreds != 0) $entexto .= " ";
280  $entexto .= $diecis[$units];
281  return $entexto;
282  }
283  if ($units != 0) {
284  if ($hundreds != 0 || $tens != 0) $entexto .= " ";
285  $entexto .= $unidades[$units - 1];
286  }
287  return $entexto;
288 }
hundreds2text($hundreds, $tens, $units)
hundreds2text
dol_convertToWord($num, $langs, $currency= '', $centimes=false)
Function to return a number into a text.
dolNumberToWord($numero, $langs, $numorcurrency= 'number')
Function to return number or amount in text.