Files
Portfolio-Engine/internal/shell/revenue.go

146 lines
3.4 KiB
Go

package shell
import (
"Portifolio/internal/database"
"Portifolio/internal/model"
"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
}
// checking if company exits
_, err = database.GetCompanyByID(db, companyID)
if err != nil {
fmt.Println("No company by that id:", 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
}
rev := model.RevenueInsert{
CompanyID: companyID,
CurrencyID: currencyID,
CategoryName: category,
ParentID: *parentID,
Period: period,
Value: value,
}
err = database.InsertRevenue(db, rev)
if 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 := database.GetRevenueByPeriod(db, companyID, period.ID)
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)
}
}