示例#1
0
// List runs the list action.
// Prev and Next links will be present only when there actually IS a next or previous page.
// Last will always be present. Total Item count needs to be computed from the "Last" link.
func (c *WorkitemController) List(ctx *app.ListWorkitemContext) error {
	var additionalQuery []string
	exp, err := query.Parse(ctx.Filter)
	if err != nil {
		return jsonapi.JSONErrorResponse(ctx, errors.NewBadParameterError("could not parse filter", err))
	}
	if ctx.FilterAssignee != nil {
		assignee := ctx.FilterAssignee
		exp = criteria.And(exp, criteria.Equals(criteria.Field("system.assignees"), criteria.Literal([]string{*assignee})))
		additionalQuery = append(additionalQuery, "filter[assignee]="+*assignee)
	}
	if ctx.FilterIteration != nil {
		iteration := ctx.FilterIteration
		exp = criteria.And(exp, criteria.Equals(criteria.Field(workitem.SystemIteration), criteria.Literal(string(*iteration))))
		additionalQuery = append(additionalQuery, "filter[iteration]="+*iteration)
	}
	if ctx.FilterWorkitemtype != nil {
		wit := ctx.FilterWorkitemtype
		exp = criteria.And(exp, criteria.Equals(criteria.Field("Type"), criteria.Literal([]string{*wit})))
		additionalQuery = append(additionalQuery, "filter[workitemtype]="+*wit)
	}
	if ctx.FilterArea != nil {
		area := ctx.FilterArea
		exp = criteria.And(exp, criteria.Equals(criteria.Field(workitem.SystemArea), criteria.Literal(string(*area))))
		additionalQuery = append(additionalQuery, "filter[area]="+*area)
	}
	offset, limit := computePagingLimts(ctx.PageOffset, ctx.PageLimit)
	return application.Transactional(c.db, func(tx application.Application) error {
		result, tc, err := tx.WorkItems().List(ctx.Context, exp, &offset, &limit)
		count := int(tc)
		if err != nil {
			return jsonapi.JSONErrorResponse(ctx, errs.Wrap(err, "Error listing work items"))
		}
		response := app.WorkItem2List{
			Links: &app.PagingLinks{},
			Meta:  &app.WorkItemListResponseMeta{TotalCount: count},
			Data:  ConvertWorkItems(ctx.RequestData, result),
		}
		setPagingLinks(response.Links, buildAbsoluteURL(ctx.RequestData), len(result), offset, limit, count, additionalQuery...)
		return ctx.OK(&response)
	})
}
// Map a remote work item into an ALM work item and persist it into the database.
func convert(db *gorm.DB, tID int, item TrackerItemContent, provider string) (*app.WorkItem, error) {
	remoteID := item.ID
	content := string(item.Content)

	wir := workitem.NewWorkItemRepository(db)
	ti := TrackerItem{Item: content, RemoteItemID: remoteID, TrackerID: uint64(tID)}

	// Converting the remote item to a local work item
	remoteTrackerItemMethodRef, ok := RemoteWorkItemImplRegistry[provider]
	if !ok {
		return nil, BadParameterError{parameter: provider, value: provider}
	}
	remoteTrackerItem, err := remoteTrackerItemMethodRef(ti)
	if err != nil {
		return nil, InternalError{simpleError{message: " Error parsing the tracker data "}}
	}
	workItem, err := Map(remoteTrackerItem, WorkItemKeyMaps[provider])
	if err != nil {
		return nil, ConversionError{simpleError{message: " Error mapping to local work item "}}
	}

	// Get the remote item identifier ( which is currently the url ) to check if the work item exists in the database.
	workItemRemoteID := workItem.Fields[workitem.SystemRemoteItemID]

	sqlExpression := criteria.Equals(criteria.Field(workitem.SystemRemoteItemID), criteria.Literal(workItemRemoteID))

	var newWorkItem *app.WorkItem

	// Querying the database
	existingWorkItems, _, err := wir.List(context.Background(), sqlExpression, nil, nil)
	if err != nil {
		return nil, err
	}

	if len(existingWorkItems) != 0 {
		log.Info(nil, map[string]interface{}{
			"pkg":      "remoteworkitem",
			"workitem": workItem,
		}, "Workitem exists, will be updated")

		existingWorkItem := existingWorkItems[0]
		for key, value := range workItem.Fields {
			existingWorkItem.Fields[key] = value
		}
		newWorkItem, err = wir.Save(context.Background(), *existingWorkItem)
		if err != nil {
			log.Error(nil, map[string]interface{}{
				"existingWorkitem": existingWorkItem,
				"err":              err,
			}, "unable to update the work item")
		}
	} else {
		log.Info(nil, map[string]interface{}{
			"pkg":           "remoteworkitem",
			"sqlExpression": sqlExpression,
			"err":           err,
		}, "Work item not found , will now create new work item")
		c := workItem.Fields[workitem.SystemCreator]
		var creator string
		if c != nil {
			creator = c.(string)
		}
		newWorkItem, err = wir.Create(context.Background(), workitem.SystemBug, workItem.Fields, creator)
		if err != nil {
			log.Error(nil, map[string]interface{}{
				"creator":            creator,
				"workItem.Fields":    workItem.Fields,
				"workitem.SystemBug": workitem.SystemBug,
				"err":                err,
			}, "unable to create the work item")
		}
	}
	return newWorkItem, errors.WithStack(err)
}