Verified Commit b5107012 authored by Korko's avatar Korko
Browse files

Store exclusions in database

parent 5fe6e36f
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Exclusion extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['participant_id', 'exclusion_id'];
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
}
......@@ -32,9 +32,6 @@ class Participant extends Model
*/
protected $fillable = ['name', 'email', 'draw_id', 'target_id', 'mail_id'];
// Fake property
public $exclusions;
public function draw()
{
return $this->belongsTo(Draw::class);
......@@ -60,6 +57,11 @@ class Participant extends Model
return $this->belongsTo(Mail::class, 'mail_id');
}
public function exclusions()
{
return $this->belongsToMany(Participant::class, 'exclusions', 'participant_id', 'exclusion_id');
}
public function scopeFindByDearSantaUrlOrFail($query, $url)
{
$route = app('router')
......@@ -76,13 +78,7 @@ class Participant extends Model
public function getExclusionsNamesAttribute()
{
$participantNames = $this->draw->participants->pluck('name', 'id');
return collect($this->exclusions)
->map(function ($participantId) use ($participantNames) {
return $participantNames[$participantId];
})
->all();
return $this->exclusions->pluck('name', 'id')->all();
}
/**
......
......@@ -72,19 +72,19 @@ class DrawHandler
$participant->draw()->associate($draw);
$participant->name = $santa['name'];
$participant->email = Arr::get($santa, 'email');
$participant->exclusions = $santa['exclusions'];
$participant->mail()->associate($mail);
$participant->save();
$participants[$idx] = $participant;
$participants[$idx]['model'] = $participant;
$draw->participants->add($participant);
}
foreach ($hat as $santaIdx => $targetIdx) {
$draw->participants[$santaIdx]->exclusions = array_map(function ($participantId) use ($participants) {
return $participants[$participantId]->id;
}, $participants[$santaIdx]->exclusions);
$draw->participants[$santaIdx]->target()->save($participants[$targetIdx]);
foreach ($participants[$santaIdx]['exclusions'] as $participantId) {
$draw->participants[$santaIdx]->exclusions()->attach($participants[$participantId]['model']->id);
}
$draw->participants[$santaIdx]->target()->save($participants[$targetIdx]['model']);
$draw->participants[$santaIdx]->save();
}
}
......@@ -96,18 +96,19 @@ class DrawHandler
public function sendDelayedOrganizerEmail(Draw $draw)
{
$draw->participants->each(function (&$participant) {
$participant->exclusions[] = $participant->target->id;
$exclusions = [];
$draw->participants->each(function (&$participant) use (&$exclusions) {
// We don't attach so not in DB, just in the Collection
$participant->exclusions->push($participant->target);
$exclusions[$participant->id] = $participant->exclusions->pluck('id')->all();
});
try {
// Check if there's a solution with the previous exclusions + the actual target
Solver::one($draw->participants->all(), $draw->participants->pluck('exclusions', 'id')->all());
Solver::one($draw->participants->all(), $exclusions);
} catch (SolverException $exception) {
// If not, reset all the exclusions
$draw->participants->each(function (&$participant) {
$participant->exclusions = [];
});
$exclusions = [];
}
SendMail::dispatch($draw->organizer, new OrganizerFinalRecap($draw))
......
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateExclusionsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('exclusions', function (Blueprint $table) {
$table->foreignId('participant_id')->constrained();
$table->foreignId('exclusion_id')->constrained('participants');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('exclusions');
}
}
......@@ -8,6 +8,7 @@ use App\Mail\OrganizerFinalRecap;
use App\Mail\OrganizerRecap;
use App\Mail\TargetDrawn;
use App\Models\Draw;
use App\Models\Exclusion;
use App\Models\Participant;
use DrawHandler;
use Exception;
......@@ -68,11 +69,12 @@ class DrawHandlerTest extends TestCase
$this->assertEquals(0, Draw::count());
$this->assertEquals(0, Participant::count());
$this->assertEquals(0, Exclusion::count());
$participants = [
['name' => 'toto', 'email' => 'test@test.com', 'exclusions' => [2]],
['name' => 'tata', 'email' => 'test3@test.com', 'exclusions' => [0]],
['name' => 'tutu', 'email' => 'test2@test.com', 'exclusions' => [1]],
['name' => uniqid(), 'email' => 'test@test.com', 'exclusions' => [2]],
['name' => uniqid(), 'email' => 'test3@test.com', 'exclusions' => [0]],
['name' => uniqid(), 'email' => 'test2@test.com', 'exclusions' => [1]],
];
DrawHandler::toParticipants($participants)
......@@ -91,11 +93,16 @@ class DrawHandlerTest extends TestCase
$this->assertHasMailPushed(TargetDrawn::class, 'test@test.com', function ($m) use (&$title) {
$title = $m->subject;
});
$this->assertStringContainsString('test mail toto => tata title', html_entity_decode($title));
$this->assertStringContainsString('test mail '.$participants[0]['name'].' => '.$participants[1]['name'].' title', html_entity_decode($title));
$this->assertHasMailPushed(TargetDrawn::class, 'test2@test.com');
$this->assertEquals(1, Draw::count());
$this->assertEquals(3, Participant::count());
$this->assertEquals(3, Exclusion::count());
// Carreful, array is 0..n, Db is 1..n
$this->assertEquals($participants[0]['name'], Participant::find(1)->name);
$this->assertEquals(Participant::find(3)->id, Participant::find(1)->exclusions[0]->id);
// Check data stored are decryptable
$path = parse_url($link, PHP_URL_PATH);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment