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

warren pushed a commit to branch feat-plugin-zentao
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git

commit 9919d22f29f03cbd6dbc4420039eb07899e73335
Author: Yingchu Chen <[email protected]>
AuthorDate: Mon Sep 19 11:05:59 2022 +0800

    feat(zentao): fix execution time
---
 plugins/helper/iso8601time.go               | 31 ++++++++++
 plugins/zentao/impl/impl.go                 |  1 +
 plugins/zentao/models/archived/execution.go | 78 ++++++++++++-------------
 plugins/zentao/models/archived/project.go   |  4 +-
 plugins/zentao/models/execution.go          | 78 ++++++++++++-------------
 plugins/zentao/models/project.go            |  4 +-
 plugins/zentao/tasks/execution_convertor.go | 91 +++++++++++++++++++++++++++++
 7 files changed, 205 insertions(+), 82 deletions(-)

diff --git a/plugins/helper/iso8601time.go b/plugins/helper/iso8601time.go
index 8d409262..3029adb1 100644
--- a/plugins/helper/iso8601time.go
+++ b/plugins/helper/iso8601time.go
@@ -18,6 +18,7 @@ limitations under the License.
 package helper
 
 import (
+       "database/sql/driver"
        "fmt"
        "regexp"
        "strings"
@@ -63,6 +64,10 @@ func init() {
                        Matcher: regexp.MustCompile(`[+-][\d]{2}:[\d]{2}$`),
                        Format:  "2006-01-02T15:04:05-07:00",
                },
+               {
+                       Matcher: regexp.MustCompile(`[+-][\d]{2}-[\d]{2}$`),
+                       Format:  "2006-01-02",
+               },
        }
 }
 
@@ -131,3 +136,29 @@ func Iso8601TimeToTime(iso8601Time *Iso8601Time) 
*time.Time {
        t := iso8601Time.ToTime()
        return &t
 }
+
+// Value FIXME ...
+func (jt *Iso8601Time) Value() (driver.Value, error) {
+       if jt == nil {
+               return nil, nil
+       }
+       var zeroTime time.Time
+       t := jt.time
+       if t.UnixNano() == zeroTime.UnixNano() {
+               return nil, nil
+       }
+       return t, nil
+}
+
+// Scan FIXME ...
+func (jt *Iso8601Time) Scan(v interface{}) error {
+       value, ok := v.(time.Time)
+       if ok {
+               *jt = Iso8601Time{
+                       time:   value,
+                       format: time.RFC3339,
+               }
+               return nil
+       }
+       return fmt.Errorf("can not convert %v to timestamp", v)
+}
diff --git a/plugins/zentao/impl/impl.go b/plugins/zentao/impl/impl.go
index 920bced0..b4004753 100644
--- a/plugins/zentao/impl/impl.go
+++ b/plugins/zentao/impl/impl.go
@@ -56,6 +56,7 @@ func (plugin Zentao) SubTaskMetas() []core.SubTaskMeta {
                tasks.ExtractProjectsMeta,
                tasks.CollectExecutionMeta,
                tasks.ExtractExecutionsMeta,
+               tasks.ConvertExecutionsMeta,
        }
 }
 
diff --git a/plugins/zentao/models/archived/execution.go 
b/plugins/zentao/models/archived/execution.go
index 787527c1..7fe6cd16 100644
--- a/plugins/zentao/models/archived/execution.go
+++ b/plugins/zentao/models/archived/execution.go
@@ -2,51 +2,51 @@ package archived
 
 import (
        "github.com/apache/incubator-devlake/models/migrationscripts/archived"
-       "time"
+       "github.com/apache/incubator-devlake/plugins/helper"
 )
 
 type ZentaoExecution struct {
-       ConnectionId   uint64 `gorm:"primaryKey"`
-       Id             uint64 `json:"id"`
-       Project        uint64 `json:"project"`
-       Model          string `json:"model"`
-       Type           string `json:"type"`
-       Lifetime       string `json:"lifetime"`
-       Budget         string `json:"budget"`
-       BudgetUnit     string `json:"budgetUnit"`
-       Attribute      string `json:"attribute"`
-       Percent        int    `json:"percent"`
-       Milestone      string `json:"milestone"`
-       Output         string `json:"output"`
-       Auth           string `json:"auth"`
-       Parent         int    `json:"parent"`
-       Path           string `json:"path"`
-       Grade          int    `json:"grade"`
-       Name           string `json:"name"`
-       Code           string `json:"code"`
-       Begin          string `json:"begin"`
-       End            string `json:"end"`
-       RealBegan      string `json:"realBegan"`
-       RealEnd        string `json:"realEnd"`
-       Days           int    `json:"days"`
-       Status         string `json:"status"`
-       SubStatus      string `json:"subStatus"`
-       Pri            string `json:"pri"`
-       Desc           string `json:"desc"`
-       Version        int    `json:"version"`
-       ParentVersion  int    `json:"parentVersion"`
-       PlanDuration   int    `json:"planDuration"`
-       RealDuration   int    `json:"realDuration"`
+       ConnectionId   uint64              `gorm:"primaryKey"`
+       Id             uint64              `json:"id" gorm:"primaryKey"`
+       Project        uint64              `json:"project"`
+       Model          string              `json:"model"`
+       Type           string              `json:"type"`
+       Lifetime       string              `json:"lifetime"`
+       Budget         string              `json:"budget"`
+       BudgetUnit     string              `json:"budgetUnit"`
+       Attribute      string              `json:"attribute"`
+       Percent        int                 `json:"percent"`
+       Milestone      string              `json:"milestone"`
+       Output         string              `json:"output"`
+       Auth           string              `json:"auth"`
+       Parent         int                 `json:"parent"`
+       Path           string              `json:"path"`
+       Grade          int                 `json:"grade"`
+       Name           string              `json:"name"`
+       Code           string              `json:"code"`
+       Begin          *helper.Iso8601Time `json:"begin"`
+       End            *helper.Iso8601Time `json:"end"`
+       RealBegan      *helper.Iso8601Time `json:"realBegan"`
+       RealEnd        *helper.Iso8601Time `json:"realEnd"`
+       Days           int                 `json:"days"`
+       Status         string              `json:"status"`
+       SubStatus      string              `json:"subStatus"`
+       Pri            string              `json:"pri"`
+       Desc           string              `json:"desc"`
+       Version        int                 `json:"version"`
+       ParentVersion  int                 `json:"parentVersion"`
+       PlanDuration   int                 `json:"planDuration"`
+       RealDuration   int                 `json:"realDuration"`
        OpenedBy       `json:"openedBy"`
-       OpenedDate     time.Time `json:"openedDate"`
-       OpenedVersion  string    `json:"openedVersion"`
+       OpenedDate     *helper.Iso8601Time `json:"openedDate"`
+       OpenedVersion  string              `json:"openedVersion"`
        LastEditedBy   `json:"lastEditedBy"`
-       LastEditedDate time.Time `json:"lastEditedDate"`
+       LastEditedDate *helper.Iso8601Time `json:"lastEditedDate"`
        ClosedBy       `json:"closedBy"`
-       ClosedDate     time.Time `json:"closedDate"`
+       ClosedDate     *helper.Iso8601Time `json:"closedDate"`
        CanceledBy     `json:"canceledBy"`
-       CanceledDate   time.Time `json:"canceledDate"`
-       SuspendedDate  string    `json:"suspendedDate"`
+       CanceledDate   *helper.Iso8601Time `json:"canceledDate"`
+       SuspendedDate  *helper.Iso8601Time `json:"suspendedDate"`
        PO             `json:"PO"`
        PM             `json:"PM"`
        QD             `json:"QD"`
@@ -147,5 +147,5 @@ type TeamMember struct {
 }
 
 func (ZentaoExecution) TableName() string {
-       return "_tool_zentao_execution"
+       return "_tool_zentao_executions"
 }
diff --git a/plugins/zentao/models/archived/project.go 
b/plugins/zentao/models/archived/project.go
index 63c498dd..94fcdfcb 100644
--- a/plugins/zentao/models/archived/project.go
+++ b/plugins/zentao/models/archived/project.go
@@ -25,7 +25,7 @@ import (
 type ZentaoProject struct {
        archived.NoPKModel
        ConnectionId  uint64 `gorm:"primaryKey;type:BIGINT  NOT NULL"`
-       ID            int    `json:"id"`
+       ID            int    `json:"id" gorm:"primaryKey;type:BIGINT  NOT NULL"`
        Project       int    `json:"project"`
        Model         string `json:"model"`
        Type          string `json:"type"`
@@ -109,5 +109,5 @@ type Hours struct {
 }
 
 func (ZentaoProject) TableName() string {
-       return "_tool_zentao_project"
+       return "_tool_zentao_projects"
 }
diff --git a/plugins/zentao/models/execution.go 
b/plugins/zentao/models/execution.go
index e51102cf..054f21d7 100644
--- a/plugins/zentao/models/execution.go
+++ b/plugins/zentao/models/execution.go
@@ -2,51 +2,51 @@ package models
 
 import (
        "github.com/apache/incubator-devlake/models/common"
-       "time"
+       "github.com/apache/incubator-devlake/plugins/helper"
 )
 
 type ZentaoExecution struct {
-       ConnectionId   uint64 `gorm:"primaryKey"`
-       Id             uint64 `json:"id"`
-       Project        uint64 `json:"project"`
-       Model          string `json:"model"`
-       Type           string `json:"type"`
-       Lifetime       string `json:"lifetime"`
-       Budget         string `json:"budget"`
-       BudgetUnit     string `json:"budgetUnit"`
-       Attribute      string `json:"attribute"`
-       Percent        int    `json:"percent"`
-       Milestone      string `json:"milestone"`
-       Output         string `json:"output"`
-       Auth           string `json:"auth"`
-       Parent         int    `json:"parent"`
-       Path           string `json:"path"`
-       Grade          int    `json:"grade"`
-       Name           string `json:"name"`
-       Code           string `json:"code"`
-       Begin          string `json:"begin"`
-       End            string `json:"end"`
-       RealBegan      string `json:"realBegan"`
-       RealEnd        string `json:"realEnd"`
-       Days           int    `json:"days"`
-       Status         string `json:"status"`
-       SubStatus      string `json:"subStatus"`
-       Pri            string `json:"pri"`
-       Desc           string `json:"desc"`
-       Version        int    `json:"version"`
-       ParentVersion  int    `json:"parentVersion"`
-       PlanDuration   int    `json:"planDuration"`
-       RealDuration   int    `json:"realDuration"`
+       ConnectionId   uint64              `gorm:"primaryKey"`
+       Id             uint64              `json:"id" gorm:"primaryKey"`
+       Project        uint64              `json:"project"`
+       Model          string              `json:"model"`
+       Type           string              `json:"type"`
+       Lifetime       string              `json:"lifetime"`
+       Budget         string              `json:"budget"`
+       BudgetUnit     string              `json:"budgetUnit"`
+       Attribute      string              `json:"attribute"`
+       Percent        int                 `json:"percent"`
+       Milestone      string              `json:"milestone"`
+       Output         string              `json:"output"`
+       Auth           string              `json:"auth"`
+       Parent         int                 `json:"parent"`
+       Path           string              `json:"path"`
+       Grade          int                 `json:"grade"`
+       Name           string              `json:"name"`
+       Code           string              `json:"code"`
+       Begin          *helper.Iso8601Time `json:"begin"`
+       End            *helper.Iso8601Time `json:"end"`
+       RealBegan      *helper.Iso8601Time `json:"realBegan"`
+       RealEnd        *helper.Iso8601Time `json:"realEnd"`
+       Days           int                 `json:"days"`
+       Status         string              `json:"status"`
+       SubStatus      string              `json:"subStatus"`
+       Pri            string              `json:"pri"`
+       Desc           string              `json:"desc"`
+       Version        int                 `json:"version"`
+       ParentVersion  int                 `json:"parentVersion"`
+       PlanDuration   int                 `json:"planDuration"`
+       RealDuration   int                 `json:"realDuration"`
        OpenedBy       `json:"openedBy"`
-       OpenedDate     time.Time `json:"openedDate"`
-       OpenedVersion  string    `json:"openedVersion"`
+       OpenedDate     *helper.Iso8601Time `json:"openedDate"`
+       OpenedVersion  string              `json:"openedVersion"`
        LastEditedBy   `json:"lastEditedBy"`
-       LastEditedDate time.Time `json:"lastEditedDate"`
+       LastEditedDate *helper.Iso8601Time `json:"lastEditedDate"`
        ClosedBy       `json:"closedBy"`
-       ClosedDate     time.Time `json:"closedDate"`
+       ClosedDate     *helper.Iso8601Time `json:"closedDate"`
        CanceledBy     `json:"canceledBy"`
-       CanceledDate   time.Time `json:"canceledDate"`
-       SuspendedDate  string    `json:"suspendedDate"`
+       CanceledDate   *helper.Iso8601Time `json:"canceledDate"`
+       SuspendedDate  *helper.Iso8601Time `json:"suspendedDate"`
        PO             `json:"PO"`
        PM             `json:"PM"`
        QD             `json:"QD"`
@@ -72,7 +72,7 @@ type ZentaoExecution struct {
 }
 
 func (ZentaoExecution) TableName() string {
-       return "_tool_zentao_execution"
+       return "_tool_zentao_executions"
 }
 
 type OpenedBy struct {
diff --git a/plugins/zentao/models/project.go b/plugins/zentao/models/project.go
index 5a51d738..db9450bf 100644
--- a/plugins/zentao/models/project.go
+++ b/plugins/zentao/models/project.go
@@ -25,7 +25,7 @@ import (
 type ZentaoProject struct {
        common.NoPKModel
        ConnectionId  uint64 `gorm:"primaryKey;type:BIGINT  NOT NULL"`
-       ID            int    `json:"id"`
+       ID            int    `json:"id" gorm:"primaryKey;type:BIGINT  NOT NULL"`
        Project       int    `json:"project"`
        Model         string `json:"model"`
        Type          string `json:"type"`
@@ -109,5 +109,5 @@ type Hours struct {
 }
 
 func (ZentaoProject) TableName() string {
-       return "_tool_zentao_project"
+       return "_tool_zentao_projects"
 }
diff --git a/plugins/zentao/tasks/execution_convertor.go 
b/plugins/zentao/tasks/execution_convertor.go
new file mode 100644
index 00000000..727ba92d
--- /dev/null
+++ b/plugins/zentao/tasks/execution_convertor.go
@@ -0,0 +1,91 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package tasks
+
+import (
+       "github.com/apache/incubator-devlake/models/domainlayer"
+       "github.com/apache/incubator-devlake/models/domainlayer/didgen"
+       "github.com/apache/incubator-devlake/models/domainlayer/ticket"
+       "github.com/apache/incubator-devlake/plugins/core"
+       "github.com/apache/incubator-devlake/plugins/core/dal"
+       "github.com/apache/incubator-devlake/plugins/helper"
+       "github.com/apache/incubator-devlake/plugins/zentao/models"
+       "reflect"
+)
+
+var _ core.SubTaskEntryPoint = ConvertExecutions
+
+var ConvertExecutionsMeta = core.SubTaskMeta{
+       Name:             "convertExecutions",
+       EntryPoint:       ConvertExecutions,
+       EnabledByDefault: true,
+       Description:      "convert Zentao executions",
+       DomainTypes:      []string{core.DOMAIN_TYPE_TICKET},
+}
+
+func ConvertExecutions(taskCtx core.SubTaskContext) error {
+       data := taskCtx.GetData().(*ZentaoTaskData)
+       db := taskCtx.GetDal()
+       boardIdGen := didgen.NewDomainIdGenerator(&models.ZentaoExecution{})
+       cursor, err := db.Cursor(
+               dal.From(&models.ZentaoExecution{}),
+               dal.Where(`_tool_zentao_executions.id = ? and 
+                       _tool_zentao_executions.connection_id = ?`, 
data.Options.ExecutionId, data.Options.ConnectionId),
+       )
+       if err != nil {
+               return err
+       }
+       defer cursor.Close()
+       convertor, err := helper.NewDataConverter(helper.DataConverterArgs{
+               InputRowType: reflect.TypeOf(models.ZentaoExecution{}),
+               Input:        cursor,
+               RawDataSubTaskArgs: helper.RawDataSubTaskArgs{
+                       Ctx: taskCtx,
+                       Params: ZentaoApiParams{
+                               ProductId:   data.Options.ProductId,
+                               ExecutionId: data.Options.ExecutionId,
+                               ProjectId:   data.Options.ProjectId,
+                       },
+                       Table: RAW_EXECUTION_TABLE,
+               },
+               Convert: func(inputRow interface{}) ([]interface{}, error) {
+                       toolExecution := inputRow.(*models.ZentaoExecution)
+
+                       domainBoard := &ticket.Board{
+                               DomainEntity: domainlayer.DomainEntity{
+                                       Id: 
boardIdGen.Generate(toolExecution.ConnectionId, toolExecution.Id),
+                               },
+                               Name:        toolExecution.Name,
+                               Description: toolExecution.Desc,
+                               Url:         toolExecution.Path,
+                               CreatedDate: 
toolExecution.OpenedDate.ToNullableTime(),
+                               Type:        toolExecution.Type,
+                       }
+
+                       results := make([]interface{}, 0)
+                       results = append(results, domainBoard)
+                       return results, nil
+               },
+       })
+
+       if err != nil {
+               return err
+       }
+
+       return convertor.Execute()
+}

Reply via email to