/*
* eGov suite of products aim to improve the internal efficiency,transparency,
* accountability and the service delivery of the government organizations.
*
* Copyright (C) <2015> eGovernments Foundation
*
* The updated version of eGov suite of products as by eGovernments Foundation
* is available at http://www.egovernments.org
*
* 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
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/ or
* http://www.gnu.org/licenses/gpl.html .
*
* In addition to the terms of the GPL license to be adhered to in using this
* program, the following additional terms are to be complied with:
*
* 1) All versions of this program, verbatim or modified must carry this
* Legal Notice.
*
* 2) Any misrepresentation of the origin of the material is prohibited. It
* is required that all modified versions of this material be marked in
* reasonable ways as different from the original version.
*
* 3) This license does not grant any rights to any user of the program
* with regards to rights under trademark law for use of the trade names
* or trademarks of eGovernments Foundation.
*
* In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org.
*/
package org.egov.infra.utils;
import org.apache.commons.lang.StringUtils;
import org.egov.infra.exception.ApplicationRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import java.text.FieldPosition;
public class NumberToWord {
private static final Logger LOGGER = LoggerFactory.getLogger(NumberToWord.class);
private static final long ZEROS = 0;
private static final long UNITS = 1;
private static final long TENS = 10 * UNITS;
private static final long HUNDREDS = 10 * TENS;
private static final long THOUSANDS = 10 * HUNDREDS;
private static final long TENTHOUSANDS = 10 * THOUSANDS;
private static final long LAKHS = 10 * TENTHOUSANDS;
private static final long TENLAKHS = 10 * LAKHS;
private static final long CRORES = 10 * TENLAKHS;
private static final long TENCRORES = 10 * CRORES;
private static final long HUNDREDCRORES = 10 * TENCRORES;
private static final long THOUSANDCRORES = 10 * HUNDREDCRORES;
private static final long TENTHOUSANDCRORES = 10 * THOUSANDCRORES;
private static final String[] CARDINAL = { "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen", "Twenty", "Thirty",
"Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety", "Hundred" };
/**
* Format decimal values.
* @param value the value
* @return the string
*/
public static String formatDecimal(final Double value) {
final DecimalFormat formater = new DecimalFormat("###0.00");
final FieldPosition _fldPos = new FieldPosition(0);
final StringBuffer _adaptor = new StringBuffer();
formater.format(value, _adaptor, _fldPos);
return _adaptor.toString();
}
/**
* Amount in words.
* @param number the number
* @return the string
*/
public static String amountInWords(final Double number) {
return NumberToWord.convertToWord(formatDecimal(Double.valueOf(number)));
}
/**
* Number to string.
* @param strNumberToConvert the str number to convert
* @return the string
*/
public static String numberToString(final String strNumberToConvert) {
if (StringUtils.contains(strNumberToConvert, ".")) {
throw new ApplicationRuntimeException("Can not pass decimal values");
} else {
return NumberToWord.convertToWord(strNumberToConvert).replace("Rupees", "").replace("Only", "");
}
}
/**
* Translate the given currency number to word .
* @param number the number
* @return the string
*/
public static String convertToWord(String number) {
String paise = "";
if (number.contains(".")) {
final String[] splitPaise = number.split("[.]");
if (splitPaise.length == 2) {
if (!splitPaise[1].equals("00")) {
paise = "and " + paiseInWords(splitPaise[1]) + " " + "Paise Only";
}
}
number = splitPaise[0];
}
final String returnValue = translateToWord(number);
return (paise.isEmpty() ? ("Rupees " + returnValue + " Only ") : ("Rupees " + returnValue + " " + paise));
}
/**
* Translate the given number to word. Decimal places not allowed, for decimal use {@see NumberToWord#convertToWord(String)}
* @param String number
* @return String word
**/
public static String translateToWord(String number) {
long num = 0L;
try {
num = Long.parseLong(number);
} catch (final NumberFormatException e) {
LOGGER.error("Invalid Number, Please enter a valid Number.");
throw new ApplicationRuntimeException("Exception occurred in convertToWord", e);
}
Long subNum = 0L;
String returnValue = "";
if (Long.parseLong(number) == ZEROS || number.length() > 12) {
returnValue += getWord(Long.parseLong(number));
}
while (num > 0 && number.length() <= 12) {
number = "" + num;
final long place = getPlace(number);
if (place == HUNDREDCRORES || place == THOUSANDCRORES || place == TENTHOUSANDCRORES) {
subNum = Long.parseLong("" + number.charAt(0));
returnValue += getWord(subNum);
if (place == HUNDREDCRORES) {
num -= subNum * HUNDREDCRORES;
if (num == 0) {
returnValue += " Hundred Crores ";
} else {
returnValue += " Hundred ";
}
} else if (place == THOUSANDCRORES) {
num -= subNum * THOUSANDCRORES;
if (num == 0) {
returnValue += " Thousand Crores ";
} else {
returnValue += " Thousand ";
}
} else {
returnValue = "";
subNum = Long.parseLong(number.charAt(0) + "" + number.charAt(1));
num -= subNum * THOUSANDCRORES;
if (subNum >= 21 && (subNum % 10) != 0 && num == 0) {
returnValue += getWord(Long.parseLong(String.valueOf(number.charAt(0))) * 10) + " " + getWord(subNum % 10) + " Thousand Crores ";
} else if (num == 0) {
returnValue += getWord(Long.parseLong(String.valueOf(number.charAt(0))) * 10) + " " + " Thousand Crores ";
} else {
returnValue += getWord(Long.parseLong(String.valueOf(number.charAt(0))) * 10) + " " + getWord(subNum % 10) + " Thousand ";
}
}
} else if (place == TENS || place == TENTHOUSANDS || place == TENLAKHS || place == TENCRORES) {
subNum = Long.parseLong(String.valueOf(number.charAt(0)) + String.valueOf(number.charAt(1)));
if (subNum >= 21 && (subNum % 10) != 0) {
returnValue += getWord(Long.parseLong(String.valueOf(number.charAt(0))) * 10) + " " + getWord(subNum % 10);
} else {
returnValue += getWord(subNum);
}
if (place == TENS) {
num = 0;
} else if (place == TENTHOUSANDS) {
num -= subNum * THOUSANDS;
returnValue += " Thousands ";
} else if (place == TENLAKHS) {
num -= subNum * LAKHS;
returnValue += " Lakhs ";
} else if (place == TENCRORES) {
num -= subNum * CRORES;
returnValue += " Crores ";
}
} else {
subNum = Long.parseLong(String.valueOf(number.charAt(0)));
returnValue += getWord(subNum);
if (place == UNITS) {
num = 0;
} else if (place == HUNDREDS) {
num -= subNum * HUNDREDS;
returnValue += " Hundred ";
} else if (place == THOUSANDS) {
num -= subNum * THOUSANDS;
returnValue += " Thousand ";
} else if (place == LAKHS) {
num -= subNum * LAKHS;
returnValue += " Lakh ";
} else if (place == CRORES) {
num -= subNum * CRORES;
returnValue += " Crore ";
}
}
}
return returnValue;
}
/**
* Normalize the unformatted number by removing comma and space.
* @param number the number
* @return the string
*/
private static String normalize(final String number) {
final String cleanedNumber = number.replace(',', ' ').replaceAll(" ", "");
if (number.length() > 1 && cleanedNumber.startsWith("0")) {
return cleanedNumber.replaceFirst("0", "");
}
return cleanedNumber;
}
/**
* this method returns the place where the number exists. it does by checking number length. Gets the place.
* @param number the number
* @return the place
*/
private static long getPlace(final String number) {
switch (number.length()) {
case 1:
return UNITS;
case 2:
return TENS;
case 3:
return HUNDREDS;
case 4:
return THOUSANDS;
case 5:
return TENTHOUSANDS;
case 6:
return LAKHS;
case 7:
return TENLAKHS;
case 8:
return CRORES;
case 9:
return TENCRORES;
case 10:
return HUNDREDCRORES;
case 11:
return THOUSANDCRORES;
case 12:
return TENTHOUSANDCRORES;
}
return 0;
}
/**
* Gets the word.
* @param number the number
* @return the word
*/
public static String getWord(final Long number) {
final int value = number.intValue();
switch (value) {
case 30:
return CARDINAL[21];
case 40:
return CARDINAL[22];
case 50:
return CARDINAL[23];
case 60:
return CARDINAL[24];
case 70:
return CARDINAL[25];
case 80:
return CARDINAL[26];
case 90:
return CARDINAL[27];
case 100:
return CARDINAL[28];
default:
if ((value < 21)) {
return CARDINAL[value];
} else {
return "";
}
}
}
/**
* Paise in words.
* @param paise the paise
* @return the string
*/
private static String paiseInWords(final String paise) {
Long subNum = 0L;
String returnValue = "";
if (paise.length() >= 2) {
subNum = Long.parseLong(paise.charAt(0) + "" + paise.charAt(1));
} else {
subNum = Long.parseLong(paise.charAt(0) + "");
}
if (subNum >= 21 && (subNum % 10) != 0) {
returnValue += getWord(Long.parseLong("" + paise.charAt(0)) * 10) + " " + getWord(subNum % 10);
} else {
returnValue += getWord(subNum);
}
return returnValue;
}
}