dolibarr 21.0.0-beta
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 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
5 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * or see https://www.gnu.org/
20 */
21
38function dol_convertToWord($num, $langs, $currency = '', $centimes = false)
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((string) $num) == 1) {
46 $num *= 10;
47 }
48
49 if (isModEnabled('numberwords')) {
50 $concatWords = $langs->getLabelFromNumber($num, $currency);
51 return $concatWords;
52 } else {
53 $TNum = explode('.', (string) $num);
54
55 $num = (int) $TNum[0];
56 $words = array();
57 $list1 = array(
58 '',
59 $langs->transnoentitiesnoconv('one'),
60 $langs->transnoentitiesnoconv('two'),
61 $langs->transnoentitiesnoconv('three'),
62 $langs->transnoentitiesnoconv('four'),
63 $langs->transnoentitiesnoconv('five'),
64 $langs->transnoentitiesnoconv('six'),
65 $langs->transnoentitiesnoconv('seven'),
66 $langs->transnoentitiesnoconv('eight'),
67 $langs->transnoentitiesnoconv('nine'),
68 $langs->transnoentitiesnoconv('ten'),
69 $langs->transnoentitiesnoconv('eleven'),
70 $langs->transnoentitiesnoconv('twelve'),
71 $langs->transnoentitiesnoconv('thirteen'),
72 $langs->transnoentitiesnoconv('fourteen'),
73 $langs->transnoentitiesnoconv('fifteen'),
74 $langs->transnoentitiesnoconv('sixteen'),
75 $langs->transnoentitiesnoconv('seventeen'),
76 $langs->transnoentitiesnoconv('eighteen'),
77 $langs->transnoentitiesnoconv('nineteen')
78 );
79 $list2 = array(
80 '',
81 $langs->transnoentitiesnoconv('ten'),
82 $langs->transnoentitiesnoconv('twenty'),
83 $langs->transnoentitiesnoconv('thirty'),
84 $langs->transnoentitiesnoconv('forty'),
85 $langs->transnoentitiesnoconv('fifty'),
86 $langs->transnoentitiesnoconv('sixty'),
87 $langs->transnoentitiesnoconv('seventy'),
88 $langs->transnoentitiesnoconv('eighty'),
89 $langs->transnoentitiesnoconv('ninety'),
90 $langs->transnoentitiesnoconv('hundred')
91 );
92 $list3 = array(
93 '',
94 $langs->transnoentitiesnoconv('thousand'),
95 $langs->transnoentitiesnoconv('million'),
96 $langs->transnoentitiesnoconv('billion'),
97 $langs->transnoentitiesnoconv('trillion'),
98 $langs->transnoentitiesnoconv('quadrillion')
99 );
100
101 $num_length = strlen((string) $num);
102 $levels = (int) (($num_length + 2) / 3);
103 $max_length = $levels * 3;
104 $num = substr('00'.$num, -$max_length);
105 $num_levels = str_split($num, 3);
106 $nboflevels = count($num_levels);
107 for ($i = 0; $i < $nboflevels; $i++) {
108 $levels--;
109 $hundreds = (int) ((int) $num_levels[$i] / 100);
110 $hundreds = ($hundreds ? ' '.$list1[$hundreds].' '.$langs->transnoentities('hundred').($hundreds == 1 ? '' : 's').' ' : '');
111 $tens = (int) ((int) $num_levels[$i] % 100);
112 $singles = '';
113 if ($tens < 20) {
114 $tens = ($tens ? ' '.$list1[$tens].' ' : '');
115 } else {
116 $tens = (int) ($tens / 10);
117 $tens = ' '.$list2[$tens].' ';
118 $singles = (int) ((int) $num_levels[$i] % 10);
119 $singles = ' '.$list1[$singles].' ';
120 }
121 $words[] = $hundreds.$tens.$singles.(($levels && (int) ($num_levels[$i])) ? ' '.$list3[$levels].' ' : '');
122 } //end for loop
123 $commas = count($words);
124 if ($commas > 1) {
125 $commas -= 1;
126 }
127 $concatWords = implode(' ', $words);
128 // Delete multi whitespaces
129 $concatWords = trim(preg_replace('/[ ]+/', ' ', $concatWords));
130
131 if (!empty($currency)) {
132 $concatWords .= ' '.$currency;
133 }
134
135 // If we need to write cents call again this function for cents
136 $decimalpart = empty($TNum[1]) ? '' : preg_replace('/0+$/', '', $TNum[1]);
137
138 if ($decimalpart) {
139 if (!empty($currency)) {
140 $concatWords .= ' '.$langs->transnoentities('and');
141 }
142
143 $concatWords .= ' '.dol_convertToWord((float) $decimalpart, $langs, '', true);
144 if (!empty($currency)) {
145 $concatWords .= ' '.$langs->transnoentities('centimes');
146 }
147 }
148 return $concatWords;
149 }
150}
151
152
162function dolNumberToWord($numero, $langs, $numorcurrency = 'number')
163{
164 // If the number is negative convert to positive and return -1 if it is too long
165 if ($numero < 0) {
166 $numero *= -1;
167 }
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 $parte_decimal = '00'; // For static analysis, strnumber should contain '.'
176 for ($i = 0; $i < $len; $i++) {
177 if ($strnumber[$i] == '.') {
178 $parte_decimal = $strnumber[$i + 1].$strnumber[$i + 2];
179 break;
180 }
181 }
182
183 /* Dolibarr 3.6.2 doesn't have $langs->default, why ask $lang like a parameter in case it exists? */
184 if (((is_object($langs) && $langs->getDefaultLang(0) == 'es_MX') || (!is_object($langs) && $langs == 'es_MX')) && $numorcurrency == 'currency') {
185 if ($numero >= 1 && $numero < 2) {
186 return ("UN PESO ".$parte_decimal." / 100 M.N.");
187 } elseif ($numero >= 0 && $numero < 1) {
188 return ("CERO PESOS ".$parte_decimal." / 100 M.N.");
189 } elseif ($numero >= 1000000 && $numero < 1000001) {
190 return ("UN MILL&OacuteN DE PESOS ".$parte_decimal." / 100 M.N.");
191 } elseif ($numero >= 1000000000000 && $numero < 1000000000001) {
192 return ("UN BILL&OacuteN DE PESOS ".$parte_decimal." / 100 M.N.");
193 } else {
194 $entexto = "";
195 $number = $numero;
196 if ($number >= 1000000000) {
197 $CdMMillon = (int) ($numero / 100000000000);
198 $numero -= $CdMMillon * 100000000000;
199 $DdMMillon = (int) ($numero / 10000000000);
200 $numero -= $DdMMillon * 10000000000;
201 $UdMMillon = (int) ($numero / 1000000000);
202 $numero -= $UdMMillon * 1000000000;
203 $entexto .= hundreds2text($CdMMillon, $DdMMillon, $UdMMillon);
204 $entexto .= " MIL ";
205 } else {
206 $CdMMillon = 0;
207 $DdMMillon = 0;
208 $UdMMillon = 0;
209 }
210 if ($number >= 1000000) {
211 $CdMILLON = (int) ($numero / 100000000);
212 $numero -= $CdMILLON * 100000000;
213 $DdMILLON = (int) ($numero / 10000000);
214 $numero -= $DdMILLON * 10000000;
215 $udMILLON = (int) ($numero / 1000000);
216 $numero -= $udMILLON * 1000000;
217 $entexto .= hundreds2text($CdMILLON, $DdMILLON, $udMILLON);
218 if (!$CdMMillon && !$DdMMillon && !$UdMMillon && !$CdMILLON && !$DdMILLON && $udMILLON == 1) {
219 $entexto .= " MILL&OacuteN ";
220 } else {
221 $entexto .= " MILLONES ";
222 }
223 }
224
225 if ($number >= 1000) {
226 $cdm = (int) ($numero / 100000);
227 $numero -= $cdm * 100000;
228 $ddm = (int) ($numero / 10000);
229 $numero -= $ddm * 10000;
230 $udm = (int) ($numero / 1000);
231 $numero -= $udm * 1000;
232 $entexto .= hundreds2text($cdm, $ddm, $udm);
233 if ($cdm || $ddm || $udm) {
234 $entexto .= " MIL ";
235 }
236 } else {
237 $ddm = 0;
238 $cdm = 0;
239 $udm = 0;
240 }
241 $c = (int) ($numero / 100);
242 $numero -= $c * 100;
243 $d = (int) ($numero / 10);
244 $u = (int) $numero - $d * 10;
245 $entexto .= hundreds2text($c, $d, $u);
246 if (!$cdm && !$ddm && !$udm && !$c && !$d && !$u && $number > 1000000) {
247 $entexto .= " DE";
248 }
249 $entexto .= " PESOS ".$parte_decimal." / 100 M.N.";
250 }
251 return $entexto;
252 }
253 return -1;
254}
255
264function hundreds2text($hundreds, $tens, $units)
265{
266 if ($hundreds == 1 && $tens == 0 && $units == 0) {
267 return "CIEN";
268 }
269 $centenas = array("CIENTO", "DOSCIENTOS", "TRESCIENTOS", "CUATROCIENTOS", "QUINIENTOS", "SEISCIENTOS", "SETECIENTOS", "OCHOCIENTOS", "NOVECIENTOS");
270 $decenas = array("", "", "TREINTA ", "CUARENTA ", "CINCUENTA ", "SESENTA ", "SETENTA ", "OCHENTA ", "NOVENTA ");
271 $veintis = array("VEINTE", "VEINTIUN", "VEINTID&OacuteS", "VEINTITR&EacuteS", "VEINTICUATRO", "VEINTICINCO", "VEINTIS&EacuteIS", "VEINTISIETE", "VEINTIOCHO", "VEINTINUEVE");
272 $diecis = array("DIEZ", "ONCE", "DOCE", "TRECE", "CATORCE", "QUINCE", "DIECIS&EacuteIS", "DIECISIETE", "DIECIOCHO", "DIECINUEVE");
273 $unidades = array("UN", "DOS", "TRES", "CUATRO", "CINCO", "SEIS", "SIETE", "OCHO", "NUEVE");
274 $entexto = "";
275 if ($hundreds != 0) {
276 $entexto .= $centenas[$hundreds - 1];
277 }
278 if ($tens > 2) {
279 if ($hundreds != 0) {
280 $entexto .= " ";
281 }
282 $entexto .= $decenas[$tens - 1];
283 if ($units != 0) {
284 $entexto .= " Y ";
285 $entexto .= $unidades[$units - 1];
286 }
287 return $entexto;
288 } elseif ($tens == 2) {
289 if ($hundreds != 0) {
290 $entexto .= " ";
291 }
292 $entexto .= " ".$veintis[$units];
293 return $entexto;
294 } elseif ($tens == 1) {
295 if ($hundreds != 0) {
296 $entexto .= " ";
297 }
298 $entexto .= $diecis[$units];
299 return $entexto;
300 }
301 if ($units != 0) {
302 if ($hundreds != 0 || $tens != 0) {
303 $entexto .= " ";
304 }
305 $entexto .= $unidades[$units - 1];
306 }
307 return $entexto;
308}
dol_convertToWord($num, $langs, $currency='', $centimes=false)
Function to return a number into a text.
hundreds2text($hundreds, $tens, $units)
hundreds2text
dolNumberToWord($numero, $langs, $numorcurrency='number')
Function to return number or amount in text.