diff options
author | 6543 <6543@obermui.de> | 2019-12-27 21:30:58 +0100 |
---|---|---|
committer | zeripath <art27@cantab.net> | 2019-12-27 20:30:58 +0000 |
commit | f2d03cda96eb5febbf9801f6b6cf5daa37220bc9 (patch) | |
tree | 8906922ca58d47634ec2b6237f00a87389dd8316 /models/issue_tracked_time.go | |
parent | 0bcf644da4c3d21fad3ce8f33ccc26f8110568d6 (diff) | |
download | gitea-f2d03cda96eb5febbf9801f6b6cf5daa37220bc9.tar.gz gitea-f2d03cda96eb5febbf9801f6b6cf5daa37220bc9.zip |
[API] Extend times API (#9200)
Extensively extend the times API.
close #8833; close #8513; close #8559
Diffstat (limited to 'models/issue_tracked_time.go')
-rw-r--r-- | models/issue_tracked_time.go | 246 |
1 files changed, 219 insertions, 27 deletions
diff --git a/models/issue_tracked_time.go b/models/issue_tracked_time.go index f616836c85..bcb163f3c5 100644 --- a/models/issue_tracked_time.go +++ b/models/issue_tracked_time.go @@ -16,28 +16,86 @@ import ( // TrackedTime represents a time that was spent for a specific issue. type TrackedTime struct { - ID int64 `xorm:"pk autoincr" json:"id"` - IssueID int64 `xorm:"INDEX" json:"issue_id"` - UserID int64 `xorm:"INDEX" json:"user_id"` - Created time.Time `xorm:"-" json:"created"` - CreatedUnix int64 `xorm:"created" json:"-"` - Time int64 `json:"time"` + ID int64 `xorm:"pk autoincr"` + IssueID int64 `xorm:"INDEX"` + Issue *Issue `xorm:"-"` + UserID int64 `xorm:"INDEX"` + User *User `xorm:"-"` + Created time.Time `xorm:"-"` + CreatedUnix int64 `xorm:"created"` + Time int64 `xorm:"NOT NULL"` + Deleted bool `xorm:"NOT NULL DEFAULT false"` } +// TrackedTimeList is a List of TrackedTime's +type TrackedTimeList []*TrackedTime + // AfterLoad is invoked from XORM after setting the values of all fields of this object. func (t *TrackedTime) AfterLoad() { t.Created = time.Unix(t.CreatedUnix, 0).In(setting.DefaultUILocation) } +// LoadAttributes load Issue, User +func (t *TrackedTime) LoadAttributes() (err error) { + return t.loadAttributes(x) +} + +func (t *TrackedTime) loadAttributes(e Engine) (err error) { + if t.Issue == nil { + t.Issue, err = getIssueByID(e, t.IssueID) + if err != nil { + return + } + err = t.Issue.loadRepo(e) + if err != nil { + return + } + } + if t.User == nil { + t.User, err = getUserByID(e, t.UserID) + if err != nil { + return + } + } + return +} + // APIFormat converts TrackedTime to API format -func (t *TrackedTime) APIFormat() *api.TrackedTime { - return &api.TrackedTime{ - ID: t.ID, - IssueID: t.IssueID, - UserID: t.UserID, - Time: t.Time, - Created: t.Created, +func (t *TrackedTime) APIFormat() (apiT *api.TrackedTime) { + apiT = &api.TrackedTime{ + ID: t.ID, + IssueID: t.IssueID, + UserID: t.UserID, + UserName: t.User.Name, + Time: t.Time, + Created: t.Created, + } + if t.Issue != nil { + apiT.Issue = t.Issue.APIFormat() + } + if t.User != nil { + apiT.UserName = t.User.Name + } + return +} + +// LoadAttributes load Issue, User +func (tl TrackedTimeList) LoadAttributes() (err error) { + for _, t := range tl { + if err = t.LoadAttributes(); err != nil { + return err + } + } + return +} + +// APIFormat converts TrackedTimeList to API format +func (tl TrackedTimeList) APIFormat() api.TrackedTimeList { + result := make([]*api.TrackedTime, 0, len(tl)) + for _, t := range tl { + result = append(result, t.APIFormat()) } + return result } // FindTrackedTimesOptions represent the filters for tracked times. If an ID is 0 it will be ignored. @@ -50,7 +108,7 @@ type FindTrackedTimesOptions struct { // ToCond will convert each condition into a xorm-Cond func (opts *FindTrackedTimesOptions) ToCond() builder.Cond { - cond := builder.NewCond() + cond := builder.NewCond().And(builder.Eq{"tracked_time.deleted": false}) if opts.IssueID != 0 { cond = cond.And(builder.Eq{"issue_id": opts.IssueID}) } @@ -71,37 +129,73 @@ func (opts *FindTrackedTimesOptions) ToSession(e Engine) *xorm.Session { if opts.RepositoryID > 0 || opts.MilestoneID > 0 { return e.Join("INNER", "issue", "issue.id = tracked_time.issue_id").Where(opts.ToCond()) } - return x.Where(opts.ToCond()) + return e.Where(opts.ToCond()) } -// GetTrackedTimes returns all tracked times that fit to the given options. -func GetTrackedTimes(options FindTrackedTimesOptions) (trackedTimes []*TrackedTime, err error) { - err = options.ToSession(x).Find(&trackedTimes) +func getTrackedTimes(e Engine, options FindTrackedTimesOptions) (trackedTimes TrackedTimeList, err error) { + err = options.ToSession(e).Find(&trackedTimes) return } +// GetTrackedTimes returns all tracked times that fit to the given options. +func GetTrackedTimes(opts FindTrackedTimesOptions) (TrackedTimeList, error) { + return getTrackedTimes(x, opts) +} + +func getTrackedSeconds(e Engine, opts FindTrackedTimesOptions) (trackedSeconds int64, err error) { + return opts.ToSession(e).SumInt(&TrackedTime{}, "time") +} + +// GetTrackedSeconds return sum of seconds +func GetTrackedSeconds(opts FindTrackedTimesOptions) (int64, error) { + return getTrackedSeconds(x, opts) +} + // AddTime will add the given time (in seconds) to the issue -func AddTime(user *User, issue *Issue, time int64) (*TrackedTime, error) { - tt := &TrackedTime{ - IssueID: issue.ID, - UserID: user.ID, - Time: time, +func AddTime(user *User, issue *Issue, amount int64, created time.Time) (*TrackedTime, error) { + sess := x.NewSession() + defer sess.Close() + + if err := sess.Begin(); err != nil { + return nil, err } - if _, err := x.Insert(tt); err != nil { + + t, err := addTime(sess, user, issue, amount, created) + if err != nil { return nil, err } - if err := issue.loadRepo(x); err != nil { + + if err := issue.loadRepo(sess); err != nil { return nil, err } - if _, err := CreateComment(&CreateCommentOptions{ + + if _, err := createComment(sess, &CreateCommentOptions{ Issue: issue, Repo: issue.Repo, Doer: user, - Content: SecToTime(time), + Content: SecToTime(amount), Type: CommentTypeAddTimeManual, }); err != nil { return nil, err } + + return t, sess.Commit() +} + +func addTime(e Engine, user *User, issue *Issue, amount int64, created time.Time) (*TrackedTime, error) { + if created.IsZero() { + created = time.Now() + } + tt := &TrackedTime{ + IssueID: issue.ID, + UserID: user.ID, + Time: amount, + Created: created, + } + if _, err := e.Insert(tt); err != nil { + return nil, err + } + return tt, nil } @@ -131,3 +225,101 @@ func TotalTimes(options FindTrackedTimesOptions) (map[*User]string, error) { } return totalTimes, nil } + +// DeleteIssueUserTimes deletes times for issue +func DeleteIssueUserTimes(issue *Issue, user *User) error { + sess := x.NewSession() + defer sess.Close() + + if err := sess.Begin(); err != nil { + return err + } + + opts := FindTrackedTimesOptions{ + IssueID: issue.ID, + UserID: user.ID, + } + + removedTime, err := deleteTimes(sess, opts) + if err != nil { + return err + } + if removedTime == 0 { + return ErrNotExist{} + } + + if err := issue.loadRepo(sess); err != nil { + return err + } + if _, err := createComment(sess, &CreateCommentOptions{ + Issue: issue, + Repo: issue.Repo, + Doer: user, + Content: "- " + SecToTime(removedTime), + Type: CommentTypeDeleteTimeManual, + }); err != nil { + return err + } + + return sess.Commit() +} + +// DeleteTime delete a specific Time +func DeleteTime(t *TrackedTime) error { + sess := x.NewSession() + defer sess.Close() + + if err := sess.Begin(); err != nil { + return err + } + + if err := deleteTime(sess, t); err != nil { + return err + } + + if _, err := createComment(sess, &CreateCommentOptions{ + Issue: t.Issue, + Repo: t.Issue.Repo, + Doer: t.User, + Content: "- " + SecToTime(t.Time), + Type: CommentTypeDeleteTimeManual, + }); err != nil { + return err + } + + return sess.Commit() +} + +func deleteTimes(e Engine, opts FindTrackedTimesOptions) (removedTime int64, err error) { + + removedTime, err = getTrackedSeconds(e, opts) + if err != nil || removedTime == 0 { + return + } + + _, err = opts.ToSession(e).Table("tracked_time").Cols("deleted").Update(&TrackedTime{Deleted: true}) + return +} + +func deleteTime(e Engine, t *TrackedTime) error { + if t.Deleted { + return ErrNotExist{ID: t.ID} + } + t.Deleted = true + _, err := e.ID(t.ID).Cols("deleted").Update(t) + return err +} + +// GetTrackedTimeByID returns raw TrackedTime without loading attributes by id +func GetTrackedTimeByID(id int64) (*TrackedTime, error) { + time := &TrackedTime{ + ID: id, + } + has, err := x.Get(time) + if err != nil { + return nil, err + } else if !has { + return nil, ErrNotExist{ID: id} + } + return time, nil +} |