diff options
Diffstat (limited to 'internal/actions/timer.go')
-rw-r--r-- | internal/actions/timer.go | 74 |
1 files changed, 57 insertions, 17 deletions
diff --git a/internal/actions/timer.go b/internal/actions/timer.go index a7e7bbb..d5a85e1 100644 --- a/internal/actions/timer.go +++ b/internal/actions/timer.go @@ -11,10 +11,10 @@ import ( // PunchIn starts a timer for the specified client/project // Use empty strings for client/project to use most recent entry -func (a *actions) PunchIn(ctx context.Context, client, project, description string, billableRate *float64) (*TimerSession, error) { +func (a *actions) PunchIn(ctx context.Context, client, project, description string, billableRate *float64, autoUnarchive bool) (*TimerSession, error) { // If no client specified, delegate to PunchInMostRecent if client == "" && project == "" { - session, err := a.PunchInMostRecent(ctx, description, billableRate) + session, err := a.PunchInMostRecent(ctx, description, billableRate, autoUnarchive) if err != nil { // Convert "no recent entries" error to "client required" for better UX if errors.Is(err, ErrNoRecentEntries) { @@ -73,6 +73,28 @@ func (a *actions) PunchIn(ctx context.Context, client, project, description stri return nil, ErrClientRequired } + // Check if client is archived + if resolvedClient.Archived != 0 { + if !autoUnarchive { + return nil, ErrArchivedClient + } + // Auto-unarchive the client + if err := a.UnarchiveClient(ctx, resolvedClient.ID); err != nil { + return nil, fmt.Errorf("failed to unarchive client: %w", err) + } + } + + // Check if project is archived + if resolvedProject != nil && resolvedProject.Archived != 0 { + if !autoUnarchive { + return nil, ErrArchivedProject + } + // Auto-unarchive the project + if err := a.UnarchiveProject(ctx, resolvedProject.ID); err != nil { + return nil, fmt.Errorf("failed to unarchive project: %w", err) + } + } + var stoppedEntryID *int64 // Check for identical timer if one is active @@ -119,7 +141,7 @@ func (a *actions) PunchIn(ctx context.Context, client, project, description stri } // PunchInMostRecent starts a timer copying the most recent time entry -func (a *actions) PunchInMostRecent(ctx context.Context, description string, billableRate *float64) (*TimerSession, error) { +func (a *actions) PunchInMostRecent(ctx context.Context, description string, billableRate *float64, autoUnarchive bool) (*TimerSession, error) { // Get most recent entry mostRecent, err := a.queries.GetMostRecentTimeEntry(ctx) if err != nil { @@ -135,6 +157,37 @@ func (a *actions) PunchInMostRecent(ctx context.Context, description string, bil finalDescription = mostRecent.Description.String } + // Get client to check if archived + client, err := a.FindClient(ctx, fmt.Sprintf("%d", mostRecent.ClientID)) + if err != nil { + return nil, fmt.Errorf("failed to get client: %w", err) + } + + // Check if client is archived + if client.Archived != 0 { + if !autoUnarchive { + return nil, ErrArchivedClient + } + // Auto-unarchive the client + if err := a.UnarchiveClient(ctx, client.ID); err != nil { + return nil, fmt.Errorf("failed to unarchive client: %w", err) + } + } + + // Check if project is archived (if exists) + if mostRecent.ProjectID.Valid { + project, err := a.FindProject(ctx, fmt.Sprintf("%d", mostRecent.ProjectID.Int64)) + if err == nil && project.Archived != 0 { + if !autoUnarchive { + return nil, ErrArchivedProject + } + // Auto-unarchive the project + if err := a.UnarchiveProject(ctx, project.ID); err != nil { + return nil, fmt.Errorf("failed to unarchive project: %w", err) + } + } + } + // Check if there's already an active timer activeEntry, err := a.queries.GetActiveTimeEntry(ctx) var hasActiveTimer bool @@ -148,13 +201,6 @@ func (a *actions) PunchInMostRecent(ctx context.Context, description string, bil // Check for identical timer if one is active if hasActiveTimer { if timeEntriesMatch(mostRecent.ClientID, mostRecent.ProjectID, finalDescription, billableRate, activeEntry) { - // Get client/project names for the result - client, _ := a.FindClient(ctx, fmt.Sprintf("%d", mostRecent.ClientID)) - clientName := "" - if client != nil { - clientName = client.Name - } - var projectName string if mostRecent.ProjectID.Valid { project, _ := a.FindProject(ctx, fmt.Sprintf("%d", mostRecent.ProjectID.Int64)) @@ -166,7 +212,7 @@ func (a *actions) PunchInMostRecent(ctx context.Context, description string, bil // No-op: identical timer already active return &TimerSession{ ID: activeEntry.ID, - ClientName: clientName, + ClientName: client.Name, ProjectName: projectName, Description: finalDescription, StartTime: activeEntry.StartTime, @@ -190,12 +236,6 @@ func (a *actions) PunchInMostRecent(ctx context.Context, description string, bil return nil, err } - // Get client name - client, err := a.FindClient(ctx, fmt.Sprintf("%d", mostRecent.ClientID)) - if err != nil { - return nil, fmt.Errorf("failed to get client name: %w", err) - } - // Get project name if exists var projectName string if mostRecent.ProjectID.Valid { |