package shell import ( "Portifolio/internal/model" "Portifolio/internal/service" "bufio" "database/sql" "fmt" "strconv" "strings" ) func promptInt(scanner *bufio.Scanner, label string) (int, error) { fmt.Print(label) scanner.Scan() v, err := strconv.Atoi(strings.TrimSpace(scanner.Text())) if err != nil { 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 } switch periodType { case "Y": 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: 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, parentID, value, period); err != nil { fmt.Println(" ✗ Error:", err) return } fmt.Printf(" ✓ Revenue added: %s = %.2f (%s)\n", category, value, period.String()) } func ListRevenue(scanner *bufio.Scanner, db *sql.DB) { companyID, err := promptInt(scanner, " Company ID: ") if err != nil { fmt.Println(" ✗", err) return } period, err := promptPeriod(scanner) if err != nil { fmt.Println(" ✗", err) return } entries, err := service.GetRevenue(db, companyID, period.Type, period.Year, period.Index) if err != nil { fmt.Println(" ✗ Error:", err) return } fmt.Printf("\n %-20s %12s\n", "CATEGORY", "VALUE") fmt.Println(" " + strings.Repeat("-", 34)) for _, e := range entries { fmt.Printf(" %-20s %12.2f\n", e.Category, e.Value) } }