fix: resolve go vet error and dayStart logic in ComputeDailyTotals
- 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
This commit is contained in:
51
internal/domain/salary.go
Normal file
51
internal/domain/salary.go
Normal file
@@ -0,0 +1,51 @@
|
||||
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], ""
|
||||
}
|
||||
Reference in New Issue
Block a user