001// --------------------------------------------------------------------------------
002// Copyright 2002-2025 Echo Three, LLC
003//
004// Licensed under the Apache License, Version 2.0 (the "License");
005// you may not use this file except in compliance with the License.
006// You may obtain a copy of the License at
007//
008//     http://www.apache.org/licenses/LICENSE-2.0
009//
010// Unless required by applicable law or agreed to in writing, software
011// distributed under the License is distributed on an "AS IS" BASIS,
012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013// See the License for the specific language governing permissions and
014// limitations under the License.
015// --------------------------------------------------------------------------------
016
017package com.echothree.util.common.string;
018
019import com.echothree.model.control.accounting.common.transfer.CurrencyTransfer;
020import com.google.common.math.IntMath;
021import java.util.Formatter;
022
023public class AmountUtils {
024
025    private AmountUtils() {
026        super();
027    }
028
029    private static class AmountUtilsHolder {
030        static AmountUtils instance = new AmountUtils();
031    }
032
033    public static AmountUtils getInstance() {
034        return AmountUtilsHolder.instance;
035    }
036
037    public String formatAmount(CurrencyTransfer currency, Integer amount) {
038        String result = null;
039
040        if(amount != null) {
041            int fractionDigits = currency.getDefaultFractionDigits();
042
043            if(fractionDigits == 0) {
044                result = amount.toString();
045            } else {
046                int rawAmount = amount;
047                var i = IntMath.checkedPow(10, fractionDigits);
048                var builtResult = new StringBuilder().append(rawAmount / i).append(currency.getFractionSeparator());
049
050                new Formatter(builtResult).format("%0" + fractionDigits + "d", Math.abs(rawAmount) % i);
051                result = builtResult.toString();
052            }
053        }
054
055        return result;
056    }
057
058    public String formatPriceUnit(CurrencyTransfer currency, Integer priceUnit) {
059        String result = null;
060
061        if(priceUnit != null) {
062            var priceUnitFractionDigits = currency.getPriceUnitFractionDigits();
063            var fractionDigits = priceUnitFractionDigits == null ? 0 : priceUnitFractionDigits;
064
065            if(fractionDigits == 0) {
066                result = priceUnit.toString();
067            } else {
068                int rawPriceUnit = priceUnit;
069                var i = IntMath.checkedPow(10, fractionDigits);
070                var builtResult = new StringBuilder().append(rawPriceUnit / i).append(currency.getFractionSeparator());
071
072                new Formatter(builtResult).format("%0" + fractionDigits + "d", Math.abs(rawPriceUnit) % i);
073                result = builtResult.toString();
074            }
075        }
076
077        return result;
078    }
079
080    public String formatPriceLine(CurrencyTransfer currency, Integer priceLine) {
081        String result = null;
082
083        if(priceLine != null) {
084            var priceLineFractionDigits = currency.getPriceLineFractionDigits();
085            var fractionDigits = priceLineFractionDigits == null ? 0 : priceLineFractionDigits;
086
087            if(fractionDigits == 0) {
088                result = priceLine.toString();
089            } else {
090                int rawPriceLine = priceLine;
091                var i = IntMath.checkedPow(10, fractionDigits);
092                var builtResult = new StringBuilder().append(rawPriceLine / i).append(currency.getFractionSeparator());
093
094                new Formatter(builtResult).format("%0" + fractionDigits + 'd', Math.abs(rawPriceLine) % i);
095                result = builtResult.toString();
096            }
097        }
098
099        return result;
100    }
101
102    public String formatCostUnit(CurrencyTransfer currency, Integer costUnit) {
103        String result = null;
104
105        if(costUnit != null) {
106            var costUnitFractionDigits = currency.getCostUnitFractionDigits();
107            var fractionDigits = costUnitFractionDigits == null ? 0 : costUnitFractionDigits;
108
109            if(fractionDigits == 0) {
110                result = costUnit.toString();
111            } else {
112                int rawCostUnit = costUnit;
113                var i = IntMath.checkedPow(10, fractionDigits);
114                var builtResult = new StringBuilder().append(rawCostUnit / i).append(currency.getFractionSeparator());
115
116                new Formatter(builtResult).format("%0" + fractionDigits + 'd', Math.abs(rawCostUnit) % i);
117                result = builtResult.toString();
118            }
119        }
120
121        return result;
122    }
123
124    public String formatCostLine(CurrencyTransfer currency, Integer costLine) {
125        String result = null;
126
127        if(costLine != null) {
128            var costLineFractionDigits = currency.getCostLineFractionDigits();
129            var fractionDigits = costLineFractionDigits == null ? 0 : costLineFractionDigits;
130
131            if(fractionDigits == 0) {
132                result = costLine.toString();
133            } else {
134                int rawCostLine = costLine;
135                var i = IntMath.checkedPow(10, fractionDigits);
136                var builtResult = new StringBuilder().append(rawCostLine / i).append(currency.getFractionSeparator());
137
138                new Formatter(builtResult).format("%0" + fractionDigits + 'd', Math.abs(rawCostLine) % i);
139                result = builtResult.toString();
140            }
141        }
142
143        return result;
144    }
145
146    public AmountFormatter getAmountFormatter(CurrencyTransfer currency, AmountFormatType amountFormatType) {
147        return new AmountFormatter(currency, amountFormatType);
148    }
149    
150}