gabor-boros/minutes

View on GitHub
internal/pkg/worklog/worklog.go

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
package worklog

import "regexp"

// FilterOpts represents the worklog creation filtering options.
// When filtering options are set, the entries are matching the regex will be
// part of the worklog, and the rest of them will be dropped. The filtering
// could be part of the fetching process, though that would be less flexible as
// some APIs are not allowing filtering. Also, this way, we can filter results
// using regex.
type FilterOpts struct {
    Client  *regexp.Regexp
    Project *regexp.Regexp
}

// Worklog is the collection of multiple Entries.
type Worklog struct {
    completeEntries   Entries
    incompleteEntries Entries
}

// CompleteEntries returns those entries which necessary fields were filled.
func (w *Worklog) CompleteEntries() Entries {
    return w.completeEntries
}

// IncompleteEntries is the opposite of CompleteEntries.
func (w *Worklog) IncompleteEntries() Entries {
    return w.incompleteEntries
}

// isEntryMatching returns true if the entry matching the filter options.
func isEntryMatching(entry Entry, opts *FilterOpts) bool {
    isClientMatching := opts.Client == nil || opts.Client.MatchString(entry.Client.Name)
    isProjectMatching := opts.Project == nil || opts.Project.MatchString(entry.Project.Name)

    return isClientMatching && isProjectMatching
}

// NewWorklog creates a worklog from the given set of entries and merges them.
func NewWorklog(entries Entries, opts *FilterOpts) Worklog {
    var filteredEntries Entries

    worklog := Worklog{}
    mergedEntries := map[string]Entry{}

    for _, entry := range entries {
        if isEntryMatching(entry, opts) {
            filteredEntries = append(filteredEntries, entry)
        }
    }

    for _, entry := range filteredEntries {
        key := entry.Key()
        storedEntry, isStored := mergedEntries[key]

        if !isStored {
            mergedEntries[key] = entry
            continue
        }

        storedEntry.BillableDuration += entry.BillableDuration
        storedEntry.UnbillableDuration += entry.UnbillableDuration

        noteSeparator := ""
        if storedEntry.Notes != "" && entry.Notes != storedEntry.Notes {
            if entry.Notes != "" {
                noteSeparator = "; "
            }

            storedEntry.Notes = storedEntry.Notes + noteSeparator + entry.Notes
        }

        mergedEntries[key] = storedEntry
    }

    for _, entry := range mergedEntries {
        if entry.IsComplete() {
            worklog.completeEntries = append(worklog.completeEntries, entry)
        } else {
            worklog.incompleteEntries = append(worklog.incompleteEntries, entry)
        }
    }

    return worklog
}