- Fix 'string(d)' int-to-rune conversion in rpg_test.go by using fmt.Sprintf - Fix ComputeDailyTotals dayStart logic: initial state should be StateWorking when dayStart > 0, correctly counting work from dayStart to first out event - Update README project structure to reflect new domain/handler/repo layout - Implement missing achievements: rpg_pioneer (on RPG enable) and salary_setter (on first rate set) - Add tryUnlockAchievement helper to Handler
52 lines
1.6 KiB
Go
52 lines
1.6 KiB
Go
package domain
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"strings"
|
|
"unicode"
|
|
)
|
|
|
|
// ComputeDailySalary calculates salary for a single day's work.
|
|
func ComputeDailySalary(workSeconds int64, hourlyRate float64) float64 {
|
|
hours := float64(workSeconds) / SecondsPerHour
|
|
return math.Round(hours*hourlyRate*SalaryRoundFactor) / SalaryRoundFactor
|
|
}
|
|
|
|
// CurrencySymbol extracts the first token as symbol, defaulting to "$".
|
|
func CurrencySymbol(currency string) string {
|
|
if parts := strings.Fields(currency); len(parts) >= 1 && parts[0] != "" {
|
|
return parts[0]
|
|
}
|
|
return "$"
|
|
}
|
|
|
|
// FormatSalary formats a salary estimate into a readable string.
|
|
func (e SalaryEstimate) FormatSalary(currency string) string {
|
|
sym := CurrencySymbol(currency)
|
|
code := "USD"
|
|
if parts := strings.Fields(currency); len(parts) >= 2 {
|
|
code = parts[1]
|
|
}
|
|
return fmt.Sprintf("%s%.2f %s", sym, e.GrossEarning, code)
|
|
}
|
|
|
|
// FormatSalaryShort returns just the symbol + amount.
|
|
func (e SalaryEstimate) FormatSalaryShort(currency string) string {
|
|
return fmt.Sprintf("%s%.2f", CurrencySymbol(currency), e.GrossEarning)
|
|
}
|
|
|
|
// ParseCurrencyInput validates and normalizes currency input (symbol + code).
|
|
func ParseCurrencyInput(s string) (string, string) {
|
|
parts := strings.Fields(s)
|
|
if len(parts) < 2 {
|
|
return "", "Please provide both symbol and code.\nUsage: /setcurrency <symbol> <code>\nExamples:\n/setcurrency $ USD\n/setcurrency T Toman\n/setcurrency IRR Rial"
|
|
}
|
|
for _, p := range parts[:2] {
|
|
if len(p) > 10 || strings.ContainsFunc(p, unicode.IsControl) {
|
|
return "", "Invalid currency. Use short printable strings like $ USD, T Toman, IRR Rial."
|
|
}
|
|
}
|
|
return parts[0] + " " + parts[1], ""
|
|
}
|