Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
andreiio committed Nov 8, 2024
1 parent dbdd7db commit 2bd1388
Show file tree
Hide file tree
Showing 20 changed files with 482 additions and 106 deletions.
46 changes: 46 additions & 0 deletions app/Actions/CheckRecordHasIssues.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace App\Actions;

class CheckRecordHasIssues
{
public function checkTurnout(array $record): bool
{
$computedTotal = collect(['LP', 'LC', 'LS', 'UM'])
->map(fn (string $key) => $record[$key])
->sum();

if ($computedTotal !== $record['LT']) {
return true;
}

return false;
}

public function checkRecord(array $record): bool
{
if ($record['a'] != $record['a1'] + $record['a2']) {
return true;
}

if ($record['a1'] < $record['b1']) {
return true;
}

if ($record['a2'] < $record['b2']) {
return true;
}

if ($record['b'] != $record['b1'] + $record['b2'] + $record['b3']) {
return true;
}

if ($record['c'] < $record['d'] + $record['e'] + $record['f']) {
return true;
}

return false;
}
}
25 changes: 25 additions & 0 deletions app/Actions/CheckVotable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace App\Actions;

use Illuminate\Support\Str;

class CheckVotable
{
private function getIndependentCandidatePrefix(): string
{
return config('import.independent_candidate_prefix');
}

public function isIndependentCandidate(string $name): bool
{
return Str::startsWith($name, $this->getIndependentCandidatePrefix());
}

public function getName(string $name): string
{
return Str::afterLast($name, $this->getIndependentCandidatePrefix());
}
}
60 changes: 60 additions & 0 deletions app/Actions/GenerateMappedVotablesList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace App\Actions;

use App\Enums\Time;
use App\Models\Candidate;
use App\Models\Party;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;

class GenerateMappedVotablesList
{
public function votables(array $header): Collection
{
return Cache::remember(
hash('xxh128', implode(',', $header)),
Time::MINUTE_IN_SECONDS,
fn () => collect($header)
->filter(fn (string $column) => $this->hasVotesSuffix($column))
->mapWithKeys(fn (string $column) => [
$column => $this->getCandidateOrParty($column),
])
);
}

protected function getVotesSuffix(): string
{
return config('import.candidate_votes_suffix');
}

protected function hasVotesSuffix(string $column): bool
{
return Str::endsWith($column, $this->getVotesSuffix());
}

protected function getCandidateOrParty(string $name): array
{
$name = Str::before($name, $this->getVotesSuffix());

$votable = Party::query()
->where('name', $name)
->firstOr(
fn () => Candidate::query()
->where('name', $name)
->first()
);

if (blank($votable)) {
throw new \Exception("Votable not found for column: {$name}");
}

return [
'votable_type' => $votable?->getMorphClass(),
'votable_id' => $votable?->id,
];
}
}
28 changes: 28 additions & 0 deletions app/Enums/Part.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace App\Enums;

use App\Concerns\Enums\Arrayable;
use App\Concerns\Enums\Comparable;
use Filament\Support\Contracts\HasLabel;

enum Part: int implements HasLabel
{
use Arrayable;
use Comparable;

case PROV = 0;
case PART = 1;
case FINAL = 2;

public function getLabel(): ?string
{
return match ($this) {
self::PROV => __('app.part.prov'),
self::PART => __('app.part.part'),
self::FINAL => __('app.part.final'),
};
}
}
15 changes: 15 additions & 0 deletions app/Enums/Time.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace App\Enums;

enum Time: int
{
case MINUTE_IN_SECONDS = 60;
case HOUR_IN_SECONDS = 60 * 60;
case DAY_IN_SECONDS = 60 * 60 * 24;
case WEEK_IN_SECONDS = 60 * 60 * 24 * 7;
case MONTH_IN_SECONDS = 60 * 60 * 24 * 7 * 30;
case YEAR_IN_SECONDS = 60 * 60 * 24 * 7 * 30 * 365;
}
23 changes: 3 additions & 20 deletions app/Filament/Imports/SimpleCandidateImporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

namespace App\Filament\Imports;

use App\Actions\CheckVotable;
use App\Models\Candidate;
use App\Models\Party;
use Carbon\CarbonInterface;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
use Illuminate\Support\Str;

class SimpleCandidateImporter extends Importer
{
Expand All @@ -33,7 +33,7 @@ public function getJobRetryUntil(): ?CarbonInterface

public function resolveRecord(): Candidate|Party
{
static::$model = $this->isIndependentCandidate()
static::$model = app(CheckVotable::class)->isIndependentCandidate($this->data['name'])
? Candidate::class
: Party::class;

Expand All @@ -43,26 +43,9 @@ public function resolveRecord(): Candidate|Party
]);
}

private function getIndependentCandidatePrefix(): string
{
return config('import.independent_candidate_prefix');
}

private function getIndependentCandidateName(): string
{
return Str::after($this->data['name'], $this->getIndependentCandidatePrefix());
}

private function isIndependentCandidate(): bool
{
return Str::startsWith($this->data['name'], $this->getIndependentCandidatePrefix());
}

protected function afterValidate(): void
{
if ($this->isIndependentCandidate()) {
$this->data['name'] = $this->getIndependentCandidateName();
}
$this->data['name'] = app(CheckVotable::class)->getName($this->data['name']);
}

public static function getCompletedNotificationBody(Import $import): string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@

declare(strict_types=1);

namespace App\Jobs\Europarl240609\Results;
namespace App\Jobs\Europarl240609\Records;

use App\Jobs\DeleteTemporaryTableData;
use App\Jobs\PersistTemporaryTableData;
use App\Jobs\SchedulableJob;
use App\Models\County;
use App\Models\Record;
use App\Models\Vote;
use Illuminate\Support\Facades\Bus;

class FetchResultsJob extends SchedulableJob
class FetchRecordsJob extends SchedulableJob
{
public static function name(): string
{
return 'Europarlamentare 09.06.2024 / Rezultate';
return 'Europarlamentare 09.06.2024 / Procese Verbale';
}

public function execute(): void
Expand All @@ -28,12 +29,15 @@ public function execute(): void
$time = now()->toDateTimeString();

$jobs = $counties
->map(fn (County $county) => new ImportCountyResultsJob($this->scheduledJob, $county))
->push(new ImportAbroadResultsJob($this->scheduledJob));
->map(fn (County $county) => new ImportCountyRecordsJob($this->scheduledJob, $county))
->push(new ImportAbroadRecordsJob($this->scheduledJob));

$persistAndClean = fn () => Bus::chain([
new PersistTemporaryTableData(Record::class, $electionId),
new DeleteTemporaryTableData(Record::class, $electionId),

new PersistTemporaryTableData(Vote::class, $electionId),
new DeleteTemporaryTableData(Vote::class, $electionId),
])->dispatch();

Bus::batch($jobs)
Expand All @@ -53,7 +57,7 @@ public function tags(): array
{
return [
'import',
'results',
'records',
'scheduled_job:' . $this->scheduledJob->id,
'election:' . $this->scheduledJob->election_id,
static::name(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

declare(strict_types=1);

namespace App\Jobs\Europarl240609\Results;
namespace App\Jobs\Europarl240609\Records;

use App\Actions\CheckRecordHasIssues;
use App\Events\CountryCodeNotFound;
use App\Exceptions\CountryCodeNotFoundException;
use App\Exceptions\MissingSourceFileException;
Expand All @@ -18,7 +19,7 @@
use Illuminate\Queue\SerializesModels;
use League\Csv\Reader;

class ImportAbroadResultsJob implements ShouldQueue
class ImportAbroadRecordsJob implements ShouldQueue
{
use Batchable;
use Dispatchable;
Expand All @@ -43,7 +44,7 @@ public function __construct(ScheduledJob $scheduledJob)
$this->scheduledJob = $scheduledJob;
}

public function handle(): void
public function handle(CheckRecordHasIssues $checker): void
{
$disk = $this->scheduledJob->disk();
$path = $this->scheduledJob->getSourcePath('sr.csv');
Expand Down Expand Up @@ -84,7 +85,7 @@ public function handle(): void
'votes_valid' => $record['e'],
'votes_null' => $record['f'],

'has_issues' => $this->determineIfHasIssues($record),
'has_issues' => $checker->checkRecord($record),
]);
} catch (CountryCodeNotFoundException $th) {
CountryCodeNotFound::dispatch($record['uat_name'], $this->scheduledJob->election);
Expand All @@ -94,31 +95,6 @@ public function handle(): void
Record::saveToTemporaryTable($values->all());
}

protected function determineIfHasIssues(array $record): bool
{
if ($record['a'] != $record['a1'] + $record['a2']) {
return true;
}

if ($record['a1'] < $record['b1']) {
return true;
}

if ($record['a2'] < $record['b2']) {
return true;
}

if ($record['b'] != $record['b1'] + $record['b2'] + $record['b3']) {
return true;
}

if ($record['c'] < $record['d'] + $record['e'] + $record['f']) {
return true;
}

return false;
}

protected function getCountryId(string $name): string
{
$country = Country::search($name)->first();
Expand All @@ -139,7 +115,7 @@ public function tags(): array
{
return [
'import',
'results',
'records',
'scheduled_job:' . $this->scheduledJob->id,
'election:' . $this->scheduledJob->election_id,
'abroad',
Expand Down
Loading

0 comments on commit 2bd1388

Please sign in to comment.