Files
kjol/finance/helpers.go

235 lines
5.4 KiB
Go

package finance
import (
. "kjol/basic"
"fmt"
"math"
"strconv"
"strings"
)
// takes a number such as 123456, and outputs (1234, 56) as strings
func SplitInt64(n int64) (string, string) {
// Calculate the first part as string
firstPart := fmt.Sprintf("%d", n/100)
// Calculate the second part as string with leading zero if necessary
secondPart := fmt.Sprintf("%02d", n%100)
return firstPart, secondPart
}
func Int64ToMoney(value int64) string {
decimalValue := float64(value) / 100.0
moneyString := fmt.Sprintf("%.2f", decimalValue)
return moneyString
}
func Int64ToMoneyWithCommas(value int64) string {
decimalValue := float64(value) / 100.0
moneyString := fmt.Sprintf("%.2f", decimalValue)
parts := strings.Split(moneyString, ".")
dollars := parts[0]
cents := parts[1]
negative := false
if strings.HasPrefix(dollars, "-") {
negative = true
dollars = dollars[1:]
}
result := ""
for i, char := range dollars {
if i > 0 && (len(dollars)-i)%3 == 0 {
result += ","
}
result += string(char)
}
if negative {
result = "-" + result
}
return result + "." + cents
}
func MoneyToInt64(input string) int64 {
if !strings.Contains(input, ".") {
input += ".00"
} else if strings.Count(input, ".") == 1 {
digits := strings.Split(input, ".")
if len(digits[1]) == 1 {
input += "0"
}
}
processedString := strings.ReplaceAll(input, ".", "")
processedString = strings.ReplaceAll(processedString, ",", "")
processedString = strings.ReplaceAll(processedString, " ", "")
result, _ := strconv.Atoi(processedString)
return int64(result)
}
func Int64ToRate(rate int64) string {
decimalValue := float64(rate) / 1000.0
rateString := fmt.Sprintf("%.3f", decimalValue)
return rateString
}
func RoundUpToCeiling(input int64) int64 {
remainder := input % 100
if remainder == 0 {
return input
}
return input + 100 - remainder
}
func RoundDownToFloor(input int64) int64 {
remainder := input % 100
if remainder == 0 {
return input
}
return input - remainder
}
func MultiplyByPercentageS64(amount int64, percentage float64) int64 {
amount_float64 := float64(amount) / 100
out_float64 := (amount_float64 * (percentage / 100))
out_int64 := int64(math.Round(out_float64 * 100))
return out_int64
}
func MultiplyByPercentageF64(amount int64, percentage float64) float64 {
amount_float64 := float64(amount) / 100
return amount_float64 * percentage
}
func ProcessDiscount(discount string) float64 {
discount_f64, _ := strconv.ParseFloat(discount, 64)
if discount_f64 < 0 {
return 0
} else if discount_f64 > 100 {
return 100
}
return discount_f64
}
// DaysToRateTerm Takes days as an input and outputs the string representation of the number of
// days, months, or years in the term based on which unit is the best fit for the amount of days
// along with the corresponding unit string.
func DaysToRateTerm(days int32) (string, string) {
years := days / 365
months := (days - years*365) / 30
dayRemainder := days - years*365 - months*30
if days == 0 { // Return empty string for value
return "", "days"
} else if days <= 270 || dayRemainder > 0 {
return ToString(days), "days"
} else if months > 0 {
return ToString(months + years*12), "months"
} else {
return ToString(years), "years"
}
}
func RateTermToDays(value string, unit string) int32 {
valueInt := StringToInt32(value)
switch unit {
case "months":
years := valueInt / 12
months := valueInt % 12
return years*365 + months*30
case "years":
return valueInt * 365
default: // case "days":
return valueInt
}
}
func RateToString(rateValue float64) string {
str, err := NumberToString(rateValue, 3, "%", true)
if err != nil {
fmt.Println(err)
return fmt.Sprint(rateValue)
}
return str
}
func RatePlainToString(rateValue float64) string {
str, err := NumberToString(rateValue, 3, "", false)
if err != nil {
fmt.Println(err)
return fmt.Sprint(rateValue)
}
return str
}
func DollarAmountToString(amount float64) string {
str, err := NumberToString(amount, 2, "", false)
if err != nil {
fmt.Println(err)
return fmt.Sprint(amount)
}
return str
}
func DollarAmountPlainToString(amount float64) string {
str, err := NumberToString(amount, 2, "$", false)
if err != nil {
fmt.Println(err)
return fmt.Sprint(amount)
}
return str
}
func NumberToString(i any, precision int, symbol string, symbolLast bool) (string, error) {
var numberFloat float64 = 0.0
err := fmt.Errorf("error: could not convert %s to a decimal value", i)
switch i.(type) {
case int32, int64, int, uint64, uint32, uint, float32, float64:
if val, ok := i.(float64); ok {
numberFloat = val
} else {
return "", err
}
default:
return "", fmt.Errorf("error: could not convert %s to a decimal value", i)
}
s := fmt.Sprintf("%.[2]*[1]f", numberFloat, precision)
parts := strings.Split(s, ".")
if len(parts) == 0 {
return "", fmt.Errorf("error: could not convert '%s' to a decimal value", s)
}
numberLeftSide := parts[0][len(parts[0])-1:]
for i := len(parts[0]) - 2; i >= 0; i-- {
if len(strings.Replace(numberLeftSide, ",", "", -1))%3 == 0 {
numberLeftSide = "," + numberLeftSide
}
numberLeftSide = string(parts[0][i]) + numberLeftSide
}
numberToReturn := numberLeftSide
if len(parts) > 1 {
numberToReturn = numberToReturn + "." + parts[1]
}
if symbol != "" {
if symbolLast {
numberToReturn = numberToReturn + symbol
} else {
numberToReturn = symbol + numberToReturn
}
}
return numberToReturn, nil
}