Skip to content

Commit

Permalink
Merge pull request #22 from dilaverdemirel/master
Browse files Browse the repository at this point in the history
Add Turkish Language support
  • Loading branch information
wjur authored Mar 5, 2019
2 parents 09dc0f2 + 0eaa932 commit 5263c3e
Show file tree
Hide file tree
Showing 15 changed files with 551 additions and 20 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Supported languages
* Slovak
* Ukrainian
* Serbian (latin)
* Turkish

Usage
-----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import static pl.allegro.finance.tradukisto.internal.Container.russianContainer;
import static pl.allegro.finance.tradukisto.internal.Container.serbianContainer;
import static pl.allegro.finance.tradukisto.internal.Container.slovakContainer;
import static pl.allegro.finance.tradukisto.internal.Container.turkishContainer;
import static pl.allegro.finance.tradukisto.internal.Container.ukrainianContainer;

public enum MoneyConverters {
Expand All @@ -32,6 +33,7 @@ public enum MoneyConverters {
LATVIAN_BANKING_MONEY_VALUE(latvianContainer().getBankingMoneyConverter()),
KAZAKH_BANKING_MONEY_VALUE(kazakhContainer().getBankingMoneyConverter()),
UKRAINIAN_BANKING_MONEY_VALUE(ukrainianContainer().getBankingMoneyConverter()),
TURKISH_BANKING_MONEY_VALUE(turkishContainer().getBankingMoneyConverter()),
SERBIAN_BANKING_MONEY_VALUE(serbianContainer().getBankingMoneyConverter()),
FRENCH_BANKING_MONEY_VALUE(frenchContainer().getBankingMoneyConverter());

Expand Down
16 changes: 9 additions & 7 deletions src/main/java/pl/allegro/finance/tradukisto/ValueConverters.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
package pl.allegro.finance.tradukisto;

import pl.allegro.finance.tradukisto.internal.IntegerToStringConverter;

import static com.google.common.base.Verify.verifyNotNull;
import static pl.allegro.finance.tradukisto.internal.Container.brazilianPortugueseContainer;
import static pl.allegro.finance.tradukisto.internal.Container.czechContainer;
import static pl.allegro.finance.tradukisto.internal.Container.englishContainer;
import static pl.allegro.finance.tradukisto.internal.Container.frenchContainer;
import static pl.allegro.finance.tradukisto.internal.Container.germanContainer;
import static pl.allegro.finance.tradukisto.internal.Container.italianContainer;
import static pl.allegro.finance.tradukisto.internal.Container.kazakhContainer;
import static pl.allegro.finance.tradukisto.internal.Container.latvianContainer;
import static pl.allegro.finance.tradukisto.internal.Container.polishContainer;
import static pl.allegro.finance.tradukisto.internal.Container.russianContainer;
import static pl.allegro.finance.tradukisto.internal.Container.serbianContainer;
import static pl.allegro.finance.tradukisto.internal.Container.slovakContainer;
import static pl.allegro.finance.tradukisto.internal.Container.latvianContainer;
import static pl.allegro.finance.tradukisto.internal.Container.kazakhContainer;
import static pl.allegro.finance.tradukisto.internal.Container.turkishContainer;
import static pl.allegro.finance.tradukisto.internal.Container.ukrainianContainer;
import static pl.allegro.finance.tradukisto.internal.Container.serbianContainer;
import static pl.allegro.finance.tradukisto.internal.Container.frenchContainer;

import pl.allegro.finance.tradukisto.internal.IntegerToStringConverter;

public enum ValueConverters {

Expand All @@ -31,7 +32,8 @@ public enum ValueConverters {
KAZAKH_INTEGER(kazakhContainer().getNumbersConverter()),
UKRAINIAN_INTEGER(ukrainianContainer().getNumbersConverter()),
SERBIAN_INTEGER(serbianContainer().getNumbersConverter()),
FRENCH_INTEGER(frenchContainer().getNumbersConverter());
FRENCH_INTEGER(frenchContainer().getNumbersConverter()),
TURKISH_INTEGER(turkishContainer().getNumbersConverter());

private final IntegerToStringConverter converter;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
import pl.allegro.finance.tradukisto.internal.languages.serbian.SerbianValues;
import pl.allegro.finance.tradukisto.internal.languages.slovak.SlovakValues;
import pl.allegro.finance.tradukisto.internal.languages.slovak.SlovakValuesForSmallNumbers;
import pl.allegro.finance.tradukisto.internal.languages.turkish.TurkishBigDecimalToBankingMoneyConverter;
import pl.allegro.finance.tradukisto.internal.languages.turkish.TurkishIntegerToWordsConverter;
import pl.allegro.finance.tradukisto.internal.languages.turkish.TurkishSmallNumbersToWordsConverter;
import pl.allegro.finance.tradukisto.internal.languages.turkish.TurkishValues;
import pl.allegro.finance.tradukisto.internal.languages.ukrainian.UkrainianValues;

public final class Container {
Expand Down Expand Up @@ -149,6 +153,19 @@ public static Container brazilianPortugueseContainer() {
return new Container(converter, bigDecimalBankingMoneyValueConverter);
}

public static Container turkishContainer() {
TurkishValues values = new TurkishValues();

TurkishSmallNumbersToWordsConverter smallNumbersConverter = new TurkishSmallNumbersToWordsConverter(values);
IntegerToWordsConverter bigNumbersConverter = new IntegerToWordsConverter(smallNumbersConverter, values.pluralForms());
IntegerToStringConverter converter =
new TurkishIntegerToWordsConverter(bigNumbersConverter, smallNumbersConverter);
BigDecimalToStringConverter bigDecimalBankingMoneyValueConverter =
new TurkishBigDecimalToBankingMoneyConverter(converter, values);

return new Container(converter, bigDecimalBankingMoneyValueConverter);
}

public static Container kazakhContainer() {
KazakhValues kazakhValues = new KazakhValues();
return new Container(kazakhValues);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package pl.allegro.finance.tradukisto.internal.languages.turkish;

import pl.allegro.finance.tradukisto.internal.BigDecimalToStringConverter;
import pl.allegro.finance.tradukisto.internal.IntegerToStringConverter;

import java.math.BigDecimal;

import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;

/**
* @author Dilaver Demirel
*/
public class TurkishBigDecimalToBankingMoneyConverter implements BigDecimalToStringConverter {
private static final String SUBUNIT_SEPARATOR = ",";
private static final String FORMAT = "%s%s%s%s";
private static final int MAXIMAL_DECIMAL_PLACES_COUNT = 2;

private final IntegerToStringConverter converter;
private final TurkishValues turkishValues;

public TurkishBigDecimalToBankingMoneyConverter(IntegerToStringConverter converter, TurkishValues turkishValues) {
this.converter = converter;
this.turkishValues = turkishValues;
}

@Override
public String asWords(BigDecimal value) {
validate(value);

Integer units = value.intValue();
int subunits = value.remainder(BigDecimal.ONE).multiply(new BigDecimal(100)).intValue();

String tempSubunitSymbol = turkishValues.subunitSymbol();
String tempSubUnitWords = SUBUNIT_SEPARATOR + converter.asWords(subunits);
if (subunits <= 0) {
tempSubunitSymbol = "";
tempSubUnitWords = "";
}

String formattedValue = format(FORMAT, converter.asWords(units), turkishValues.currency(), tempSubUnitWords, tempSubunitSymbol);
String convertedToMoneyTypeValue = formattedValue.replace(Character.toString(turkishValues.twoDigitsNumberSeparator()), "");
return convertedToMoneyTypeValue;
}

private void validate(BigDecimal value) {
checkArgument(value.scale() <= MAXIMAL_DECIMAL_PLACES_COUNT,
"can't transform more than %s decimal places for value %s", MAXIMAL_DECIMAL_PLACES_COUNT, value);

checkArgument(valueLessThanIntMax(value),
"can't transform numbers greater than Integer.MAX_VALUE for value %s", value);

checkArgument(valueGreaterThanOrEqualToZero(value),
"can't transform negative numbers for value %s", value);
}

private boolean valueLessThanIntMax(BigDecimal value) {
return value.compareTo(new BigDecimal(Integer.MAX_VALUE).add(BigDecimal.ONE)) == -1;
}

private boolean valueGreaterThanOrEqualToZero(BigDecimal value) {
return value.signum() >= 0;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package pl.allegro.finance.tradukisto.internal.languages.turkish;

import pl.allegro.finance.tradukisto.internal.IntegerToStringConverter;
import pl.allegro.finance.tradukisto.internal.NumberProcessor;

/**
* @author Dilaver Demirel
*/
public class TurkishIntegerToWordsConverter implements IntegerToStringConverter {

private final IntegerToStringConverter bigNumbersConverter;
private final TurkishSmallNumbersToWordsConverter smallNumbersConverter;

public TurkishIntegerToWordsConverter(IntegerToStringConverter bigNumbersConverter,
TurkishSmallNumbersToWordsConverter smallNumbersConverter) {
this.bigNumbersConverter = bigNumbersConverter;
this.smallNumbersConverter = smallNumbersConverter;
}

@Override
public String asWords(Integer value) {
Integer bigNumber = value / 1000000;
Integer smallNumber = value % 1000000;

return new NumberProcessor(bigNumbersConverter, smallNumbersConverter).process(bigNumber, smallNumber);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package pl.allegro.finance.tradukisto.internal.languages.turkish;

import pl.allegro.finance.tradukisto.internal.languages.GenderType;
import pl.allegro.finance.tradukisto.internal.languages.PluralForms;

/**
* @author Dilaver Demirel
*/
public class TurkishPluralForms implements PluralForms {

private final String form;

public TurkishPluralForms(String form) {
this.form = form;
}

@Override
public String formFor(Integer value) {
return form;
}

@Override
public GenderType genderType() {
return GenderType.NON_APPLICABLE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package pl.allegro.finance.tradukisto.internal.languages.turkish;

import com.google.common.collect.Range;
import pl.allegro.finance.tradukisto.internal.GenderAwareIntegerToStringConverter;
import pl.allegro.finance.tradukisto.internal.languages.GenderType;

import static java.lang.String.format;

/**
* @author Dilaver Demirel
* <p>
* Small numbers are between 0 and 999.999
* Big numbers are greater than 999.999
*/
public class TurkishSmallNumbersToWordsConverter implements GenderAwareIntegerToStringConverter {

private final TurkishValues turkishValues;
private final char separator;

public TurkishSmallNumbersToWordsConverter(TurkishValues turkishValues) {
this.turkishValues = turkishValues;
separator = turkishValues.twoDigitsNumberSeparator();
}

@Override
public String asWords(Integer value, GenderType genderType) {
if (turkishValues.baseNumbers().containsKey(value)) {
return turkishValues.baseNumbers().get(value).formFor(genderType);
} else if (Range.closed(21, 99).contains(value)) {
return twoDigitsNumberAsString(value, genderType);
} else if (Range.closed(101, 999).contains(value)) {
return threeDigitsNumberAsString(value, genderType);
} else if (value == 1000) {
return "Bin";
} else if (Range.closed(1001, 1999).contains(value)) {
return oneThousandsAsString(value, genderType);
} else if (Range.closed(2000, 999999).contains(value)) {
return greaterThanOneThousandsAsString(value, genderType);
}

throw new IllegalArgumentException(format("Can't convert %d", value));
}

private String twoDigitsNumberAsString(Integer value, GenderType genderType) {
Integer units = value % 10;
Integer tens = value - units;
return format("%s" + separator + "%s", asWords(tens, genderType), asWords(units, genderType));
}

private String threeDigitsNumberAsString(Integer value, GenderType genderType) {
Integer tensWithUnits = value % 100;
Integer hundreds = value - tensWithUnits;
return format("%s" + separator + "%s", asWords(hundreds, genderType), asWords(tensWithUnits, genderType));
}

private String greaterThanOneThousandsAsString(Integer value, GenderType genderType) {
Integer thousands = value / 1000;
Integer other = value % 1000;

if (other == 0) {
return format("%s" + separator + "Bin", asWords(thousands, genderType));
}
return format("%s" + separator + "Bin" + separator + "%s", asWords(thousands, genderType),
asWords(other, genderType));
}

private String oneThousandsAsString(Integer value, GenderType genderType) {
Integer other = value % 1000;
return format("Bin" + separator + "%s", asWords(other, genderType));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package pl.allegro.finance.tradukisto.internal.languages.turkish;

import pl.allegro.finance.tradukisto.internal.BaseValues;
import pl.allegro.finance.tradukisto.internal.languages.GenderForms;
import pl.allegro.finance.tradukisto.internal.languages.PluralForms;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static pl.allegro.finance.tradukisto.internal.support.BaseNumbersBuilder.baseNumbersBuilder;

public class TurkishValues implements BaseValues {

public Map<Integer, GenderForms> baseNumbers() {
return baseNumbersBuilder()
.put(0, "Sıfır")
.put(1, "Bir")
.put(2, "İki")
.put(3, "Üç")
.put(4, "Dört")
.put(5, "Beş")
.put(6, "Altı")
.put(7, "Yedi")
.put(8, "Sekiz")
.put(9, "Dokuz")
.put(10, "On")
.put(11, "On Bir")
.put(12, "On İki")
.put(13, "On Üç")
.put(14, "On Dört")
.put(15, "On Beş")
.put(16, "On Altı")
.put(17, "On Yedi")
.put(18, "On Sekiz")
.put(19, "On Dokuz")
.put(20, "Yirmi")
.put(30, "Otuz")
.put(40, "Kırk")
.put(50, "Elli")
.put(60, "Altmış")
.put(70, "Yetmiş")
.put(80, "Seksen")
.put(90, "Doksan")
.put(100, "Yüz")
.put(200, "İki Yüz")
.put(300, "Üç Yüz")
.put(400, "Dört Yüz")
.put(500, "Beş Yüz")
.put(600, "Altı Yüz")
.put(700, "Yedi Yüz")
.put(800, "Sekiz Yüz")
.put(900, "Dokuz Yüz")
.build();
}

public List<PluralForms> pluralForms() {
return Arrays.asList(
new TurkishPluralForms("Milyon"),
new TurkishPluralForms("Milyar"));
}

public String currency() {
return "TL";
}

@Override
public char twoDigitsNumberSeparator() {
return ' ';
}

public String subunitSymbol() {
return "Kr.";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@ package pl.allegro.finance.tradukisto
import com.google.common.base.VerifyException
import spock.lang.Specification

import static pl.allegro.finance.tradukisto.MoneyConverters.BRAZILIAN_PORTUGUESE_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.CZECH_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.ENGLISH_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.FRENCH_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.GERMAN_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.ITALIAN_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.KAZAKH_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.LATVIAN_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.POLISH_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.BRAZILIAN_PORTUGUESE_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.RUSSIAN_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.SERBIAN_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.SLOVAK_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.TURKISH_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.UKRAINIAN_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.SERBIAN_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.FRENCH_BANKING_MONEY_VALUE

class MoneyConvertersTest extends Specification {

Expand Down Expand Up @@ -91,4 +92,9 @@ class MoneyConvertersTest extends Specification {
then:
thrown(VerifyException)
}

def "should convert money in Turkish"() {
expect:
TURKISH_BANKING_MONEY_VALUE.asWords(1_23.4) == "YüzYirmiÜçTL,KırkKr."
}
}
Loading

0 comments on commit 5263c3e

Please sign in to comment.