feat(ui+backend): task update ok

This commit is contained in:
2020-09-11 11:55:22 +02:00
parent 7fc1a7f3af
commit aacff1d694
16 changed files with 331 additions and 219 deletions

View File

@ -2,48 +2,10 @@ package graph
import (
"context"
"strconv"
"forge.cadoles.com/Cadoles/guesstimate/internal/model"
"github.com/pkg/errors"
)
func handleEstimations(ctx context.Context, task *model.Task) (*model.Estimations, error) {
estimations := &model.Estimations{}
if task.Estimations == nil {
return estimations, nil
}
rawOptimistic, exists := task.Estimations[model.EstimationOptimistic]
if exists && rawOptimistic != nil {
optimistic, err := strconv.ParseFloat(*rawOptimistic, 64)
if err != nil {
return nil, errors.WithStack(err)
}
estimations.Optimistic = optimistic
}
rawLikely, exists := task.Estimations[model.EstimationLikely]
if exists && rawLikely != nil {
likely, err := strconv.ParseFloat(*rawLikely, 64)
if err != nil {
return nil, errors.WithStack(err)
}
estimations.Likely = likely
}
rawPessimistic, exists := task.Estimations[model.EstimationPessimistic]
if exists && rawPessimistic != nil {
pessimistic, err := strconv.ParseFloat(*rawPessimistic, 64)
if err != nil {
return nil, errors.WithStack(err)
}
estimations.Pessimistic = pessimistic
}
return estimations, nil
return task.Estimations, nil
}

View File

@ -22,6 +22,7 @@ type Mutation {
updateUser(id: ID!, changes: UserChanges!): User!
createProject(changes: CreateProjectChanges!): Project!
updateProjectTitle(projectId: ID!, title: String!): Project!
addProjectTask(projectId: ID!, changes: ProjectTaskChanges): Task!
addProjectTask(projectId: ID!, changes: ProjectTaskChanges!): Task!
removeProjectTask(projectId: ID!, taskId: ID!): Boolean!
updateProjectTask(projectId: ID!, taskId: ID!, changes: ProjectTaskChanges!): Task!
}

View File

@ -22,7 +22,7 @@ func (r *mutationResolver) UpdateProjectTitle(ctx context.Context, projectID int
return handleUpdateProjectTitle(ctx, projectID, title)
}
func (r *mutationResolver) AddProjectTask(ctx context.Context, projectID int64, changes *model.ProjectTaskChanges) (*model.Task, error) {
func (r *mutationResolver) AddProjectTask(ctx context.Context, projectID int64, changes model.ProjectTaskChanges) (*model.Task, error) {
return handleAddProjectTask(ctx, projectID, changes)
}
@ -30,6 +30,10 @@ func (r *mutationResolver) RemoveProjectTask(ctx context.Context, projectID int6
return handleRemoveProjectTask(ctx, projectID, taskID)
}
func (r *mutationResolver) UpdateProjectTask(ctx context.Context, projectID int64, taskID int64, changes model.ProjectTaskChanges) (*model.Task, error) {
return handleUpdateProjectTask(ctx, projectID, taskID, changes)
}
// Mutation returns generated.MutationResolver implementation.
func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResolver{r} }

View File

@ -64,7 +64,7 @@ func handleUpdateProjectTitle(ctx context.Context, projectID int64, title string
return project, nil
}
func handleAddProjectTask(ctx context.Context, projectID int64, changes *model.ProjectTaskChanges) (*model.Task, error) {
func handleAddProjectTask(ctx context.Context, projectID int64, changes model.ProjectTaskChanges) (*model.Task, error) {
db, err := getDB(ctx)
if err != nil {
return nil, errors.WithStack(err)
@ -94,3 +94,19 @@ func handleRemoveProjectTask(ctx context.Context, projectID int64, taskID int64)
return true, nil
}
func handleUpdateProjectTask(ctx context.Context, projectID, taskID int64, changes model.ProjectTaskChanges) (*model.Task, error) {
db, err := getDB(ctx)
if err != nil {
return nil, errors.WithStack(err)
}
repo := model.NewProjectRepository(db)
task, err := repo.UpdateTask(ctx, projectID, taskID, changes)
if err != nil {
return nil, errors.WithStack(err)
}
return task, nil
}

View File

@ -90,20 +90,20 @@ type Access struct {
Level string `json:"level"`
}
const (
EstimationPessimistic = "pessimistic"
EstimationLikely = "likely"
EstimationOptimistic = "optimistic"
)
type Task struct {
Base
ProjectID int64 `json:"-"`
Project *Project `json:"-"`
Label *string `json:"label"`
CategoryID int64 `json:"-"`
Category *TaskCategory `json:"category"`
Estimations postgres.Hstore `json:"estimations"`
ProjectID int64 `json:"-"`
Project *Project `json:"-"`
Label *string `json:"label"`
CategoryID int64 `json:"-"`
Category *TaskCategory `json:"category"`
Estimations *Estimations `gorm:"EMBEDDED;EMBEDDED_PREFIX:estimation_" json:"estimations"`
}
type Estimations struct {
Optimistic float64 `json:"optimistic"`
Likely float64 `json:"likely"`
Pessimistic float64 `json:"pessimistic"`
}
type TaskCategory struct {

View File

@ -3,9 +3,6 @@ package model
import (
"context"
"fmt"
"strconv"
"github.com/jinzhu/gorm/dialects/postgres"
"forge.cadoles.com/Cadoles/guesstimate/internal/orm"
"github.com/jinzhu/gorm"
@ -137,54 +134,14 @@ func (r *ProjectRepository) Search(ctx context.Context, filter *ProjectsFilter)
return projects, nil
}
func (r *ProjectRepository) AddTask(ctx context.Context, projectID int64, changes *ProjectTaskChanges) (*Task, error) {
func (r *ProjectRepository) AddTask(ctx context.Context, projectID int64, changes ProjectTaskChanges) (*Task, error) {
project := &Project{}
project.ID = projectID
task := &Task{}
if changes == nil {
return nil, errors.Errorf("changes should not be nil")
}
err := r.db.Transaction(func(tx *gorm.DB) error {
if changes.Label != nil {
task.Label = changes.Label
}
if changes.CategoryID != nil {
taskCategory := &TaskCategory{}
taskCategory.ID = *changes.CategoryID
task.Category = taskCategory
}
if changes.Estimations != nil {
if task.Estimations == nil {
task.Estimations = postgres.Hstore{}
}
if changes.Estimations.Pessimistic != nil {
pessimistic := strconv.FormatFloat(*changes.Estimations.Pessimistic, 'f', 12, 64)
task.Estimations[EstimationPessimistic] = &pessimistic
}
if changes.Estimations.Likely != nil {
likely := strconv.FormatFloat(*changes.Estimations.Likely, 'f', 12, 64)
task.Estimations[EstimationLikely] = &likely
}
if changes.Estimations.Optimistic != nil {
optimistic := strconv.FormatFloat(*changes.Estimations.Optimistic, 'f', 12, 64)
task.Estimations[EstimationOptimistic] = &optimistic
}
if changes.CategoryID != nil {
taskCategory := &TaskCategory{}
if err := tx.Find(taskCategory, "id = ?", *changes.CategoryID).Error; err != nil {
return errors.Wrap(err, "could not find task category")
}
task.Category = taskCategory
}
if err := updateTaskWithChanges(tx, task, changes); err != nil {
return errors.WithStack(err)
}
if err := tx.Save(task).Error; err != nil {
@ -219,7 +176,7 @@ func (r *ProjectRepository) RemoveTask(ctx context.Context, projectID int64, tas
return errors.Wrap(err, "could not remove task relationship")
}
err = tx.Delete(task, "id = ?", taskID).Error
err = tx.Delete(task, "id = ? AND project_id = ?", taskID, projectID).Error
if err != nil {
return errors.Wrap(err, "could not delete task")
}
@ -233,15 +190,21 @@ func (r *ProjectRepository) RemoveTask(ctx context.Context, projectID int64, tas
return nil
}
func (r *ProjectRepository) UpdateTaskEstimation(ctx context.Context, projectID, taskID int64, estimation string, value float64) (*Task, error) {
func (r *ProjectRepository) UpdateTask(ctx context.Context, projectID, taskID int64, changes ProjectTaskChanges) (*Task, error) {
task := &Task{}
err := r.db.Transaction(func(tx *gorm.DB) error {
task := &Task{}
if err := tx.First(task, "id = ?", taskID).Error; err != nil {
err := tx.Model(task).
Preload("Category").
First(task, "id = ? AND project_id = ?", taskID, projectID).
Error
if err != nil {
return errors.WithStack(err)
}
strValue := strconv.FormatFloat(value, 'f', 12, 64)
task.Estimations[estimation] = &strValue
if err := updateTaskWithChanges(tx, task, changes); err != nil {
return errors.WithStack(err)
}
if err := tx.Save(task).Error; err != nil {
return errors.WithStack(err)
@ -253,7 +216,58 @@ func (r *ProjectRepository) UpdateTaskEstimation(ctx context.Context, projectID,
return nil, errors.Wrap(err, "could not update task")
}
return nil, nil
return task, nil
}
func updateTaskWithChanges(db *gorm.DB, task *Task, changes ProjectTaskChanges) error {
if changes.Label != nil {
task.Label = changes.Label
}
if changes.CategoryID != nil {
taskCategory := &TaskCategory{}
taskCategory.ID = *changes.CategoryID
task.Category = taskCategory
}
if changes.Estimations == nil {
return nil
}
if task.Estimations == nil {
task.Estimations = &Estimations{}
}
if changes.Estimations.Pessimistic != nil {
task.Estimations.Pessimistic = *changes.Estimations.Pessimistic
}
if changes.Estimations.Likely != nil {
task.Estimations.Likely = *changes.Estimations.Likely
}
if changes.Estimations.Optimistic != nil {
task.Estimations.Optimistic = *changes.Estimations.Optimistic
}
if task.Estimations.Likely < task.Estimations.Optimistic {
task.Estimations.Likely = task.Estimations.Optimistic
}
if task.Estimations.Pessimistic < task.Estimations.Likely {
task.Estimations.Pessimistic = task.Estimations.Likely
}
if changes.CategoryID != nil {
taskCategory := &TaskCategory{}
if err := db.Find(taskCategory, "id = ?", *changes.CategoryID).Error; err != nil {
return errors.Wrap(err, "could not find task category")
}
task.Category = taskCategory
}
return nil
}
func NewProjectRepository(db *gorm.DB) *ProjectRepository {