diff options
Diffstat (limited to 'internal/actions/projects.go')
-rw-r--r-- | internal/actions/projects.go | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/internal/actions/projects.go b/internal/actions/projects.go new file mode 100644 index 0000000..f991728 --- /dev/null +++ b/internal/actions/projects.go @@ -0,0 +1,64 @@ +package actions + +import ( + "context" + "database/sql" + "fmt" + "strconv" + + "punchcard/internal/queries" +) + +// CreateProject creates a new project for the specified client +func (a *actionsImpl) CreateProject(ctx context.Context, name, client string, billableRate *float64) (*queries.Project, error) { + // Find the client first + clientRecord, err := a.FindClient(ctx, client) + if err != nil { + return nil, fmt.Errorf("invalid client: %w", err) + } + + var billableRateParam sql.NullInt64 + if billableRate != nil && *billableRate > 0 { + rate := int64(*billableRate * 100) // Convert dollars to cents + billableRateParam = sql.NullInt64{Int64: rate, Valid: true} + } + + project, err := a.queries.CreateProject(ctx, queries.CreateProjectParams{ + Name: name, + ClientID: clientRecord.ID, + BillableRate: billableRateParam, + }) + if err != nil { + return nil, fmt.Errorf("failed to create project: %w", err) + } + + return &project, nil +} + +// FindProject finds a project by name or ID +func (a *actionsImpl) FindProject(ctx context.Context, nameOrID string) (*queries.Project, error) { + // Parse as ID if possible, otherwise use 0 + var idParam int64 + if id, err := strconv.ParseInt(nameOrID, 10, 64); err == nil { + idParam = id + } + + // Search by both ID and name + projects, err := a.queries.FindProject(ctx, queries.FindProjectParams{ + ID: idParam, + Name: nameOrID, + }) + if err != nil { + return nil, fmt.Errorf("database error looking up project: %w", err) + } + + // Check results + switch len(projects) { + case 0: + return nil, fmt.Errorf("%w: %s", ErrProjectNotFound, nameOrID) + case 1: + return &projects[0], nil + default: + return nil, fmt.Errorf("%w: %s matches multiple projects", ErrAmbiguousProject, nameOrID) + } +}
\ No newline at end of file |