From 058504526095df96d554ffe7e6a3420d01360845 Mon Sep 17 00:00:00 2001 From: kolaente Date: Fri, 21 Mar 2025 17:32:50 +0100 Subject: [PATCH] fix(kanban): Mark tasks done when creating them in the done bucket Resolves https://community.vikunja.io/t/bugs-around-project-duplication-with-kanban-buckets/3433/6 --- pkg/models/tasks.go | 142 +++++++++++++++++++++++++++----------------- 1 file changed, 88 insertions(+), 54 deletions(-) diff --git a/pkg/models/tasks.go b/pkg/models/tasks.go index de373727c..56aec0828 100644 --- a/pkg/models/tasks.go +++ b/pkg/models/tasks.go @@ -961,8 +961,10 @@ func setTaskInBucketInViews(s *xorm.Session, t *Task, a web.Auth, setBucket bool positions := []*TaskPosition{} taskBuckets := []*TaskBucket{} + var moveToDone bool + for _, view := range views { - if setBucket && + if setBucket && !moveToDone && view.ViewKind == ProjectViewKindKanban && view.BucketConfigurationMode == BucketConfigurationModeManual { @@ -978,6 +980,25 @@ func setTaskInBucketInViews(s *xorm.Session, t *Task, a web.Auth, setBucket bool } } + if view.DoneBucketID != 0 && view.DoneBucketID == t.BucketID && !t.Done { + t.Done = true + _, err = s.Where("id = ?", t.ID). + Cols("done"). + Update(t) + if err != nil { + return nil, nil, err + } + + err = t.moveTaskToDoneBuckets(s, a, views) + if err != nil { + return nil, nil, err + } + + moveToDone = true + + continue + } + taskBuckets = append(taskBuckets, &TaskBucket{ BucketID: bucketID, TaskID: t.ID, @@ -992,6 +1013,11 @@ func setTaskInBucketInViews(s *xorm.Session, t *Task, a web.Auth, setBucket bool positions = append(positions, newPosition) } + + if moveToDone { + taskBuckets = []*TaskBucket{} + } + return positions, taskBuckets, nil } @@ -1122,59 +1148,9 @@ func (t *Task) Update(s *xorm.Session, a web.Auth) (err error) { // When a task changed its done status, make sure it is in the correct bucket if t.ProjectID == ot.ProjectID && !t.isRepeating() && t.Done != ot.Done { - for _, view := range views { - currentTaskBucket := &TaskBucket{} - _, err := s.Where("task_id = ? AND project_view_id = ?", t.ID, view.ID). - Get(currentTaskBucket) - if err != nil { - return err - } - - var bucketID = currentTaskBucket.BucketID - - // Task done, but no done bucket? Do nothing - if t.Done && view.DoneBucketID == 0 { - continue - } - - // Task not done, currently not in done bucket? Do nothing - if !t.Done && bucketID != view.DoneBucketID { - continue - } - - // Task done? Done bucket - if t.Done && view.DoneBucketID != 0 { - bucketID = view.DoneBucketID - } - - // Task not done, currently in done bucket? Move to default - if !t.Done && bucketID == view.DoneBucketID { - bucketID, err = getDefaultBucketID(s, view) - if err != nil { - return err - } - } - - tb := &TaskBucket{ - BucketID: bucketID, - TaskID: t.ID, - ProjectViewID: view.ID, - ProjectID: t.ProjectID, - } - err = tb.Update(s, a) - if err != nil { - return err - } - - tp := TaskPosition{ - TaskID: t.ID, - ProjectViewID: view.ID, - Position: calculateDefaultPosition(t.Index, t.Position), - } - err = tp.Update(s, a) - if err != nil { - return err - } + err = t.moveTaskToDoneBuckets(s, a, views) + if err != nil { + return } } @@ -1327,6 +1303,64 @@ func (t *Task) Update(s *xorm.Session, a web.Auth) (err error) { return updateProjectLastUpdated(s, &Project{ID: t.ProjectID}) } +func (t *Task) moveTaskToDoneBuckets(s *xorm.Session, a web.Auth, views []*ProjectView) error { + for _, view := range views { + currentTaskBucket := &TaskBucket{} + _, err := s.Where("task_id = ? AND project_view_id = ?", t.ID, view.ID). + Get(currentTaskBucket) + if err != nil { + return err + } + + var bucketID = currentTaskBucket.BucketID + + // Task done, but no done bucket? Do nothing + if t.Done && view.DoneBucketID == 0 { + continue + } + + // Task not done, currently not in done bucket? Do nothing + if !t.Done && bucketID != view.DoneBucketID { + continue + } + + // Task done? Done bucket + if t.Done && view.DoneBucketID != 0 { + bucketID = view.DoneBucketID + } + + // Task not done, currently in done bucket? Move to default + if !t.Done && bucketID == view.DoneBucketID { + bucketID, err = getDefaultBucketID(s, view) + if err != nil { + return err + } + } + + tb := &TaskBucket{ + BucketID: bucketID, + TaskID: t.ID, + ProjectViewID: view.ID, + ProjectID: t.ProjectID, + } + err = tb.Update(s, a) + if err != nil { + return err + } + + tp := TaskPosition{ + TaskID: t.ID, + ProjectViewID: view.ID, + Position: calculateDefaultPosition(t.Index, t.Position), + } + err = tp.Update(s, a) + if err != nil { + return err + } + } + return nil +} + func addOneMonthToDate(d time.Time) time.Time { return time.Date(d.Year(), d.Month()+1, d.Day(), d.Hour(), d.Minute(), d.Second(), d.Nanosecond(), config.GetTimeZone()) }