diff --git a/db/features.go b/db/features.go index 96c0327d9..7a170349c 100644 --- a/db/features.go +++ b/db/features.go @@ -205,3 +205,9 @@ func (db database) GetPhaseByUuid(phaseUuid string) (FeaturePhase, error) { } return phase, nil } + +func (db database) GetBountiesByPhaseUuid(phaseUuid string) []Bounty { + bounties := []Bounty{} + db.db.Model(&Bounty{}).Where("phase_uuid = ?", phaseUuid).Find(&bounties) + return bounties +} diff --git a/db/interface.go b/db/interface.go index ffc141e7a..bbfeff93f 100644 --- a/db/interface.go +++ b/db/interface.go @@ -159,4 +159,5 @@ type Database interface { DeleteFeatureByUuid(uuid string) error GetBountyByFeatureAndPhaseUuid(featureUuid string, phaseUuid string) (Bounty, error) GetPhaseByUuid(phaseUuid string) (FeaturePhase, error) + GetBountiesByPhaseUuid(phaseUuid string) []Bounty } diff --git a/db/structs.go b/db/structs.go index 1c038104e..c6c2fe414 100644 --- a/db/structs.go +++ b/db/structs.go @@ -569,19 +569,22 @@ type WorkspaceRepositories struct { } type WorkspaceFeatures struct { - ID uint `json:"id"` - Uuid string `gorm:"not null" json:"uuid"` - WorkspaceUuid string `gorm:"not null" json:"workspace_uuid"` - Name string `gorm:"not null" json:"name"` - Brief string `json:"brief"` - Requirements string `json:"requirements"` - Architecture string `json:"architecture"` - Url string `json:"url"` - Priority int `json:"priority"` - Created *time.Time `json:"created"` - Updated *time.Time `json:"updated"` - CreatedBy string `json:"created_by"` - UpdatedBy string `json:"updated_by"` + ID uint `json:"id"` + Uuid string `gorm:"not null" json:"uuid"` + WorkspaceUuid string `gorm:"not null" json:"workspace_uuid"` + Name string `gorm:"not null" json:"name"` + Brief string `json:"brief"` + Requirements string `json:"requirements"` + Architecture string `json:"architecture"` + Url string `json:"url"` + Priority int `json:"priority"` + Created *time.Time `json:"created"` + Updated *time.Time `json:"updated"` + CreatedBy string `json:"created_by"` + UpdatedBy string `json:"updated_by"` + BountiesCountCompleted int `json:"bounties_count_completed"` + BountiesCountAssigned int `json:"bounties_count_assigned"` + BountiesCountOpen int `json:"bounties_count_open"` } type FeaturePhase struct { diff --git a/handlers/workspaces.go b/handlers/workspaces.go index 06d1e5bc6..8e76af271 100644 --- a/handlers/workspaces.go +++ b/handlers/workspaces.go @@ -914,6 +914,30 @@ func (oh *workspaceHandler) GetFeaturesByWorkspaceUuid(w http.ResponseWriter, r uuid := chi.URLParam(r, "workspace_uuid") workspaceFeatures := oh.db.GetFeaturesByWorkspaceUuid(uuid, r) + for i, feature := range workspaceFeatures { + + phases := oh.db.GetPhasesByFeatureUuid(feature.Uuid) + + var totalCompleted, totalAssigned, totalOpen int + + for _, phase := range phases { + bounties := oh.db.GetBountiesByPhaseUuid(phase.Uuid) + for _, bounty := range bounties { + if bounty.Completed { + totalCompleted++ + } else if bounty.Assignee != "" { + totalAssigned++ + } else { + totalOpen++ + } + } + } + + workspaceFeatures[i].BountiesCountCompleted = totalCompleted + workspaceFeatures[i].BountiesCountAssigned = totalAssigned + workspaceFeatures[i].BountiesCountOpen = totalOpen + } + w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(workspaceFeatures) } diff --git a/mocks/Database.go b/mocks/Database.go index b801eef8d..cf326bb2a 100644 --- a/mocks/Database.go +++ b/mocks/Database.go @@ -7500,3 +7500,43 @@ func NewDatabase(t interface { return mock } + +func (_m *Database) GetBountiesByPhaseUuid(phaseUuid string) []db.Bounty { + ret := _m.Called(phaseUuid) + + var r0 []db.Bounty + if rf, ok := ret.Get(0).(func(string) []db.Bounty); ok { + r0 = rf(phaseUuid) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]db.Bounty) + } + } + + return r0 +} + +type Database_GetBountiesByPhaseUuid_Call struct { + *mock.Call +} + +func (_e *Database_Expecter) GetBountiesByPhaseUuid(phaseUuid interface{}) *Database_GetBountiesByPhaseUuid_Call { + return &Database_GetBountiesByPhaseUuid_Call{Call: _e.mock.On("GetBountiesByPhaseUuid", phaseUuid)} +} + +func (_c *Database_GetBountiesByPhaseUuid_Call) Run(run func(phaseUuid string)) *Database_GetBountiesByPhaseUuid_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *Database_GetBountiesByPhaseUuid_Call) Return(_a0 []db.Bounty) *Database_GetBountiesByPhaseUuid_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Database_GetBountiesByPhaseUuid_Call) RunAndReturn(run func(string) []db.Bounty) *Database_GetBountiesByPhaseUuid_Call { + _c.Call.Return(run) + return _c +}