fix: skip bucket update for recurring tasks when no default bucket is set

This commit is contained in:
nithinvarma411 2026-05-30 15:05:27 +05:30
parent 19ce8bb034
commit e9d9c2ae4b
2 changed files with 21 additions and 37 deletions

View File

@ -148,8 +148,8 @@ func updateTaskBucket(s *xorm.Session, a web.Auth, b *TaskBucket) (err error) {
// A repeating task doesn't stay in the done bucket; route
// it back to the view's default bucket so the user sees
// the next iteration waiting in the "To-Do" column.
// When no explicit default bucket is configured, preserve
// the task's original bucket so it remains in place.
// When no default bucket is configured, leave the task in
// its current bucket — no update needed.
if view.DefaultBucketID != 0 {
b.BucketID, err = getDefaultBucketID(s, view)
if err != nil {
@ -158,10 +158,10 @@ func updateTaskBucket(s *xorm.Session, a web.Auth, b *TaskBucket) (err error) {
} else {
b.BucketID = oldTaskBucket.BucketID
}
// If the task is already in the correct bucket, skip the
// upsert — MySQL's UPDATE returns 0 affected rows when
// the value is unchanged, which would make upsert fall
// through to INSERT and hit the unique constraint.
// If the bucket is unchanged, skip the upsert — MySQL's
// UPDATE returns 0 affected rows when the value is unchanged,
// which would make upsert fall through to INSERT and hit the
// unique constraint.
if b.BucketID == oldTaskBucket.BucketID {
updateBucket = false
}

View File

@ -1528,51 +1528,35 @@ func (t *Task) moveTaskToDoneBuckets(s *xorm.Session, a web.Auth, views []*Proje
// and is used when a repeating task is marked done: repeating tasks
// don't stay in the done bucket, so they should be routed back to
// the default ("To-Do") bucket so the next iteration is visible there.
// When no explicit default bucket is configured, the task is restored
// to its original bucket so it remains in its original workflow column.
// When no explicit default bucket is configured, the task stays in its
// current bucket — no update needed.
func (t *Task) moveTaskToDefaultBuckets(s *xorm.Session, a web.Auth, views []*ProjectView) error {
for _, view := range views {
var bucketID int64
var err error
if view.DefaultBucketID != 0 {
bucketID = view.DefaultBucketID
} else {
// No explicit default: preserve the task's current bucket.
currentTaskBucket := &TaskBucket{}
_, err = s.Where("task_id = ? AND project_view_id = ?", t.ID, view.ID).
Get(currentTaskBucket)
defaultBucketID, err := getDefaultBucketID(s, view)
if err != nil {
return err
}
bucketID = currentTaskBucket.BucketID
if bucketID == 0 {
// Task not in any bucket yet — fall back to first by position.
bucketID, err = getDefaultBucketID(s, view)
if err != nil {
return err
}
tb := &TaskBucket{
BucketID: defaultBucketID,
TaskID: t.ID,
ProjectViewID: view.ID,
ProjectID: t.ProjectID,
}
if err = updateTaskBucket(s, a, tb); err != nil {
return err
}
}
tb := &TaskBucket{
BucketID: bucketID,
TaskID: t.ID,
ProjectViewID: view.ID,
ProjectID: t.ProjectID,
}
err = updateTaskBucket(s, a, tb)
if err != nil {
return err
}
// When no default bucket is configured, the task stays in its current
// bucket — no bucket update needed.
tp := TaskPosition{
TaskID: t.ID,
ProjectViewID: view.ID,
Position: calculateDefaultPosition(t.Index, t.Position),
}
err = updateTaskPosition(s, a, &tp)
if err != nil {
if err := updateTaskPosition(s, a, &tp); err != nil {
return err
}
}