This is an automated email from the ASF dual-hosted git repository.

abeizn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git


The following commit(s) were added to refs/heads/main by this push:
     new 1974f49e0 fix: fix 500 error for project (#5347)
1974f49e0 is described below

commit 1974f49e0515a4ed68c3ae05210ea315fe72d84e
Author: mappjzc <[email protected]>
AuthorDate: Tue Jun 6 11:57:42 2023 +0800

    fix: fix 500 error for project (#5347)
    
    * fix: fix 500 error for project
    
    Fix 500 error for Project
    With the type ClosedBy string but not interface
    
    Nddtfjiang <[email protected]>
    
    * fix: fix project and product
    
    Fix project and product lost scope config id.
    
    Nddtfjiang <[email protected]>
---
 .../helpers/pluginhelper/api/scope_db_helper.go    |  8 ++++--
 backend/plugins/zentao/api/blueprint_V200_test.go  | 33 ++++++++--------------
 backend/plugins/zentao/api/blueprint_v200.go       | 25 ++++++++--------
 backend/plugins/zentao/api/remote.go               |  9 ++++++
 .../migrationscripts/20230601_add_scope_config.go  | 20 ++++++++++++-
 backend/plugins/zentao/models/product.go           |  1 +
 backend/plugins/zentao/models/project.go           | 33 ++++++++++++++++++++--
 7 files changed, 89 insertions(+), 40 deletions(-)

diff --git a/backend/helpers/pluginhelper/api/scope_db_helper.go 
b/backend/helpers/pluginhelper/api/scope_db_helper.go
index 2a6074413..e9fc3b46c 100644
--- a/backend/helpers/pluginhelper/api/scope_db_helper.go
+++ b/backend/helpers/pluginhelper/api/scope_db_helper.go
@@ -97,9 +97,11 @@ func (s *ScopeDatabaseHelperImpl[Conn, Scope, Tr]) 
GetScopeAndConfig(connectionI
        scopeConfig := new(Tr)
        scIdField := reflectField(scope, "ScopeConfigId")
        if scIdField.IsValid() {
-               err = s.db.First(scopeConfig, dal.Where("id = ?", 
scIdField.Uint()))
-               if err != nil {
-                       return nil, nil, err
+               if scIdField.Uint() != 0 {
+                       err = s.db.First(scopeConfig, dal.Where("id = ?", 
scIdField.Uint()))
+                       if err != nil {
+                               return nil, nil, err
+                       }
                }
        }
        entitiesField := reflectField(scopeConfig, "Entities")
diff --git a/backend/plugins/zentao/api/blueprint_V200_test.go 
b/backend/plugins/zentao/api/blueprint_V200_test.go
index bb48c595c..42432f76b 100644
--- a/backend/plugins/zentao/api/blueprint_V200_test.go
+++ b/backend/plugins/zentao/api/blueprint_V200_test.go
@@ -127,28 +127,18 @@ func TestMakeDataSourcePipelinePlanV200(t *testing.T) {
 // mockBasicRes FIXME ...
 func mockBasicRes() {
        testZentaoProduct := &models.ZentaoProduct{
-               ConnectionId: 1,
-               Id:           1,
-               Name:         "test/testRepo",
-               Type:         `product/normal`,
-               //ScopeConfigId: 1,
+               ConnectionId:  1,
+               Id:            1,
+               Name:          "test/testRepo",
+               Type:          `product/normal`,
+               ScopeConfigId: 0,
        }
        testZentaoProject := &models.ZentaoProject{
-               ConnectionId: 1,
-               Id:           1,
-               Name:         "test/testRepo",
-               Type:         `project`,
-               //ScopeConfigId: 1,
-       }
-
-       testScopeConfig := &models.ZentaoScopeConfig{
-               ScopeConfig: common.ScopeConfig{
-                       Entities: []string{"TICKET"},
-                       Model: common.Model{
-                               ID: 1,
-                       },
-               },
-               Name: "Zentao scope config",
+               ConnectionId:  1,
+               Id:            1,
+               Name:          "test/testRepo",
+               Type:          `project`,
+               ScopeConfigId: 0,
        }
        mockRes := unithelper.DummyBasicRes(func(mockDal *mockdal.Dal) {
                mockDal.On("First", 
mock.AnythingOfType("*models.ZentaoProject"), mock.Anything).Run(func(args 
mock.Arguments) {
@@ -162,8 +152,7 @@ func mockBasicRes() {
                }).Return(nil)
 
                mockDal.On("First", 
mock.AnythingOfType("*models.ZentaoScopeConfig"), mock.Anything).Run(func(args 
mock.Arguments) {
-                       dst := args.Get(0).(*models.ZentaoScopeConfig)
-                       *dst = *testScopeConfig
+                       panic("The empty scope should not call First() for 
ZentaoScopeConfig")
                }).Return(nil)
        })
        Init(mockRes)
diff --git a/backend/plugins/zentao/api/blueprint_v200.go 
b/backend/plugins/zentao/api/blueprint_v200.go
index f64738992..3aa7b449d 100644
--- a/backend/plugins/zentao/api/blueprint_v200.go
+++ b/backend/plugins/zentao/api/blueprint_v200.go
@@ -73,39 +73,40 @@ func makePipelinePlanV200(
                scopeId := strings.Split(bpScope.Id, `/`)[1]
 
                var entities []string
+
                if scopeType == `project` {
-                       scope, scopeConfig, err := 
projectScopeHelper.DbHelper().GetScopeAndConfig(connection.ID, scopeId)
+                       project, scopeConfig, err := 
projectScopeHelper.DbHelper().GetScopeAndConfig(connection.ID, scopeId)
                        if err != nil {
                                return nil, nil, err
                        }
-                       op.ProjectId = scope.Id
+                       op.ProjectId = project.Id
                        entities = scopeConfig.Entities
 
-                       if utils.StringsContains(scopeConfig.Entities, 
plugin.DOMAIN_TYPE_TICKET) {
+                       if utils.StringsContains(entities, 
plugin.DOMAIN_TYPE_TICKET) {
                                scopeTicket := &ticket.Board{
                                        DomainEntity: domainlayer.DomainEntity{
-                                               Id: 
didgen.NewDomainIdGenerator(&models.ZentaoProject{}).Generate(connection.ID, 
scope.Id),
+                                               Id: 
didgen.NewDomainIdGenerator(&models.ZentaoProject{}).Generate(connection.ID, 
project.Id),
                                        },
-                                       Name: scope.Name,
-                                       Type: scope.Type,
+                                       Name: project.Name,
+                                       Type: project.Type,
                                }
                                domainScopes = append(domainScopes, scopeTicket)
                        }
                } else {
-                       scope, scopeConfig, err := 
productScopeHelper.DbHelper().GetScopeAndConfig(connection.ID, scopeId)
+                       product, scopeConfig, err := 
productScopeHelper.DbHelper().GetScopeAndConfig(connection.ID, scopeId)
                        if err != nil {
                                return nil, nil, err
                        }
-                       op.ProductId = scope.Id
+                       op.ProductId = product.Id
                        entities = scopeConfig.Entities
 
-                       if utils.StringsContains(scopeConfig.Entities, 
plugin.DOMAIN_TYPE_TICKET) {
+                       if utils.StringsContains(entities, 
plugin.DOMAIN_TYPE_TICKET) {
                                scopeTicket := &ticket.Board{
                                        DomainEntity: domainlayer.DomainEntity{
-                                               Id: 
didgen.NewDomainIdGenerator(&models.ZentaoProduct{}).Generate(connection.ID, 
scope.Id),
+                                               Id: 
didgen.NewDomainIdGenerator(&models.ZentaoProduct{}).Generate(connection.ID, 
product.Id),
                                        },
-                                       Name: scope.Name,
-                                       Type: scope.Type,
+                                       Name: product.Name,
+                                       Type: product.Type,
                                }
                                domainScopes = append(domainScopes, scopeTicket)
                        }
diff --git a/backend/plugins/zentao/api/remote.go 
b/backend/plugins/zentao/api/remote.go
index 25fc6d35b..795be8a1b 100644
--- a/backend/plugins/zentao/api/remote.go
+++ b/backend/plugins/zentao/api/remote.go
@@ -43,6 +43,12 @@ type ProjectResponse struct {
        Values []models.ZentaoProject `json:"projects"`
 }
 
+func (pr *ProjectResponse) ConvertFix() {
+       for i := range pr.Values {
+               pr.Values[i].ConvertFix()
+       }
+}
+
 func getGroup(basicRes context2.BasicRes, gid string, queryData 
*api.RemoteQueryData, connection models.ZentaoConnection) 
([]api.BaseRemoteGroupResponse, errors.Error) {
        return []api.BaseRemoteGroupResponse{
                {
@@ -124,6 +130,9 @@ func RemoteScopes(input *plugin.ApiResourceInput) 
(*plugin.ApiResourceOutput, er
                                if err != nil {
                                        return nil, err
                                }
+
+                               resBody.ConvertFix()
+
                                return resBody.Values, nil
                        })
        }
diff --git 
a/backend/plugins/zentao/models/migrationscripts/20230601_add_scope_config.go 
b/backend/plugins/zentao/models/migrationscripts/20230601_add_scope_config.go
index 3ed1bd37c..e00be67bc 100644
--- 
a/backend/plugins/zentao/models/migrationscripts/20230601_add_scope_config.go
+++ 
b/backend/plugins/zentao/models/migrationscripts/20230601_add_scope_config.go
@@ -56,6 +56,22 @@ func (task20230601) TableName() string {
        return "_tool_zentao_tasks"
 }
 
+type project20230602 struct {
+       ScopeConfigId uint64 `json:"scopeConfigId,omitempty" 
mapstructure:"scopeConfigId"`
+}
+
+func (project20230602) TableName() string {
+       return "_tool_zentao_projects"
+}
+
+type product20230602 struct {
+       ScopeConfigId uint64 `json:"scopeConfigId,omitempty" 
mapstructure:"scopeConfigId"`
+}
+
+func (product20230602) TableName() string {
+       return "_tool_zentao_products"
+}
+
 func (*addScopeConfigTables) Up(basicRes context.BasicRes) errors.Error {
 
        return migrationhelper.AutoMigrateTables(
@@ -64,11 +80,13 @@ func (*addScopeConfigTables) Up(basicRes context.BasicRes) 
errors.Error {
                &bug20230601{},
                &story20230601{},
                &task20230601{},
+               &project20230602{},
+               &product20230602{},
        )
 }
 
 func (*addScopeConfigTables) Version() uint64 {
-       return 20230601000001
+       return 20230602000001
 }
 
 func (*addScopeConfigTables) Name() string {
diff --git a/backend/plugins/zentao/models/product.go 
b/backend/plugins/zentao/models/product.go
index c27f02d1c..bfec5fc6c 100644
--- a/backend/plugins/zentao/models/product.go
+++ b/backend/plugins/zentao/models/product.go
@@ -146,6 +146,7 @@ type ZentaoProduct struct {
        Docs             int                 `json:"docs" mapstructure:"docs"`
        Progress         float64             `json:"progress" 
mapstructure:"progress"`
        CaseReview       bool                `json:"caseReview" 
mapstructure:"caseReview"`
+       ScopeConfigId    uint64              `json:"scopeConfigId,omitempty" 
mapstructure:"scopeConfigId"`
 }
 
 func (ZentaoProduct) TableName() string {
diff --git a/backend/plugins/zentao/models/project.go 
b/backend/plugins/zentao/models/project.go
index f5fbceb5a..551c1404f 100644
--- a/backend/plugins/zentao/models/project.go
+++ b/backend/plugins/zentao/models/project.go
@@ -64,9 +64,11 @@ type ZentaoProject struct {
        OpenedVersion string              `json:"openedVersion" 
mapstructure:"openedVersion"`
        //LastEditedBy   string              `json:"lastEditedBy" 
mapstructure:"lastEditedBy"`
        LastEditedDate *helper.Iso8601Time `json:"lastEditedDate" 
mapstructure:"lastEditedDate"`
-       ClosedBy       string              `json:"closedBy" 
mapstructure:"closedBy"`
+       ClosedBy       string
+       ClosedByRes    interface{}         `json:"closedBy" 
mapstructure:"closedBy" gorm:"-"`
        ClosedDate     *helper.Iso8601Time `json:"closedDate" 
mapstructure:"closedDate"`
-       CanceledBy     string              `json:"canceledBy" 
mapstructure:"canceledBy"`
+       CanceledBy     string
+       CanceledByRes  interface{}         `json:"canceledBy" 
mapstructure:"canceledBy" gorm:"-"`
        CanceledDate   *helper.Iso8601Time `json:"canceledDate" 
mapstructure:"canceledDate"`
        SuspendedDate  *helper.Iso8601Time `json:"suspendedDate" 
mapstructure:"suspendedDate"`
        PO             string              `json:"po" mapstructure:"po"`
@@ -91,6 +93,7 @@ type ZentaoProject struct {
        TotalLeft     float64 `json:"totalLeft" mapstructure:"totalLeft"`
        Progress      float64 `json:"progress" mapstructure:"progress"`
        TotalReal     int     `json:"totalReal" mapstructure:"totalReal"`
+       ScopeConfigId uint64  `json:"scopeConfigId,omitempty" 
mapstructure:"scopeConfigId"`
 }
 type PM struct {
        PmId       int64  `json:"id" mapstructure:"id"`
@@ -112,6 +115,32 @@ type Hours struct {
        HoursTotalReal     float64 `json:"totalReal" mapstructure:"totalReal"`
 }
 
+func (p *ZentaoProject) ConvertFix() {
+       switch cb := p.ClosedByRes.(type) {
+       case string:
+               p.ClosedBy = cb
+       default:
+               if cb == nil {
+                       p.ClosedBy = ""
+               } else {
+                       p.ClosedBy = fmt.Sprintf("%v", cb)
+               }
+       }
+       p.ClosedByRes = p.ClosedBy
+
+       switch cb := p.CanceledByRes.(type) {
+       case string:
+               p.CanceledBy = cb
+       default:
+               if cb == nil {
+                       p.CanceledBy = ""
+               } else {
+                       p.CanceledBy = fmt.Sprintf("%v", cb)
+               }
+       }
+       p.CanceledByRes = p.CanceledBy
+}
+
 func (ZentaoProject) TableName() string {
        return "_tool_zentao_projects"
 }

Reply via email to