Skip to content

Commit

Permalink
Merge pull request #591 from wri/release/tacky-teak
Browse files Browse the repository at this point in the history
[RELEASE] Tacky Teak
  • Loading branch information
roguenet authored Dec 2, 2024
2 parents f7dfdec + 9bb6341 commit 7e29a10
Show file tree
Hide file tree
Showing 69 changed files with 4,860 additions and 246 deletions.
53 changes: 53 additions & 0 deletions app/Console/Commands/ExportApprovedDashboardDataCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace App\Console\Commands;

use App\Helpers\TerrafundDashboardQueryHelper;
use Illuminate\Console\Command;
use Illuminate\Http\Request;

class ExportApprovedDashboardDataCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:export-approved-dashboard-data-command';

/**
* The console command description.
*
* @var string
*/
protected $description = 'return CSV for approved projects';

/**
* Execute the console command.
*/
public function handle()
{
$request = new Request(['filter' => []]);
$projects = TerrafundDashboardQueryHelper::buildQueryFromRequest($request)
->with(['organisation:id,type,name'])
->select([
'v2_projects.uuid',
'v2_projects.id',
])
->get();
$csvFile = fopen('projects_report.csv', 'w');
fputcsv($csvFile, ['Project UUID', 'Trees Planted to Date', 'Hectares Under Restoration', 'Jobs Created']);

foreach ($projects as $project) {
fputcsv($csvFile, [
$project->uuid,
$project->approved_trees_planted_count,
$project->total_hectares_restored_sum,
$project->total_approved_jobs_created,
]);
}
fclose($csvFile);

echo "CSV file 'projects_report.csv' created successfully.";
}
}
56 changes: 56 additions & 0 deletions app/Console/Commands/OneOff/BackfillTestProjectsOrgs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace App\Console\Commands\OneOff;

use App\Models\V2\Organisation;
use App\Models\V2\Projects\Project;
use Illuminate\Console\Command;

class BackfillTestProjectsOrgs extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'one-off:backfill-test-projects-orgs';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Sets the is_test flag on test projects and organisations';

// In addition to these orgs, all projects within these orgs will get marked with is_test = true
private const TEST_ORGS = [
'7150d4ef-c785-49ed-9fb6-a28ef48ffb98', // 3SC PRODUCTION ORG (GT) - PLEASE IGNORE
'15c2a8dc-d395-11ed-8014-0682e69bfbec', // TM Org
'2470ced8-dc03-4d1e-9c64-b6445ac2c558', // test 0709
'f936d363-8409-401e-8711-708909cfa205', // Edward's Testing Playground
'15c07e71-d395-11ed-8014-0682e69bfbec', // Claire Trees Org
];

// These test projects are in an org that is not itself a test org
private const TEST_PROJECTS = [
'be1d70ad-9f0e-486f-a85a-86c075d6a4d1', // Conservation International test project
];

/**
* Execute the console command.
*/
public function handle()
{
foreach (Organisation::whereIn('uuid', self::TEST_ORGS)->get() as $organisation) {
$organisation->update(['is_test' => true]);

foreach ($organisation->projects as $project) {
$project->update(['is_test' => true]);
}
}

foreach (Project::whereIn('uuid', self::TEST_PROJECTS)->get() as $project) {
$project->update(['is_test' => true]);
}
}
}
45 changes: 43 additions & 2 deletions app/Exports/V2/OrganisationsExport.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,46 @@ public function collection(): Collection
{
ini_set('max_execution_time', 60);

return Organisation::all();
return Organisation::query()->select([
'uuid',
'status',
'type',
'name',
'phone',
'hq_street_1',
'hq_street_2',
'hq_city',
'hq_state',
'hq_zipcode',
'hq_country',
'countries',
'languages',
'founding_date',
'description',
'web_url',
'facebook_url',
'instagram_url',
'linkedin_url',
'twitter_url',
'fin_start_month',
'fin_budget_3year',
'fin_budget_2year',
'fin_budget_1year',
'fin_budget_current_year',
'ha_restored_total',
'ha_restored_3year',
'trees_grown_total',
'trees_grown_3year',
'tree_care_approach',
'relevant_experience_years',
'updated_at',
'created_at',
])->get();
}

public function chunkSize(): int
{
return 1000;
}

public function headings(): array
Expand Down Expand Up @@ -108,6 +147,7 @@ public function map($organisation): array

private function addFileCollectionValues(Organisation $organisation, array $mapped): array
{
$organisation = Organisation::where('uuid', $organisation->uuid)->first();
foreach ($organisation->fileConfiguration as $key => $config) {
if ($config['multiple'] == true) {
$medias = $organisation->getMedia($key);
Expand Down Expand Up @@ -141,7 +181,8 @@ private function addFileCollectionHeadings(array $headings): array
private function buildTreeSpecies(Organisation $organisation): string
{
$list = [];
foreach ($organisation->treeSpecies as $treeSpecies) {
$treeSpecies = $organisation->treeSpecies()->select('name', 'amount')->get();
foreach ($treeSpecies as $treeSpecies) {
$list[] = $treeSpecies->name . '(' . $treeSpecies->amount . ')';
}

Expand Down
21 changes: 8 additions & 13 deletions app/Helpers/GeometryHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use App\Models\V2\PolygonGeometry;
use App\Models\V2\Projects\Project;
use App\Models\V2\Projects\ProjectPolygon;
use App\Models\V2\Sites\CriteriaSite;
use App\Models\V2\Sites\Site;
use App\Models\V2\Sites\SitePolygon;
use Exception;
Expand Down Expand Up @@ -125,18 +124,14 @@ public static function getPolygonsBbox($polygonsIds)

public static function getCriteriaDataForPolygonGeometry($polygonGeometry)
{
return CriteriaSite::whereIn(
'id',
$polygonGeometry
->criteriaSite()
->groupBy('criteria_id')
->selectRaw('max(id) as latest_id')
)->get([
'criteria_id',
'valid',
'created_at as latest_created_at',
'extra_info',
]);
return $polygonGeometry
->criteriaSite()
->get([
'criteria_id',
'valid',
'created_at as latest_created_at',
'extra_info',
]);
}

public static function groupFeaturesBySiteId($geojson)
Expand Down
72 changes: 72 additions & 0 deletions app/Http/Controllers/AuthController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@
use App\Http\Requests\ResendByEmailRequest;
use App\Http\Requests\ResendRequest;
use App\Http\Requests\ResetRequest;
use App\Http\Requests\SendLoginDetailsRequest;
use App\Http\Requests\SetPasswordRequest;
use App\Http\Requests\VerifyRequest;
use App\Http\Resources\V2\User\MeResource;
use App\Jobs\ResetPasswordJob;
use App\Jobs\SendLoginDetailsJob;
use App\Jobs\UserVerificationJob;
use App\Models\PasswordReset as PasswordResetModel;
use App\Models\V2\Projects\ProjectInvite;
Expand All @@ -24,6 +27,7 @@
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;

Expand Down Expand Up @@ -160,6 +164,74 @@ public function resetAction(ResetRequest $request): JsonResponse
return JsonResponseHelper::success((object) [], 200);
}

public function sendLoginDetailsAction(SendLoginDetailsRequest $request): JsonResponse
{
$this->authorize('reset', 'App\\Models\\Auth');
$data = $request->json()->all();

try {
$user = UserModel::where('email_address', '=', $data['email_address'])
->whereNull('password')
->firstOrFail();
} catch (Exception $exception) {
return JsonResponseHelper::success((object) [], 200);
}

SendLoginDetailsJob::dispatch($user, isset($data['callback_url']) ? $data['callback_url'] : null);

return JsonResponseHelper::success((object) [], 200);
}

public function getEmailByResetTokenAction(Request $request): JsonResponse
{
$data = $request->query();

$passwordReset = PasswordResetModel::where('token', '=', $data['token'])->first();

if (! $passwordReset) {
return JsonResponseHelper::success((object) [
'email_address' => null,
'token_used' => true,
], 200);
}
if (Carbon::parse($passwordReset->created_at)->addDays(7)->isPast()) {
$passwordReset->delete();

return JsonResponseHelper::success((object) [
'email_address' => null,
'token_used' => true,
], 200);
}

$user = UserModel::findOrFail($passwordReset->user_id);

return JsonResponseHelper::success((object) [
'email_address' => $user->email_address,
'token_used' => false,
], 200);
}

public function setNewPasswordAction(SetPasswordRequest $request): JsonResponse
{
$this->authorize('change', 'App\\Models\\Auth');
$data = $request->json()->all();
$passwordReset = PasswordResetModel::where('token', '=', $data['token'])->firstOrFail();
$user = UserModel::findOrFail($passwordReset->user_id);
if (Hash::check($data['password'], $user->password)) {
throw new SamePasswordException();
}
$user->password = $data['password'];

if (empty($user->email_address_verified_at)) {
$user->email_address_verified_at = new DateTime('now', new DateTimeZone('UTC'));
}

$user->saveOrFail();
$passwordReset->delete();

return JsonResponseHelper::success((object) [], 200);
}

public function changeAction(ChangePasswordRequest $request): JsonResponse
{
$this->authorize('change', 'App\\Models\\Auth');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function __invoke(Request $request, Project $project)

return (new DelayedJobResource($delayedJob))->additional(['message' => "Export for project $project->id is being processed"]);
} else {
$filename = storage_path('./'.Str::of($project->name)->replace(['/', '\\'], '-') . ' full export - ' . now() . '.zip');
$filename = storage_path('./'.Str::of($project->name)->replace(['/', '\\'], '-') . ' full export - ' . now()->format('d-m-Y') . '.zip');
file_put_contents($filename, $binary_data);

return response()->download($filename)->deleteFileAfterSend();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,45 @@

namespace App\Http\Controllers\V2\Organisations;

use App\Exports\V2\OrganisationsExport;
use App\Http\Controllers\Controller;
use App\Http\Resources\DelayedJobResource;
use App\Jobs\ExportAllOrganisationsJob;
use App\Models\DelayedJob;
use App\Models\V2\Organisation;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Excel;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class AdminExportOrganisationsController extends Controller
{
public function __invoke(Request $request): BinaryFileResponse
public function __invoke(Request $request)
{
$this->authorize('export', Organisation::class);

$filename = 'organisations(' . now()->format('d-m-Y-H-i'). ').csv';
$filename = 'organisations(' . now()->format('d-m-Y'). ').csv';
$relativePath = 'exports/' . $filename;
$absolutePath = storage_path('app/' . $relativePath);

return (new OrganisationsExport())->download($filename, Excel::CSV)->deleteFileAfterSend(true);
try {
$binary_data = Redis::get('exports:organisations:'.$filename);
if (! $binary_data) {
$delayedJob = DelayedJob::create();
$job = new ExportAllOrganisationsJob(
$delayedJob->id,
$filename
);
dispatch($job);

return (new DelayedJobResource($delayedJob))->additional(['message' => "Export for organisations $filename is being processed"]);
} else {
file_put_contents($absolutePath, $binary_data);

return response()->download($absolutePath, $filename)->deleteFileAfterSend(true);
}
} catch (\Exception $e) {
Log::error('Error during export for organisations : ' . $e->getMessage());

return response()->json(['error' => 'An error occurred during organisations export'], 500);
}
}
}
20 changes: 20 additions & 0 deletions app/Http/Controllers/V2/Projects/AdminUpdateProjectController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace App\Http\Controllers\V2\Projects;

use App\Http\Controllers\Controller;
use App\Http\Requests\V2\Projects\AdminUpdateProjectRequest;
use App\Http\Resources\V2\Projects\ProjectResource;
use App\Models\V2\Projects\Project;

class AdminUpdateProjectController extends Controller
{
public function __invoke(Project $project, AdminUpdateProjectRequest $request): ProjectResource
{
$this->authorize('update', $project);

$project->update($request->validated());

return new ProjectResource($project);
}
}
Loading

0 comments on commit 7e29a10

Please sign in to comment.