Skip to content

Commit

Permalink
Merge pull request #715 from wri/feat/TM-1718-jobs-demographics
Browse files Browse the repository at this point in the history
[TM-1718] Convert jobs data to the Demographics tables
  • Loading branch information
roguenet authored Feb 26, 2025
2 parents a2957a7 + fe1a5c3 commit a030114
Show file tree
Hide file tree
Showing 24 changed files with 264 additions and 627 deletions.
152 changes: 152 additions & 0 deletions app/Console/Commands/OneOff/MigrateJobsToDemographics.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
<?php

namespace App\Console\Commands\OneOff;

use App\Models\V2\Demographics\Demographic;
use App\Models\V2\Projects\ProjectReport;
use Illuminate\Console\Command;

class MigrateJobsToDemographics extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'one-off:migrate-jobs-to-demographics';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Move jobs data to demographics';

protected const JOBS_MAPPING = [
'full-time' => [
'gender' => [
'male' => 'ft_men',
'female' => 'ft_women',
'non-binary' => 'ft_other',
],
'age' => [
'youth' => 'ft_youth',
'non-youth' => 'ft_jobs_non_youth',
],
'total' => 'ft_total',
],
'part-time' => [
'gender' => [
'male' => 'pt_men',
'female' => 'pt_women',
'non-binary' => 'pt_other',
],
'age' => [
'youth' => 'pt_youth',
'non-youth' => 'pt_non_youth',
],
'total' => 'pt_total',
],
];

protected const VOLUNTEERS_MAPPING = [
'volunteer' => [
'gender' => [
'male' => 'volunteer_men',
'female' => 'volunteer_women',
'non-binary' => 'volunteer_other',
],
'age' => [
'youth' => 'volunteer_youth',
'non-youth' => 'volunteer_non_youth',
],
'caste' => [
'marginalized' => 'volunteer_scstobc',
],
'total' => 'volunteer_total',
],
];

protected const MIGRATION_MAPPING = [
'jobs' => self::JOBS_MAPPING,
'volunteers' => self::VOLUNTEERS_MAPPING,
];

/**
* Execute the console command.
*/
public function handle()
{
$this->info('Moving project report jobs data to Demographics...');
$this->withProgressBar(ProjectReport::count(), function ($progressBar) {
ProjectReport::chunkById(100, function ($projectReports) use ($progressBar) {
foreach ($projectReports as $projectReport) {
$this->convertJobs($projectReport);
$progressBar->advance();
}
});
});

$this->info("\n\nCompleted moving project report jobs data to Demographics.");
}

private function convertJobs(ProjectReport $projectReport): void
{
foreach (self::MIGRATION_MAPPING as $demographicType => $mapping) {
foreach ($mapping as $collection => $types) {
/** @var Demographic $demographic */
$demographic = null;
foreach ($types as $type => $subtypes) {
if ($type == 'total') {
$field = $subtypes;
if ($demographic != null) {
// Make sure gender / age demographics are balanced and reach at least to the "_total" field
// for this type of job from the original report. Pad gender and age demographics with an
// "unknown" if needed.
$genderTotal = $demographic->entries()->gender()->sum('amount');
$ageTotal = $demographic->entries()->age()->sum('amount');
$targetTotal = max($genderTotal, $ageTotal, $projectReport[$field]);
if ($genderTotal < $targetTotal) {
$demographic->entries()->create([
'type' => 'gender',
'subtype' => 'unknown',
'amount' => $targetTotal - $genderTotal,
]);
}
if ($ageTotal < $targetTotal) {
$demographic->entries()->create([
'type' => 'age',
'subtype' => 'unknown',
'amount' => $targetTotal - $ageTotal,
]);
}
}
} else {
// If none of the fields for this type exist, skip
$fields = collect(array_values($subtypes));
if ($fields->first(fn ($field) => $projectReport[$field] > 0) == null) {
continue;
}

if ($demographic == null) {
$demographic = $projectReport->demographics()->create([
'type' => $demographicType,
'collection' => $collection,
]);
}
foreach ($subtypes as $subtype => $field) {
$value = $projectReport[$field];
if ($value > 0) {
$demographic->entries()->create([
'type' => $type,
'subtype' => $subtype,
'amount' => $value,
]);
}
}
}
}
}
}
}
}
4 changes: 3 additions & 1 deletion app/Exports/V2/BaseExportFormSubmission.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ protected function getAnswer(array $field, array $answers, ?string $frameworkKey

case 'workdays':
case 'restorationPartners':
case 'jobs':
case 'volunteers':
$list = [];
$demographic = $answer->first();
if ($demographic == null) {
Expand All @@ -88,7 +90,7 @@ protected function getAnswer(array $field, array $answers, ?string $frameworkKey
$list[] = 'age:(' . implode(')(', $types['age']) . ')';
if ($frameworkKey == 'hbf') {
$list[] = 'caste:(' . implode(')(', $types['caste']) . ')';
} else {
} elseif ($field['input_type'] == 'workdays' || $field['input_type'] == 'restorationPartners') {
$list[] = 'ethnicity:(' . implode(')(', $types['ethnicity']) . ')';
}

Expand Down

This file was deleted.

24 changes: 0 additions & 24 deletions app/Http/Resources/V2/ProjectReports/ProjectReportResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ public function toArray($request)
'due_at' => $this->due_at,
'completion' => $this->completion,
'readable_completion_status' => $this->readable_completion_status,
'workdays_paid' => $this->workdays_paid,
'workdays_volunteer' => $this->workdays_volunteer,
'total_unique_restoration_partners' => $this->total_unique_restoration_partners,
'direct_restoration_partners' => $this->direct_restoration_partners,
'indirect_restoration_partners' => $this->indirect_restoration_partners,
Expand All @@ -42,35 +40,18 @@ public function toArray($request)
'pct_survival_to_date' => $this->pct_survival_to_date,
'survival_calculation' => $this->survival_calculation,
'survival_comparison' => $this->survival_comparison,
'ft_women' => $this->ft_women,
'ft_men' => $this->ft_men,
'ft_youth' => $this->ft_youth,
'ft_smallholder_farmers' => $this->ft_smallholder_farmers,
'ft_total' => $this->ft_total,
'pt_non_youth' => $this->pt_non_youth,
'pt_women' => $this->pt_women,
'pt_men' => $this->pt_men,
'pt_youth' => $this->pt_youth,
'pt_smallholder_farmers' => $this->pt_smallholder_farmers,
'pt_total' => $this->pt_total,
'workdays_total' => $this->workdays_total,
'seasonal_women' => $this->seasonal_women,
'seasonal_men' => $this->seasonal_men,
'seasonal_youth' => $this->seasonal_youth,
'seasonal_smallholder_farmers' => $this->seasonal_smallholder_farmers,
'seasonal_total' => $this->seasonal_total,
'volunteer_women' => $this->volunteer_women,
'volunteer_men' => $this->volunteer_men,
'volunteer_youth' => $this->volunteer_youth,
'volunteer_smallholder_farmers' => $this->volunteer_smallholder_farmers,
'volunteer_total' => $this->volunteer_total,
'shared_drive_link' => $this->shared_drive_link,
'planted_trees' => $this->planted_trees,
'new_jobs_description' => $this->new_jobs_description,
'volunteers_work_description' => $this->volunteers_work_description,
'ft_jobs_non_youth' => $this->ft_jobs_non_youth,
'ft_jobs_youth' => $this->ft_jobs_youth,
'volunteer_non_youth' => $this->volunteer_non_youth,
'beneficiaries' => $this->beneficiaries,
'beneficiaries_description' => $this->beneficiaries_description,
'beneficiaries_women' => $this->beneficiaries_women,
Expand All @@ -87,7 +68,6 @@ public function toArray($request)
'project' => new ProjectLiteResource($this->project),
'site_reports_count' => $this->site_reports_count,
'nursery_reports_count' => $this->nursery_reports_count,
'total_jobs_created' => $this->total_jobs_created,
'task_uuid' => $this->task_uuid,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
Expand All @@ -113,7 +93,6 @@ public function toArray($request)
'convergence_schemes' => $this->convergence_schemes,
'convergence_amount' => $this->convergence_amount,
'community_partners_assets_description' => $this->community_partners_assets_description,
'volunteer_scstobc' => $this->volunteer_scstobc,
'beneficiaries_scstobc_farmers' => $this->beneficiaries_scstobc_farmers,
'beneficiaries_scstobc' => $this->beneficiaries_scstobc,
'people_knowledge_skills_increased' => $this->people_knowledge_skills_increased,
Expand All @@ -124,9 +103,6 @@ public function toArray($request)
'non_tree_total' => $this->non_tree_total,
'total_community_partners' => $this->total_community_partners,
'business_milestones' => $this->business_milestones,
'ft_other' => $this->ft_other,
'pt_other' => $this->pt_other,
'volunteer_other' => $this->volunteer_other,
'beneficiaries_other' => $this->beneficiaries_other,
'beneficiaries_training_women' => $this->beneficiaries_training_women,
'beneficiaries_training_men' => $this->beneficiaries_training_men,
Expand Down
3 changes: 0 additions & 3 deletions app/Http/Resources/V2/SiteReports/SiteReportResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ public function toArray($request)
'nothing_to_report' => $this->nothing_to_report,

'title' => $this->title,
'workdays_paid' => $this->workdays_paid,
'workdays_volunteer' => $this->workdays_volunteer,
'seeds_planted' => $this->seeds_planted,
'technical_narrative' => $this->technical_narrative,
'public_narrative' => $this->public_narrative,
Expand All @@ -40,7 +38,6 @@ public function toArray($request)
'polygon_status' => $this->polygon_status,
'paid_other_activity_description' => $this->paid_other_activity_description,

'total_workdays_count' => $this->total_workdays_count,
'total_trees_planted_count' => $this->total_trees_planted_count,
'total_seeds_planted_count' => $this->total_seeds_planted_count,

Expand Down
10 changes: 10 additions & 0 deletions app/Models/Traits/HasDemographics.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ trait HasDemographics
'workdaysConvergenceTotal' => ['type' => Demographic::WORKDAY_TYPE, 'collections' => 'convergence'],
'directRestorationPartners' => ['type' => Demographic::RESTORATION_PARTNER_TYPE, 'collections' => 'direct'],
'indirectRestorationPartners' => ['type' => Demographic::RESTORATION_PARTNER_TYPE, 'collections' => 'indirect'],
'jobsFullTimeTotal' => ['type' => Demographic::JOBS_TYPE, 'collections' => 'full-time'],
'jobsPartTimeTotal' => ['type' => Demographic::JOBS_TYPE, 'collections' => 'part-time'],
'volunteersTotal' => ['type' => Demographic::VOLUNTEERS_TYPE, 'collections' => 'volunteer'],
];

public static function bootHasDemographics()
Expand All @@ -40,6 +43,13 @@ public static function bootHasDemographics()
$collectionSets['direct'],
$collectionSets['indirect'],
])->flatten(),
Demographic::JOBS_TYPE => collect([
$collectionSets['full-time'],
$collectionSets['part-time'],
])->flatten(),
Demographic::VOLUNTEERS_TYPE => collect([
$collectionSets['volunteer'],
])->flatten(),
default => throw new InternalErrorException("Unrecognized demographic type: $demographicType"),
};
$collections->each(function ($collection) use ($attributePrefix) {
Expand Down
2 changes: 2 additions & 0 deletions app/Models/Traits/UsesLinkedFields.php
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,8 @@ private function syncRelation(string $property, string $inputType, $data, bool $
'disturbances',
'workdays',
'restorationPartners',
'jobs',
'volunteers',
'stratas',
'invasive',
'seedings',
Expand Down
10 changes: 9 additions & 1 deletion app/Models/V2/Demographics/Demographic.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ class Demographic extends Model implements HandlesLinkedFieldSync

public const WORKDAY_TYPE = 'workdays';
public const RESTORATION_PARTNER_TYPE = 'restoration-partners';
public const JOBS_TYPE = 'jobs';
public const VOLUNTEERS_TYPE = 'volunteers';

public const VALID_TYPES = [self::WORKDAY_TYPE, self::RESTORATION_PARTNER_TYPE];
public const VALID_TYPES = [self::WORKDAY_TYPE, self::RESTORATION_PARTNER_TYPE, self::JOBS_TYPE, self::VOLUNTEERS_TYPE];

// In TM-1681 we moved several "name" values to "subtype". This check helps make sure that both in-flight
// work at the time of release, and updates from update requests afterward honor that change.
Expand Down Expand Up @@ -191,6 +193,12 @@ public function getReadableCollectionAttribute(): ?string
SiteReport::class => DemographicCollections::WORKDAYS_SITE_COLLECTIONS,
default => null
},
self::JOBS_TYPE => match ($this->demographical_type) {
ProjectReport::class => DemographicCollections::JOBS_PROJECT_COLLECTIONS,
},
self::VOLUNTEERS_TYPE => match ($this->demographical_type) {
ProjectReport::class => DemographicCollections::VOLUNTEERS_PROJECT_COLLECTIONS,
},
default => null
};
if (empty($collections)) {
Expand Down
14 changes: 14 additions & 0 deletions app/Models/V2/Demographics/DemographicCollections.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,18 @@ class DemographicCollections
self::DIRECT_OTHER => 'Direct Other',
self::INDIRECT_OTHER => 'Indirect Other',
];

public const FULL_TIME = 'full-time';
public const PART_TIME = 'part-time';

public const JOBS_PROJECT_COLLECTIONS = [
self::FULL_TIME => 'Full-time',
self::PART_TIME => 'Part-time',
];

public const VOLUNTEER = 'volunteer';

public const VOLUNTEERS_PROJECT_COLLECTIONS = [
self::VOLUNTEER => 'Volunteer',
];
}
Loading

0 comments on commit a030114

Please sign in to comment.