Initial add backend stuff
This commit is contained in:
234
finance/helpers.go
Normal file
234
finance/helpers.go
Normal file
@@ -0,0 +1,234 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user