Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Debt] Removes expectedClassifications, expectedSalary, expectedGenericJobTitle #7578

Merged
merged 5 commits into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions api/app/GraphQL/Mutations/PoolCandidateSnapshot.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,6 @@ query getProfile($userId: UUID!) {
fr
}
}
expectedGenericJobTitles {
id
key
name {
en
fr
}
}
isWoman
hasDisability
isIndigenous
Expand All @@ -63,16 +55,6 @@ query getProfile($userId: UUID!) {
locationPreferences
locationExemptions
acceptedOperationalRequirements
expectedSalary
expectedClassifications {
id
name {
en
fr
}
group
level
}
positionDuration
userSkills {
id
Expand Down
5 changes: 0 additions & 5 deletions api/app/GraphQL/Queries/CountPoolCandidatesByPool.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,6 @@ public function __invoke($_, array $args)
User::scopePositionDuration($userQuery, $filters['positionDuration']);
}

// expectedClassifications
if (array_key_exists('expectedClassifications', $filters)) {
User::scopeExpectedClassifications($userQuery, $filters['expectedClassifications']);
}

// skills
if (array_key_exists('skills', $filters)) {
User::scopeSkillsAdditive($userQuery, $filters['skills']);
Expand Down
3 changes: 0 additions & 3 deletions api/app/Http/Resources/UserResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,6 @@ public function toArray($request)
'govEmployeeType' => $this->gov_employee_type,
'department' => $this->department ? (new DepartmentResource(Department::find($this->department))) : null,
'currentClassification' => (new ClassificationResource($this->currentClassification)),
'expectedClassifications' => ClassificationResource::collection($this->expectedClassifications),
'expectedGenericJobTitles' => GenericJobTitleResource::collection($this->expectedGenericJobTitles),
'isWoman' => $this->is_woman,
'hasDisability' => $this->has_disability,
'isIndigenous' => $this->is_indigenous,
Expand All @@ -92,7 +90,6 @@ public function toArray($request)
'locationPreferences' => $this->location_preferences,
'locationExemptions' => $this->location_exemptions,
'acceptedOperationalRequirements' => $this->accepted_operational_requirements,
'expectedSalary' => $this->expected_salary,
'positionDuration' => $this->position_duration,
'poolCandidates' => PoolCandidateResource::collection($this->poolCandidates),
'experiences' => $collection,
Expand Down
2 changes: 0 additions & 2 deletions api/app/Listeners/StoreApplicationSnapshot.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ public function handle(ApplicationSubmitted $event)
$user = User::with([
'department',
'currentClassification',
'expectedClassifications',
'expectedGenericJobTitles',
'userSkills.skill',
'awardExperiences',
'awardExperiences.skills',
Expand Down
26 changes: 0 additions & 26 deletions api/app/Models/PoolCandidate.php
Original file line number Diff line number Diff line change
Expand Up @@ -214,30 +214,6 @@ public static function scopeQualifiedClassifications(Builder $query, ?array $cla
return $query;
}

/**
* scopeExpectedClassifications
*
* Scopes the query to only include applicants who have expressed interest in any of $classifications.
*
* @param Builder $query
* @param array|null $classifications
* @return Builder
*/
public function scopeExpectedClassifications(Builder $query, ?array $classifications): Builder
{
// if no filters provided then return query unchanged
if (empty($classifications)) {
return $query;
}

// pointing to the classification scope on the User model
// that scope also contains filterByClassificationToSalary and filterByClassificationToGenericJobTitles
$query->whereHas('user', function ($query) use ($classifications) {
User::scopeExpectedClassifications($query, $classifications);
});
return $query;
}

/**
* Scope Publishing Groups
*
Expand Down Expand Up @@ -502,8 +478,6 @@ public function createSnapshot()
$user = User::with([
'department',
'currentClassification',
'expectedClassifications',
'expectedGenericJobTitles',
'awardExperiences',
'awardExperiences.skills',
'communityExperiences',
Expand Down
1 change: 0 additions & 1 deletion api/app/Models/PoolCandidateFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
* @property boolean $is_woman
* @property string $language_ability
* @property array $work_regions
* @property array $expected_salary
* @property array $operational_requirements
* @property Illuminate\Support\Carbon $created_at
* @property Illuminate\Support\Carbon $updated_at
Expand Down
155 changes: 0 additions & 155 deletions api/app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
* @property boolean $has_diploma
* @property array $location_preferences
* @property string $location_exemptions
* @property array $expected_salary
* @property array $position_duration
* @property array $accepted_operational_requirements
* @property string $gov_employee_type
Expand Down Expand Up @@ -81,7 +80,6 @@ class User extends Model implements Authenticatable, LaratrustUser

protected $casts = [
'location_preferences' => 'array',
'expected_salary' => 'array',
'accepted_operational_requirements' => 'array',
'position_duration' => 'array',
'indigenous_communities' => 'array',
Expand All @@ -108,14 +106,6 @@ public function currentClassification(): BelongsTo
{
return $this->belongsTo(Classification::class, "current_classification");
}
public function expectedClassifications(): BelongsToMany
{
return $this->belongsToMany(Classification::class, 'classification_user')->withTimestamps();
}
public function expectedGenericJobTitles(): BelongsToMany
{
return $this->belongsToMany(GenericJobTitle::class, 'generic_job_title_user')->withTimestamps();
}
/**
* @deprecated
*/
Expand Down Expand Up @@ -247,7 +237,6 @@ public static function scopeIsProfileComplete(Builder $query, ?bool $isProfileCo
$query->whereNotNull('location_preferences');
$query->whereJsonLength('location_preferences', '>', 0);
$query->whereJsonLength('position_duration', '>', 0);
$query->has('expectedGenericJobTitles');
$query->whereNotNull('citizenship');
$query->whereNotNull('armed_forces_status');
}
Expand Down Expand Up @@ -471,52 +460,6 @@ public static function scopeQualifiedStreams(Builder $query, ?array $streams): B
return $query;
}

/**
* scopeExpectedClassifications
*
* Scopes the query to only return applicants who have expressed interest in any of $classifications.
* Applicants have been able to record this interest in various ways, so this scope may consider three fields on
* the user: expectedClassifications, expectedSalary, and expectedGenericJobTitles.
*
* @param Builder $query
* @param array|null $classifications Each classification is an object with a group and a level field.
* @return Builder
*/
public static function scopeExpectedClassifications(Builder $query, ?array $classifications): Builder
{
// if no filters provided then return query unchanged
if (empty($classifications)) {
return $query;
}

// Classifications act as an OR filter. The query should return candidates with any of the classifications.
// A single whereHas clause for the relationship, containing multiple orWhere clauses accomplishes this.
$query->where(function ($query) use ($classifications) {
$query->whereHas('expectedClassifications', function ($query) use ($classifications) {
foreach ($classifications as $index => $classification) {
if ($index === 0) {
// First iteration must use where instead of orWhere
$query->where(function ($query) use ($classification) {
$query->where('group', $classification['group'])->where('level', $classification['level']);
});
} else {
$query->orWhere(function ($query) use ($classification) {
$query->where('group', $classification['group'])->where('level', $classification['level']);
});
}
}
});
$query->orWhere(function ($query) use ($classifications) {
self::filterByClassificationToSalary($query, $classifications);
});
$query->orWhere(function ($query) use ($classifications) {
self::filterByClassificationToGenericJobTitles($query, $classifications);
});
});

return $query;
}

/**
* Scope Publishing Groups
*
Expand Down Expand Up @@ -556,104 +499,6 @@ public static function scopeInITPublishingGroup(Builder $query)
return $query;
}

public static function filterByClassificationToGenericJobTitles(Builder $query, ?array $classifications): Builder
{
// if no filters provided then return query unchanged
if (empty($classifications)) {
return $query;
}
// Classifications act as an OR filter. The query should return candidates with any of the classifications.
// A single whereHas clause for the relationship, containing multiple orWhere clauses accomplishes this.

// group these in a subquery to properly handle "OR" condition
$query->whereHas('expectedGenericJobTitles', function ($query) use ($classifications) {
$query->whereHas('classification', function ($query) use ($classifications) {
foreach ($classifications as $index => $classification) {
if ($index === 0) {
// First iteration must use where instead of orWhere
$query->where(function ($query) use ($classification) {
$query->where('group', $classification['group'])->where('level', $classification['level']);
});
} else {
$query->orWhere(function ($query) use ($classification) {
$query->where('group', $classification['group'])->where('level', $classification['level']);
});
}
}
});
});

return $query;
}
private static function filterByClassificationToSalary(Builder $query, ?array $classifications): Builder
{
// When managers search for a classification, also return any users whose expected salary
// ranges overlap with the min/max salaries of any of those classifications.
// Since salary ranges are text enums a custom SQL subquery is used to convert them to
// numeric values and compare them to specified classifications

// This subquery only works for a non-zero number of filter classifications.
// If passed zero classifications then return same query builder unchanged.
if (empty($classifications)) {
return $query;
}

$parameters = [];
$sql = <<<RAWSQL1
SELECT NULL -- find all candidates where a salary/group combination matches a classification filter
FROM (
SELECT -- convert salary ranges to numeric min/max values
t.user_id,
CASE t.salary_range_id
WHEN '_50_59K' THEN 50000
WHEN '_60_69K' THEN 60000
WHEN '_70_79K' THEN 70000
WHEN '_80_89K' THEN 80000
WHEN '_90_99K' THEN 90000
WHEN '_100K_PLUS' THEN 100000
END min_salary,
CASE t.salary_range_id
WHEN '_50_59K' THEN 59999
WHEN '_60_69K' THEN 69999
WHEN '_70_79K' THEN 79999
WHEN '_80_89K' THEN 89999
WHEN '_90_99K' THEN 99999
WHEN '_100K_PLUS' THEN 2147483647
END max_salary
FROM (
SELECT -- find all salary ranges for each candidate
users.id user_id,
JSONB_ARRAY_ELEMENTS_TEXT(users.expected_salary) salary_range_id
FROM users
) t
) u
JOIN classifications c ON
c.max_salary >= u.min_salary
AND c.min_salary <= u.max_salary
WHERE (
RAWSQL1;

foreach ($classifications as $index => $classification) {
if ($index === 0) {
// First iteration must use where instead of orWhere
$sql .= '(c.group = ? AND c.level = ?)';
} else {
$sql .= ' OR (c.group = ? AND c.level = ?)';
}
array_push($parameters, [$classification['group'], $classification['level']]);
}

$sql .= <<<RAWSQL2
)
AND u.user_id = "users".id
RAWSQL2;

return $query->whereRaw('EXISTS (' . $sql . ')', $parameters);
}

public static function scopeHasDiploma(Builder $query, ?bool $hasDiploma): Builder
{
if ($hasDiploma) {
Expand Down
26 changes: 0 additions & 26 deletions api/database/factories/UserFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,17 +122,6 @@ public function definition()
3
),
'location_exemptions' => "{$this->faker->city()}, {$this->faker->city()}, {$this->faker->city()}",
'expected_salary' => $this->faker->randomElements(
[
'_50_59K',
'_60_69K',
'_70_79K',
'_80_89K',
'_90_99K',
'_100K_PLUS',
],
3
),
'position_duration' => $this->faker->boolean() ?
[ApiEnums::POSITION_DURATION_PERMANENT, ApiEnums::POSITION_DURATION_TEMPORARY]
: [ApiEnums::POSITION_DURATION_PERMANENT], // always accepting PERMANENT
Expand All @@ -148,18 +137,6 @@ public function definition()
];
}

/**
* GenericJobTitleSeeder must have already been run.
*/
public function withExpectedGenericJobTitles()
{
return $this->afterCreating(function (User $user) {
$user->expectedGenericJobTitles()->saveMany(
GenericJobTitle::inRandomOrder()->take(3)->get()
);
});
}

public function withExperiences($count = 10)
{
$types = [
Expand Down Expand Up @@ -202,9 +179,6 @@ public function configure()
{
return $this->afterCreating(function (User $user) {
$user->addRole('base_user');
$user->expectedGenericJobTitles()->saveMany(
GenericJobTitle::inRandomOrder()->take(1)->get()
);
});
}

Expand Down
Loading