new rev sys
This commit is contained in:
@@ -10,144 +10,120 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func AddRevenue(scanner *bufio.Scanner, db *sql.DB) {
|
||||
fmt.Print(" Company ID: ")
|
||||
func promptInt(scanner *bufio.Scanner, label string) (int, error) {
|
||||
fmt.Print(label)
|
||||
scanner.Scan()
|
||||
companyID, err := strconv.Atoi(strings.TrimSpace(scanner.Text()))
|
||||
v, err := strconv.Atoi(strings.TrimSpace(scanner.Text()))
|
||||
if err != nil {
|
||||
fmt.Println(" ✗ Invalid company ID")
|
||||
return
|
||||
return 0, fmt.Errorf("invalid %s", label)
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func promptFloat(scanner *bufio.Scanner, label string) (float64, error) {
|
||||
fmt.Print(label)
|
||||
scanner.Scan()
|
||||
v, err := strconv.ParseFloat(strings.TrimSpace(scanner.Text()), 64)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("invalid %s", label)
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func promptString(scanner *bufio.Scanner, label string) string {
|
||||
fmt.Print(label)
|
||||
scanner.Scan()
|
||||
return strings.TrimSpace(scanner.Text())
|
||||
}
|
||||
|
||||
func promptPeriod(scanner *bufio.Scanner) (model.Period, error) {
|
||||
periodType := strings.ToUpper(promptString(scanner, " Period type (Q/H/Y): "))
|
||||
year, err := promptInt(scanner, " Year: ")
|
||||
if err != nil {
|
||||
return model.Period{}, err
|
||||
}
|
||||
|
||||
fmt.Print(" Currency ID: ")
|
||||
scanner.Scan()
|
||||
currencyID, err := strconv.Atoi(strings.TrimSpace(scanner.Text()))
|
||||
if err != nil {
|
||||
fmt.Println(" ✗ Invalid currency ID")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(" Period type (Q/H/Y): ")
|
||||
scanner.Scan()
|
||||
periodType := strings.ToUpper(strings.TrimSpace(scanner.Text()))
|
||||
|
||||
fmt.Print(" Year: ")
|
||||
scanner.Scan()
|
||||
year, err := strconv.Atoi(strings.TrimSpace(scanner.Text()))
|
||||
if err != nil {
|
||||
fmt.Println(" ✗ Invalid year")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(" Index (Q: 1-4 | H: 1-2 | Y: 1): ")
|
||||
scanner.Scan()
|
||||
idx, err := strconv.Atoi(strings.TrimSpace(scanner.Text()))
|
||||
if err != nil {
|
||||
fmt.Println(" ✗ Invalid index")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(" Category (product/location/total): ")
|
||||
scanner.Scan()
|
||||
category := strings.TrimSpace(scanner.Text())
|
||||
|
||||
fmt.Print(" Label (e.g. iPhone, Americas): ")
|
||||
scanner.Scan()
|
||||
label := strings.TrimSpace(scanner.Text())
|
||||
|
||||
fmt.Print(" Value: ")
|
||||
scanner.Scan()
|
||||
value, err := strconv.ParseFloat(strings.TrimSpace(scanner.Text()), 64)
|
||||
if err != nil {
|
||||
fmt.Println(" ✗ Invalid value")
|
||||
return
|
||||
}
|
||||
|
||||
var period model.Period
|
||||
switch periodType {
|
||||
case "Q":
|
||||
period = model.QuarterPeriod(year, idx)
|
||||
case "H":
|
||||
period = model.HalfYearPeriod(year, idx)
|
||||
case "Y":
|
||||
period = model.FullYearPeriod(year)
|
||||
return model.FullYearPeriod(year), nil
|
||||
case "Q", "H":
|
||||
label := map[string]string{"Q": " Index (1-4): ", "H": " Index (1-2): "}[periodType]
|
||||
idx, err := promptInt(scanner, label)
|
||||
if err != nil {
|
||||
return model.Period{}, err
|
||||
}
|
||||
if periodType == "Q" {
|
||||
return model.QuarterPeriod(year, idx), nil
|
||||
}
|
||||
return model.HalfYearPeriod(year, idx), nil
|
||||
default:
|
||||
fmt.Println(" ✗ Invalid period type")
|
||||
return model.Period{}, fmt.Errorf("invalid period type: %s", periodType)
|
||||
}
|
||||
}
|
||||
|
||||
func AddRevenue(scanner *bufio.Scanner, db *sql.DB) {
|
||||
companyID, err := promptInt(scanner, " Company ID: ")
|
||||
if err != nil {
|
||||
fmt.Println(" ✗", err)
|
||||
return
|
||||
}
|
||||
currencyID, err := promptInt(scanner, " Currency ID: ")
|
||||
if err != nil {
|
||||
fmt.Println(" ✗", err)
|
||||
return
|
||||
}
|
||||
period, err := promptPeriod(scanner)
|
||||
if err != nil {
|
||||
fmt.Println(" ✗", err)
|
||||
return
|
||||
}
|
||||
category := promptString(scanner, " Category name: ")
|
||||
|
||||
var parentID *int
|
||||
parentStr := promptString(scanner, " Parent category ID (leave blank for root): ")
|
||||
if parentStr != "" {
|
||||
pid, err := strconv.Atoi(parentStr)
|
||||
if err != nil {
|
||||
fmt.Println(" ✗ Invalid parent ID")
|
||||
return
|
||||
}
|
||||
parentID = &pid
|
||||
}
|
||||
|
||||
value, err := promptFloat(scanner, " Value: ")
|
||||
if err != nil {
|
||||
fmt.Println(" ✗", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := service.InsertRevenue(db, companyID, currencyID, category, label, value, period); err != nil {
|
||||
if err := service.InsertRevenue(db, companyID, currencyID, category, parentID, value, period); err != nil {
|
||||
fmt.Println(" ✗ Error:", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf(" ✓ Revenue entry added: %s / %s = %.2f (%s)\n", category, label, value, period.String())
|
||||
fmt.Printf(" ✓ Revenue added: %s = %.2f (%s)\n", category, value, period.String())
|
||||
}
|
||||
|
||||
func ListRevenue(scanner *bufio.Scanner, db *sql.DB) {
|
||||
fmt.Print(" Company ID: ")
|
||||
scanner.Scan()
|
||||
companyID, err := strconv.Atoi(strings.TrimSpace(scanner.Text()))
|
||||
companyID, err := promptInt(scanner, " Company ID: ")
|
||||
if err != nil {
|
||||
fmt.Println(" ✗ Invalid company ID")
|
||||
fmt.Println(" ✗", err)
|
||||
return
|
||||
}
|
||||
period, err := promptPeriod(scanner)
|
||||
if err != nil {
|
||||
fmt.Println(" ✗", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(" Period type (Q/H/Y): ")
|
||||
scanner.Scan()
|
||||
periodType := strings.ToUpper(strings.TrimSpace(scanner.Text()))
|
||||
|
||||
fmt.Print(" Year: ")
|
||||
scanner.Scan()
|
||||
year, _ := strconv.Atoi(strings.TrimSpace(scanner.Text()))
|
||||
|
||||
fmt.Print(" Index: ")
|
||||
scanner.Scan()
|
||||
idx, _ := strconv.Atoi(strings.TrimSpace(scanner.Text()))
|
||||
|
||||
entries, err := service.GetRevenue(db, companyID, model.PeriodType(periodType), year, idx)
|
||||
entries, err := service.GetRevenue(db, companyID, period.Type, period.Year, period.Index)
|
||||
if err != nil {
|
||||
fmt.Println(" ✗ Error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("\n %-12s %-20s %12s\n", "CATEGORY", "LABEL", "VALUE")
|
||||
fmt.Println(" " + strings.Repeat("-", 46))
|
||||
fmt.Printf("\n %-20s %12s\n", "CATEGORY", "VALUE")
|
||||
fmt.Println(" " + strings.Repeat("-", 34))
|
||||
for _, e := range entries {
|
||||
fmt.Printf(" %-12s %-20s %12.2f\n", e.Category, e.Label, e.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func SumRevenue(scanner *bufio.Scanner, db *sql.DB) {
|
||||
fmt.Print(" Company ID: ")
|
||||
scanner.Scan()
|
||||
companyID, err := strconv.Atoi(strings.TrimSpace(scanner.Text()))
|
||||
if err != nil {
|
||||
fmt.Println(" ✗ Invalid company ID")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(" Period type to sum (Q/H/Y): ")
|
||||
scanner.Scan()
|
||||
periodType := strings.ToUpper(strings.TrimSpace(scanner.Text()))
|
||||
|
||||
fmt.Print(" Year: ")
|
||||
scanner.Scan()
|
||||
year, _ := strconv.Atoi(strings.TrimSpace(scanner.Text()))
|
||||
|
||||
rs, err := service.SumRevenue(db, companyID, model.PeriodType(periodType), year)
|
||||
if err != nil {
|
||||
fmt.Println(" ✗ Error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("\n Revenue Sum — FY%d\n", year)
|
||||
fmt.Printf(" Total: %.2f\n\n", rs.Total)
|
||||
fmt.Println(" By Category:")
|
||||
for cat, sum := range rs.Categories {
|
||||
fmt.Printf(" %-15s %.2f\n", cat, sum)
|
||||
}
|
||||
fmt.Println("\n By Label:")
|
||||
for label, sum := range rs.Labels {
|
||||
fmt.Printf(" %-20s %.2f\n", label, sum)
|
||||
fmt.Printf(" %-20s %12.2f\n", e.Category, e.Value)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user