diff --git a/app/graphql/mutations/upsert_project.rb b/app/graphql/mutations/upsert_project.rb index 47d3e1d6..58160bbc 100644 --- a/app/graphql/mutations/upsert_project.rb +++ b/app/graphql/mutations/upsert_project.rb @@ -15,6 +15,7 @@ class UpsertProject < BaseMutation argument :hourly_rate, Integer, required: false, description: "The hourly rate for this project." argument :starts_on, GraphQL::Types::ISO8601Date, required: false, description: "The date this project starts." argument :ends_on, GraphQL::Types::ISO8601Date, required: false, description: "The date this project ends." + argument :assignments, [Types::StaffPlan::AssignmentAttributes], required: false, description: "Assignments for this project. See upsertAssignment to create a single assignment for existing projects." # return type from the mutation type Types::StaffPlan::ProjectType, null: true @@ -31,7 +32,8 @@ def resolve( rate_type: nil, hourly_rate: nil, starts_on: nil, - ends_on: nil + ends_on: nil, + assignments: [] ) current_company = context[:current_company] @@ -68,6 +70,10 @@ def resolve( if project.valid? project.save! + + assignments.map do |assignment| + project.assignments << Assignment.new(assignment.to_h) + end else project.errors.group_by_attribute.each do |attribute, errors| errors.each do |error| diff --git a/app/graphql/schema.graphql b/app/graphql/schema.graphql index a0a89fe0..67122fdb 100644 --- a/app/graphql/schema.graphql +++ b/app/graphql/schema.graphql @@ -38,6 +38,41 @@ type Assignment { workWeeks: [WorkWeek!]! } +""" +Attributes for creating an assignment +""" +input AssignmentAttributes { + """ + The date the assignment ends + """ + endsOn: ISO8601Date + + """ + The estimated weekly hours for this assignment + """ + estimatedWeeklyHours: Int + + """ + The project this assignment is for + """ + projectId: ID + + """ + The date the assignment starts + """ + startsOn: ISO8601Date + + """ + The status of the assignment + """ + status: String + + """ + The user assigned to this assignment + """ + userId: ID +} + enum AssignmentStatus { """ The assignment is currently in progress. @@ -181,6 +216,11 @@ type Mutation { Create or update a project. """ upsertProject( + """ + Assignments for this project. See upsertAssignment to create a single assignment for existing projects. + """ + assignments: [AssignmentAttributes!] + """ The ID of the client for this project. """ diff --git a/app/graphql/types/staff_plan/assignment_attributes.rb b/app/graphql/types/staff_plan/assignment_attributes.rb new file mode 100644 index 00000000..6b425c71 --- /dev/null +++ b/app/graphql/types/staff_plan/assignment_attributes.rb @@ -0,0 +1,10 @@ +class Types::StaffPlan::AssignmentAttributes < Types::BaseInputObject + description "Attributes for creating an assignment" + + argument :user_id, ID, required: false, description: "The user assigned to this assignment" + argument :project_id, ID, required: false, description: "The project this assignment is for" + argument :status, String, required: false, description: "The status of the assignment" + argument :starts_on, GraphQL::Types::ISO8601Date, required: false, description: "The date the assignment starts" + argument :ends_on, GraphQL::Types::ISO8601Date, required: false, description: "The date the assignment ends" + argument :estimated_weekly_hours, Integer, required: false, description: "The estimated weekly hours for this assignment" +end \ No newline at end of file diff --git a/spec/graphql/mutations/upsert_project_spec.rb b/spec/graphql/mutations/upsert_project_spec.rb index 8e417eb8..ddf43cb4 100644 --- a/spec/graphql/mutations/upsert_project_spec.rb +++ b/spec/graphql/mutations/upsert_project_spec.rb @@ -5,10 +5,10 @@ RSpec.describe Mutations::UpsertProject do context "resolve" do - it "creates a new project with valid params" do + it "creates a new project with assignments from valid params" do query_string = <<-GRAPHQL - mutation($clientId: ID, $name: String, $status: String) { - upsertProject(clientId: $clientId, name: $name, status: $status) { + mutation($clientId: ID, $name: String, $status: String, $assignments: [AssignmentAttributes!]) { + upsertProject(clientId: $clientId, name: $name, status: $status, assignments: $assignments) { id client { id @@ -17,11 +17,17 @@ status startsOn endsOn + assignments { + assignedUser { + email + } + } } } GRAPHQL user = create(:user) + assignee = create(:membership, company: user.current_company).user client = create(:client, company: user.current_company) result = StaffplanReduxSchema.execute( @@ -33,7 +39,10 @@ variables: { clientId: client.id, name: project_name = Faker::Company.buzzword, - status: Project::UNCONFIRMED + status: Project::UNCONFIRMED, + assignments: [{ + userId: assignee.id, + }] } ) @@ -44,6 +53,62 @@ expect(post_result["status"]).to eq(Project::UNCONFIRMED) expect(post_result["startsOn"]).to be_nil expect(post_result["endsOn"]).to be_nil + expect(post_result["assignments"].length).to eq(1) + expect(post_result["assignments"].first["assignedUser"]["email"]).to eq(assignee.email) + end + + it "creates a new project with unassigned assignments from valid params" do + query_string = <<-GRAPHQL + mutation($clientId: ID, $name: String, $status: String, $assignments: [AssignmentAttributes!]) { + upsertProject(clientId: $clientId, name: $name, status: $status, assignments: $assignments) { + id + client { + id + } + name + status + startsOn + endsOn + assignments { + assignedUser { + email + } + startsOn + } + } + } + GRAPHQL + + user = create(:user) + starts_on = Date.tomorrow.iso8601 + client = create(:client, company: user.current_company) + + result = StaffplanReduxSchema.execute( + query_string, + context: { + current_user: user, + current_company: user.current_company + }, + variables: { + clientId: client.id, + name: project_name = Faker::Company.buzzword, + status: Project::UNCONFIRMED, + assignments: [{ + startsOn: starts_on, + }] + } + ) + + post_result = result["data"]["upsertProject"] + expect(result["errors"]).to be_nil + expect(post_result["client"]["id"]).to eq(client.id.to_s) + expect(post_result["name"]).to eq(project_name) + expect(post_result["status"]).to eq(Project::UNCONFIRMED) + expect(post_result["startsOn"]).to be_nil + expect(post_result["endsOn"]).to be_nil + expect(post_result["assignments"].length).to eq(1) + expect(post_result["assignments"].first["assignedUser"]).to be_nil + expect(post_result["assignments"].first["startsOn"]).to eq(starts_on) end it "does not allow a client_id from another company to be specified" do