package models import ( "context" "sort" "time" ) type Project struct { ID string `json:"id" db:"project_id"` UserID string `json:"-" db:"user_id"` GroupID *string `json:"groupId" db:"project_group_id"` Name string `json:"name" db:"name"` Description string `json:"description" db:"description"` Icon string `json:"icon" db:"icon"` Active bool `json:"active" db:"active"` CreatedTime time.Time `json:"createdTime" db:"created_time"` StartTime *time.Time `json:"startTime" db:"start_time"` EndTime *time.Time `json:"endTime" db:"end_time"` SubtractAmount int `json:"subtractAmount" db:"subtract_amount"` StatusTag *string `json:"statusTag" db:"status_tag"` Favorite bool `json:"favorite" db:"favorite"` Tags []string `json:"tags" db:"tags"` TaskSortFields []string `json:"taskSortFields" db:"task_sort_fields"` } func (project *Project) Update(update ProjectUpdate) { if update.GroupID != nil { if *update.GroupID == "" { project.GroupID = nil } else { project.GroupID = update.GroupID } } if update.Name != nil { project.Name = *update.Name } if update.Description != nil { project.Description = *update.Description } if update.Icon != nil { project.Icon = *update.Icon } if update.Active != nil { project.Active = *update.Active } if update.StartTime != nil { startTimeCopy := update.StartTime.UTC() project.StartTime = &startTimeCopy } if update.ClearStartTime { project.StartTime = nil } if update.EndTime != nil { endTimeCopy := update.EndTime.UTC() project.EndTime = &endTimeCopy } if update.ClearEndTime { project.EndTime = nil } if update.SubtractAmount != nil { project.SubtractAmount = *update.SubtractAmount if project.SubtractAmount < 0 { project.SubtractAmount = 0 } } if update.StatusTag != nil { project.StatusTag = update.StatusTag } if update.ClearStatusTag { project.StatusTag = nil } if update.Favorite != nil { project.Favorite = *update.Favorite } if update.SetTags != nil { project.Tags = update.SetTags } if update.TaskSortFields != nil { project.TaskSortFields = append(update.TaskSortFields[:0:0], update.TaskSortFields...) } if project.StatusTag != nil && project.Active { project.StatusTag = nil } } type ProjectUpdate struct { GroupID *string `json:"groupId"` Name *string `json:"name"` Description *string `json:"description"` Icon *string `json:"icon"` Active *bool `json:"active"` StartTime *time.Time `json:"startTime"` ClearStartTime bool `json:"clearStartTime"` EndTime *time.Time `json:"endTime"` ClearEndTime bool `json:"clearEndTime"` SubtractAmount *int `json:"subtractAmount"` StatusTag *string `json:"statusTag"` ClearStatusTag bool `json:"clearStatusTag"` SetTags []string `json:"setTags"` Favorite *bool `json:"favorite"` TaskSortFields []string `json:"taskSortFields"` } type ProjectResult struct { Project Tasks []*TaskResult `json:"tasks"` Subtractions []ProjectSubtraction `json:"subtractions"` } func (result *ProjectResult) SortTasks() { sorter := TaskSorter{ Data: result.Tasks, Fields: result.Project.TaskSortFields, } if len(sorter.Fields) == 0 { sorter.Fields = []string{"status"} } sort.Sort(sorter) } type ProjectSubtraction struct { Item Item `json:"item"` Amount int `json:"amount"` } type ProjectFilter struct { UserID string ProjectGroupIDs []string Active *bool Favorite *bool Expiring bool IncludeSemiActive bool IDs []string Ungrouped bool } type ProjectRepository interface { Find(ctx context.Context, id string) (*Project, error) List(ctx context.Context, filter ProjectFilter) ([]*Project, error) Insert(ctx context.Context, project Project) error Update(ctx context.Context, project Project) error Delete(ctx context.Context, project Project) error }