Skip to content

Commit

Permalink
Merge branch 'main' into 12420-copy-advertisement-admin
Browse files Browse the repository at this point in the history
  • Loading branch information
mnigh authored Jan 14, 2025
2 parents 2ea22e7 + c4d9102 commit 1d9781c
Show file tree
Hide file tree
Showing 33 changed files with 874 additions and 42 deletions.
11 changes: 11 additions & 0 deletions api/app/Enums/DevelopmentProgramParticipationStatus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace App\Enums;

enum DevelopmentProgramParticipationStatus
{
case NOT_INTERESTED;
case INTERESTED;
case ENROLLED;
case COMPLETED;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\GraphQL\Validators;

use App\Models\DevelopmentProgram;
use App\Models\WorkStream;
use Database\Helpers\ApiErrorEnums;
use Illuminate\Validation\Rule;
Expand All @@ -18,6 +19,7 @@ public function rules(): array
{
$communityId = $this->arg('community.connect');
$workStreams = $communityId ? WorkStream::where('community_id', $communityId)->get('id')->pluck('id') : [];
$developmentProgramIds = $communityId ? DevelopmentProgram::where('community_id', $communityId)->get('id')->pluck('id') : [];

return [
'userId' => ['uuid', 'required', 'exists:users,id'],
Expand All @@ -28,6 +30,7 @@ public function rules(): array
'jobInterest' => ['nullable', 'boolean'],
'trainingInterest' => ['nullable', 'boolean'],
'additionalInformation' => ['nullable', 'string'],
'interestInDevelopmentPrograms.create.*.developmentProgramId' => ['uuid', Rule::in($developmentProgramIds)],
];
}

Expand All @@ -38,6 +41,7 @@ public function messages(): array
'community.connect.unique' => ApiErrorEnums::COMMUNITY_INTEREST_EXISTS,
'workStreams.sync.*.in' => ApiErrorEnums::WORK_STREAM_NOT_IN_COMMUNITY,
'workStreams.sync.*.exists' => ApiErrorEnums::WORK_STREAM_NOT_FOUND,
'interestInDevelopmentPrograms.create.*.developmentProgramId.in' => ApiErrorEnums::DEVELOPMENT_PROGRAM_NOT_VALID_FOR_COMMUNITY,
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace App\GraphQL\Validators;

use App\Enums\DevelopmentProgramParticipationStatus;
use Database\Helpers\ApiErrorEnums;
use Illuminate\Validation\Rule;
use Nuwave\Lighthouse\Validation\Validator;

final class CreateDevelopmentProgramInterestInputValidator extends Validator
{
/**
* Return the validation rules.
*
* @return array<string, array<mixed>>
*/
public function rules(): array
{
return [
// developmentProgramId validated in the Create/UpdateCommunityInterestInputValidator
'participationStatus' => [Rule::in(array_column(DevelopmentProgramParticipationStatus::cases(), 'name'))],
'completionDate' => [
'date',
'required_if:participationStatus,'.DevelopmentProgramParticipationStatus::COMPLETED->name,
'prohibited_unless:participationStatus,'.DevelopmentProgramParticipationStatus::COMPLETED->name,
],
];
}

public function messages(): array
{
return [
'completionDate.required_if' => ApiErrorEnums::DEVELOPMENT_PROGRAM_COMPLETION_DATE_REQUIRED,
'completionDate.prohibited_unless' => ApiErrorEnums::DEVELOPMENT_PROGRAM_COMPLETION_DATE_PROHIBITED,
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\GraphQL\Validators;

use App\Models\CommunityInterest;
use App\Models\DevelopmentProgram;
use App\Models\WorkStream;
use Database\Helpers\ApiErrorEnums;
use Illuminate\Validation\Rule;
Expand All @@ -19,12 +20,14 @@ public function rules(): array
{
$communityId = CommunityInterest::with('community')->find($this->arg('id'))?->community?->id;
$workStreams = $communityId ? WorkStream::where('community_id', $communityId)->get('id')->pluck('id') : [];
$developmentProgramIds = $communityId ? DevelopmentProgram::where('community_id', $communityId)->get('id')->pluck('id') : [];

return [
'workStreams.sync.*' => ['uuid', 'exists:work_streams,id', Rule::in($workStreams)],
'jobInterest' => ['nullable', 'boolean'],
'trainingInterest' => ['nullable', 'boolean'],
'additionalInformation' => ['nullable', 'string'],
'interestInDevelopmentPrograms.create.*.developmentProgramId' => ['uuid', Rule::in($developmentProgramIds)],
];
}

Expand All @@ -34,6 +37,7 @@ public function messages(): array
'community.connect.exists' => ApiErrorEnums::COMMUNITY_NOT_FOUND,
'workStreams.sync.*.in' => ApiErrorEnums::WORK_STREAM_NOT_IN_COMMUNITY,
'workStreams.sync.*.exists' => ApiErrorEnums::WORK_STREAM_NOT_FOUND,
'interestInDevelopmentPrograms.create.*.developmentProgramId.in' => ApiErrorEnums::DEVELOPMENT_PROGRAM_NOT_VALID_FOR_COMMUNITY,
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace App\GraphQL\Validators;

use App\Enums\DevelopmentProgramParticipationStatus;
use Database\Helpers\ApiErrorEnums;
use Illuminate\Validation\Rule;
use Nuwave\Lighthouse\Validation\Validator;

final class UpdateDevelopmentProgramInterestInputValidator extends Validator
{
/**
* Return the validation rules.
*
* @return array<string, array<mixed>>
*/
public function rules(): array
{
return [
'participationStatus' => [Rule::in(array_column(DevelopmentProgramParticipationStatus::cases(), 'name'))],
'completionDate' => [
'date',
'required_if:participationStatus,'.DevelopmentProgramParticipationStatus::COMPLETED->name,
'prohibited_unless:participationStatus,'.DevelopmentProgramParticipationStatus::COMPLETED->name,
],
];
}

public function messages(): array
{
return [
'completionDate.required_if' => ApiErrorEnums::DEVELOPMENT_PROGRAM_COMPLETION_DATE_REQUIRED,
'completionDate.prohibited_unless' => ApiErrorEnums::DEVELOPMENT_PROGRAM_COMPLETION_DATE_PROHIBITED,
];
}
}
9 changes: 9 additions & 0 deletions api/app/Models/Community.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,13 @@ public function getTeamIdForRoleAssignmentAttribute()
{
return $this->team?->id;
}

/** A community has 0..* associated development programs
*
* @return HasMany<DevelopmentProgram, $this>
*/
public function developmentPrograms(): HasMany
{
return $this->hasMany(DevelopmentProgram::class);
}
}
7 changes: 7 additions & 0 deletions api/app/Models/CommunityInterest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;

/**
* Class CommunityInterest
Expand All @@ -29,4 +30,10 @@ public function workStreams(): BelongsToMany
{
return $this->belongsToMany(WorkStream::class);
}

/** @return HasMany<DevelopmentProgramInterest, $this> */
public function interestInDevelopmentPrograms(): HasMany
{
return $this->hasMany(DevelopmentProgramInterest::class);
}
}
48 changes: 48 additions & 0 deletions api/app/Models/DevelopmentProgram.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

/**
* Class DevelopmentProgram
*
* @property string $id
* @property \Illuminate\Support\Carbon $created_at
* @property ?\Illuminate\Support\Carbon $updated_at
* @property ?\Illuminate\Support\Carbon $deleted_at
* @property array $name
* @property array $description_for_profile
* @property array $description_for_nominations
* @property string $community_id
*/
class DevelopmentProgram extends Model
{
use HasFactory;

protected $keyType = 'string';

/**
* The attributes that should be cast.
*/
protected $casts = [
'name' => 'array',
'description_for_profile' => 'array',
'description_for_nominations' => 'array',
];

/** @return BelongsTo<Community, $this> */
public function community(): BelongsTo
{
return $this->belongsTo(Community::class);
}

/** @return BelongsToMany<Classification, $this> */
public function eligibleClassifications(): BelongsToMany
{
return $this->belongsToMany(Classification::class);
}
}
47 changes: 47 additions & 0 deletions api/app/Models/DevelopmentProgramInterest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace App\Models;

use App\Enums\DevelopmentProgramParticipationStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
* Class DevelopmentProgramInterest
*
* @property string $id
* @property \Illuminate\Support\Carbon $created_at
* @property ?\Illuminate\Support\Carbon $updated_at
* @property ?\Illuminate\Support\Carbon $deleted_at
* @property string $development_program_id
* @property string $community_interest_id
* @property string $participation_status
* @property ?\Illuminate\Support\Carbon $completion_date
*/
class DevelopmentProgramInterest extends Model
{
use HasFactory;

protected $keyType = 'string';

/**
* The attributes that should be cast.
*/
protected $casts = [
'participation_status' => DevelopmentProgramParticipationStatus::class,
'completion_date' => 'datetime',
];

/** @return BelongsTo<CommunityInterest, $this> */
public function communityInterest(): BelongsTo
{
return $this->belongsTo(CommunityInterest::class);
}

/** @return BelongsTo<DevelopmentProgram, $this> */
public function developmentProgram(): BelongsTo
{
return $this->belongsTo(DevelopmentProgram::class);
}
}
17 changes: 17 additions & 0 deletions api/database/factories/CommunityInterestFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Models\Community;
use App\Models\CommunityInterest;
use App\Models\DevelopmentProgramInterest;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;

Expand Down Expand Up @@ -52,4 +53,20 @@ public function withWorkStreams(int $limit = 3)
$model->workStreams()->attach($workStreams);
});
}

/**
* Create many development program relationships from the parent community
*/
public function withDevelopmentProgramInterests(int $limit = 3)
{
return $this->afterCreating(function (CommunityInterest $communityInterest) use ($limit) {
$developmentPrograms = $communityInterest->community->developmentPrograms()->limit($limit)->get();
foreach ($developmentPrograms as $developmentProgram) {
DevelopmentProgramInterest::factory()
->for($communityInterest)
->for($developmentProgram)
->create();
}
});
}
}
60 changes: 60 additions & 0 deletions api/database/factories/DevelopmentProgramFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

namespace Database\Factories;

use App\Models\Classification;
use App\Models\Community;
use App\Models\DevelopmentProgram;
use Database\Helpers\FactoryHelpers;
use ErrorException;
use Illuminate\Database\Eloquent\Factories\Factory;

class DevelopmentProgramFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = DevelopmentProgram::class;

/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'name' => FactoryHelpers::toFakeLocalizedString($this->faker->company()),
'description_for_profile' => FactoryHelpers::toFakeLocalizedString($this->faker->sentence()),
'description_for_nominations' => FactoryHelpers::toFakeLocalizedString($this->faker->sentence()),
'community_id' => function () {
$community = Community::inRandomOrder()->firstOr(fn () => Community::factory()->withWorkStreams()->create());

return $community->id;
},
];
}

public function configure()
{
return $this
->afterMaking(function (DevelopmentProgram $model) {
// https://laravel.com/docs/10.x/eloquent-factories#belongs-to-relationships
if (is_null($model->community_id)) {
throw new ErrorException('community_id must be set to use this factory. Try calling this factory with the `for` method to specify the parent community.');
}
});
}

public function withEligibleClassifications(?int $min = 1, ?int $max = 3)
{
$count = $this->faker->numberBetween($min, $max);

return $this->afterCreating(function (DevelopmentProgram $program) use ($count) {
$classifications = Classification::inRandomOrder()->limit($count)->get();
$program->eligibleClassifications()->sync($classifications);
});
}
}
Loading

0 comments on commit 1d9781c

Please sign in to comment.