Skip to content

Commit

Permalink
Merge pull request #565 from wri/release/sassy-sycamore
Browse files Browse the repository at this point in the history
[RELEASE] Sassy Sycamore
  • Loading branch information
roguenet authored Nov 14, 2024
2 parents d6b0d21 + ea418b4 commit 9574202
Show file tree
Hide file tree
Showing 120 changed files with 6,290 additions and 3,582 deletions.
67 changes: 67 additions & 0 deletions app/Console/Commands/BulkApproveProjectPolygonsCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace App\Console\Commands;

use App\Models\Traits\SaveAuditStatusTrait;
use App\Models\V2\Projects\Project;
use App\Models\V2\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\File;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\ConsoleOutput;

class BulkApproveProjectPolygonsCommand extends Command
{
use SaveAuditStatusTrait;

protected $signature = 'bulk-approve-project-polygons {file}';

protected $description = 'Bulk approve site polygons for projects listed in a CSV file';

public function handle(): void
{
$filePath = $this->argument('file');

if (! File::exists($filePath)) {
$this->error("CSV file not found at {$filePath}");

return;
}
$userEmail = '[email protected]';
$user = User::where('email_address', $userEmail)->first();
Auth::login($user);
$data = array_map('str_getcsv', file($filePath));
$header = array_shift($data);
$output = new ConsoleOutput();
$progressBar = new ProgressBar($output, count($data));
$progressBar->setFormat('Processing: %current% [%bar%] %percent:3s%%');

$progressBar->start();

$polygonsChanged = [];

foreach ($data as $row) {
$uuid = $row[0];
$project = Project::isUuid($uuid)->first();
$this->info("\nProcessing project " . $uuid);
if ($project) {
foreach ($project->sitePolygons as $sitePolygon) {
$sitePolygon->status = 'approved';
$sitePolygon->save();

$this->saveAuditStatus(get_class($sitePolygon), $sitePolygon->id, $sitePolygon->status, 'Approved via bulk command', 'status');

$polygonsChanged[] = $sitePolygon;
}
}

$progressBar->advance();
}

$progressBar->finish();

// Print summary of the number of polygons approved
$this->info("\n" . count($polygonsChanged) . ' polygons were updated.');
}
}
71 changes: 71 additions & 0 deletions app/Console/Commands/BulkApproveProjects.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

namespace App\Console\Commands;

use App\Models\V2\Projects\Project;
use App\Models\V2\Projects\ProjectReport;
use App\Models\V2\Sites\SiteReport;
use App\Models\V2\Tasks\Task;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\ConsoleOutput;

class BulkApproveProjects extends Command
{
protected $signature = 'bulk-approve-projects {file}';

protected $description = 'Bulk approve projects from a CSV file';

public function handle(): void
{
$filePath = $this->argument('file');

if (! File::exists($filePath)) {
$this->error("CSV file not found at {$filePath}");

return;
}

$data = array_map('str_getcsv', file($filePath));
$header = array_shift($data);
$output = new ConsoleOutput();
$progressBar = new ProgressBar($output, count($data));
$progressBar->setFormat('Processing: %current% [%bar%] %percent:3s%%');

$progressBar->start();


$excludeDueDate = '2024-07-30';
foreach ($data as $row) {
$uuid = $row[0];

$project = Project::where('uuid', $uuid)->first();

if ($project) {
ProjectReport::where('project_id', $project->id)
->whereIn('status', ['awaiting-approval', 'needs-more-information'])
->whereDate('due_at', '!=', $excludeDueDate)
->update(['status' => 'approved']);

$sites = $project->sites;
foreach ($sites as $site) {
SiteReport::where('site_id', $site->id)
->whereIn('status', ['awaiting-approval', 'needs-more-information'])
->whereDate('due_at', '!=', $excludeDueDate)
->update(['status' => 'approved']);
}

Task::where('project_id', $project->id)
->whereIn('status', ['awaiting-approval', 'needs-more-information'])
->whereDate('due_at', '!=', $excludeDueDate)
->update(['status' => 'approved']);
}

$progressBar->advance();
}

$progressBar->finish();
$output->writeln("\nUpdate complete!");
}
}
74 changes: 74 additions & 0 deletions app/Console/Commands/BulkUpdateSiteReportDates.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace App\Console\Commands;

use App\Models\V2\Sites\SiteReport;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\ConsoleOutput;

class BulkUpdateSiteReportDates extends Command
{
protected $signature = 'sitereports:bulk-update-dates {file}';

protected $description = 'Bulk update site report due dates from a CSV file';

public function handle(): void
{
$filePath = $this->argument('file');
if (! File::exists($filePath)) {
$this->error("CSV file not found at {$filePath}");

return;
}

$output = new ConsoleOutput();
$progressBar = new ProgressBar($output);
$progressBar->setFormat('Processing: %current% [%bar%] %percent:3s%%');
$progressBar->start();

$handle = fopen($filePath, 'r');
$header = fgetcsv($handle);

while (($row = fgetcsv($handle)) !== false) {
if (empty(array_filter($row))) {
continue;
}
$uuid = $row[1];
$dueDateString = $row[2];
$dueDate = $this->parseDateString($dueDateString);
$siteReport = SiteReport::where('uuid', $uuid)->first();
if ($siteReport) {
$siteReport->update(['due_at' => $dueDate]);
}

$progressBar->advance();
}

fclose($handle);
$progressBar->finish();
$output->writeln("\nUpdate complete!");
}

protected function parseDateString(string $dateString): ?Carbon
{
$formats = [
'n/j/Y H:i',
'n/j/Y H:i:s',
'Y-m-d H:i:s',
'Y-m-d',
];

foreach ($formats as $format) {
try {
return Carbon::createFromFormat($format, $dateString)->setTimezone('UTC');
} catch (\Exception $e) {
// Ignore the exception and try the next format
}
}

return null;
}
}
11 changes: 5 additions & 6 deletions app/Console/Commands/CreateServiceAccount.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,23 @@ class CreateServiceAccount extends Command
*
* @var string
*/
protected $signature = 'create-service-account {email}';
protected $signature = 'create-service-account';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Creates a service account with the given email address.';
protected $description = 'Creates a service account';

/**
* Execute the console command.
*/
public function handle()
{
try {
$email = $this->argument('email');

$email = $this->ask('Email address for account');
$role = $this->choice('Role for account', ['greenhouse-service-account', 'research-service-account']);
$apiKey = base64_encode(random_bytes(48));

$data = [
Expand All @@ -46,8 +46,7 @@ public function handle()
$user = new User($data);
$user->saveOrFail();

// TODO Allow other types of service account, when/if necessary.
$user->assignRole('greenhouse-service-account');
$user->assignRole($role);

$this->info("Created service account $email with API Key: $apiKey");

Expand Down
16 changes: 9 additions & 7 deletions app/Console/Commands/OneOff/FixDuplicateDemographics.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace App\Console\Commands\OneOff;

use App\Models\V2\Demographics\Demographic;
use App\Models\V2\Workdays\Workday;
use App\Models\V2\Workdays\WorkdayDemographic;
use Illuminate\Console\Command;

class FixDuplicateDemographics extends Command
Expand All @@ -29,24 +29,26 @@ public function handle()
{
$workdays = [];

WorkdayDemographic::selectRaw('workday_id, type, subtype, name, count(*) as num, sum(amount) as sum')
Demographic::selectRaw('demographical_id, type, subtype, name, count(*) as num, sum(amount) as sum')
// group by is case insensitive, so in order to avoid turning up false positives, we cast to binary
// to get the DB to recognize different casing.
->groupByRaw('workday_id, type, subtype, name, Cast(name as binary)')
->groupByRaw('demographical_id, type, subtype, name, Cast(name as binary)')
->where('demographical_type', Workday::class)
->orderByRaw('num desc')
->chunk(10, function ($chunk) use (&$workdays) {
foreach ($chunk as $demographic) {
if ($demographic->num == 1) {
return false;
}

$demographic['rows'] = WorkdayDemographic::where([
'workday_id' => $demographic->workday_id,
$demographic['rows'] = Demographic::where([
'demographical_id' => $demographic->demographical_id,
'demographical_type' => Workday::class,
'type' => $demographic->type,
'subtype' => $demographic->subtype,
'name' => $demographic->name,
])->select('id', 'amount')->get()->toArray();
$workdays[$demographic->workday_id][] = $demographic->toArray();
$workdays[$demographic->demographical_id][] = $demographic->toArray();
}

return true;
Expand Down Expand Up @@ -95,7 +97,7 @@ public function handle()
unset($row);
foreach ($stat['rows'] as $row) {
if ($row['action'] == 'delete') {
WorkdayDemographic::find($row['id'])->delete();
Demographic::find($row['id'])->delete();
}
}
}
Expand Down
15 changes: 8 additions & 7 deletions app/Console/Commands/OneOff/MigrateWorkdayData.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace App\Console\Commands\OneOff;

use App\Models\V2\Demographics\Demographic;
use App\Models\V2\Workdays\Workday;
use App\Models\V2\Workdays\WorkdayDemographic;
use Illuminate\Console\Command;
use Illuminate\Support\Str;

Expand All @@ -24,9 +24,9 @@ class MigrateWorkdayData extends Command
protected $description = 'Updates Workday data to use the new workday_demographics table';

private const DEMOGRAPHICS = [
WorkdayDemographic::GENDER,
WorkdayDemographic::AGE,
WorkdayDemographic::ETHNICITY,
Demographic::GENDER,
Demographic::AGE,
Demographic::ETHNICITY,
];

private const SUBTYPE_NULL = 'subtype-null';
Expand Down Expand Up @@ -76,8 +76,9 @@ private function updateEntityWorkdays(string $entityType, int $entityId): void
foreach ($mapping as $demographic => $subTypes) {
foreach ($subTypes as $subType => $names) {
foreach ($names as $name => $amount) {
WorkdayDemographic::create([
'workday_id' => $workday->id,
Demographic::create([
'demographical_id' => $workday->id,
'demographical_type' => Workday::class,
'type' => $demographic,
'subtype' => $subType == self::SUBTYPE_NULL ? null : $subType,
'name' => $name == self::NAME_NULL ? null : $name,
Expand Down Expand Up @@ -119,7 +120,7 @@ private function mapWorkdayCollection(array $workdays): array

private function getSubtype(string $demographic, Workday $workday): string
{
if ($demographic != WorkdayDemographic::ETHNICITY) {
if ($demographic != Demographic::ETHNICITY) {
return self::SUBTYPE_NULL;
}

Expand Down
36 changes: 36 additions & 0 deletions app/Console/Commands/SendDailyDigestNotifications.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace App\Console\Commands;

use App\Jobs\SendDailyDigestNotificationsJob;
use App\Models\V2\Tasks\Task;
use Illuminate\Console\Command;

class SendDailyDigestNotifications extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'send-daily-digest-notifications';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Runs daily digest notifications for tasks';

/**
* Execute the console command.
*/
public function handle()
{
Task::isIncomplete()->chunkById(100, function ($tasks) {
$tasks->each(function (Task $task) {
SendDailyDigestNotificationsJob::dispatchSync($task);
});
});
}
}
1 change: 1 addition & 0 deletions app/Console/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ protected function schedule(Schedule $schedule)
$schedule->command('process-scheduled-jobs')->everyFiveMinutes()->onOneServer();
$schedule->command('generate-application-export')->twiceDaily(13, 20)->onOneServer();
$schedule->command('generate-admin-all-entity-records-export')->twiceDaily(13, 20)->onOneServer();
$schedule->command('send-daily-digest-notifications')->weeklyOn(1, '17:00')->timezone('Europe/Sofia')->onOneServer();
}

protected function commands()
Expand Down
Loading

0 comments on commit 9574202

Please sign in to comment.