Skip to content

Commit

Permalink
- [x] Change completeness logic
Browse files Browse the repository at this point in the history
- [x] Update unit tests for completeness
- [x] Fix completeness issues raised by QA
  • Loading branch information
PG-Momik committed Feb 3, 2025
1 parent a17d277 commit 828a4b6
Show file tree
Hide file tree
Showing 38 changed files with 3,761 additions and 1,832 deletions.
16 changes: 12 additions & 4 deletions app/Console/Commands/RefreshActivityElementCompleteness.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Exception;
use Illuminate\Console\Command;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;

/**
Expand Down Expand Up @@ -45,22 +46,29 @@ public function handle(): void
foreach ($activities as $activity) {
$this->info("Started for activity: $activity->id");

$activityElementNames = $activity->getAttributes();
$activityElementNames = getActivityAttributes();
$elementStatus = [];

foreach ($activityElementNames as $element => $value) {
foreach ($activityElementNames as $element) {
$methodName = dashesToCamelCase('is_' . $element . '_element_completed');

if (method_exists($elementCompleteService, $methodName)) {
$elementStatus[$element] = $elementCompleteService->$methodName($activity);
if ($element === 'reporting_org') {
$organization = $activity->organization;
$elementStatus[$element] = Arr::get($organization, 'element_status.reporting_org', false);
} else {
$elementStatus[$element] = $elementCompleteService->$methodName($activity);
}
}
}

$elementStatus['result'] = $elementCompleteService->isResultElementCompleted($activity);
$elementStatus['transactions'] = $elementCompleteService->isTransactionsElementCompleted($activity);

$complete_percentage = $elementCompleteService->calculateCompletePercentage($elementStatus);

$activity->timestamps = false;
$activity->updateQuietly(['element_status' => $elementStatus]);
$activity->updateQuietly(['element_status' => $elementStatus, 'complete_percentage' => $complete_percentage]);

$this->info("Completed for activity: $activity->id");
$this->info('---------------------------------------');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use App\CsvImporter\Entities\Activity\Components\Factory\Validation;
use App\Http\Requests\Activity\DefaultAidType\DefaultAidTypeRequest;
use App\IATI\Traits\DataSanitizeTrait;
use Illuminate\Support\Arr;

/**
* Class DefaultAidType.
Expand Down Expand Up @@ -137,8 +138,8 @@ protected function setDefaultAidTypeCode($key, $value, $index): void
}

if ($key === $this->_csvHeaders[1]) {
$defaultAidTypeVocabulary = $this->data['default_aid_type'][$index]['default_aid_type_vocabulary'] ?? '';
$defaultAidTypeVocabulary = empty($defaultAidTypeVocabulary) ?: (int) $defaultAidTypeVocabulary;
$accessKey = "default_aid_type.$index.default_aid_type_vocabulary";
$defaultAidTypeVocabulary = Arr::get($this->data, $accessKey, '1');
$value = is_null($value) ? '' : trim($value);

switch ($defaultAidTypeVocabulary) {
Expand Down
95 changes: 63 additions & 32 deletions app/CsvImporter/Entities/Activity/Components/Elements/Sector.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ public function prepare($fields): void
* @param $index
*
* @return void
* @throws \JsonException
*/
public function map($key, $value, $index): void
{
Expand Down Expand Up @@ -161,45 +162,48 @@ protected function setSectorVocabulary($key, $value, $index): void
/**
* Set sector code for Sector.
*
* @param $key
* @param $value
* @param $index
* This method handles setting the sector code based on the sector vocabulary.
*
* Extra condition:
* - Adds or unsets the 'text' key based on allowed sector vocabularies.
* - Allowed vocabularies: null, '', '3', '4', '5', '6', '9', '10', '11', '12', '98', '99'.
* - If the sector vocabulary is one of the allowed values, it makes sure 'text' key exists.
* - If the sector vocabulary is not allowed, it unsets the 'text' key.
*
* Based on the sector vocabulary, it performs different actions:
* - '1' -> Calls handleSectorVocabularyOne() to process value.
* - '2' -> Calls setSectorCategoryCode() to process value.
* - '7' -> Calls setSectorSdgGoal() to process value.
* - '8' -> Calls setSectorSdgTarget() to process value.
* - default -> Calls setSectorText() to process value.
*
* @param mixed $key The key for the sector field.
* @param mixed $value The value to be processed for the sector.
* @param int $index The index of the sector.
*
* @return void
* @throws \JsonException
*/
protected function setSectorCode($key, $value, $index): void
{
if (!isset($this->data['sector'][$index]['text'])) {
$this->data['sector'][$index]['text'] = '';
$accessKey = "sector.$index.sector_vocabulary";
$allowedVocabularies = [null, '', '3', '4', '5', '6', '9', '10', '11', '12', '98', '99'];
$sectorVocabulary = Arr::get($this->data, $accessKey);

if (!in_array($sectorVocabulary, $allowedVocabularies, true)) {
unset($this->data['sector'][$index]['text']);
} else {
$this->data['sector'][$index]['text'] = $this->data['sector'][$index]['text'] ?? '';
}

if ($key === $this->_csvHeaders[1]) {
$sectorVocabulary = Arr::get($this->data['sector'], $index . '.sector_vocabulary', null);

if ($sectorVocabulary === '1') {
$value = $value ? trim($value) : $value;
$this->codes[] = $value;
$validSectorCode = $this->loadCodeList('SectorCode');

if ($value) {
foreach ($validSectorCode as $code => $name) {
if (strcasecmp($value, $name) === 0) {
$value = (string) $code;
break;
}
}
}

$this->data['sector'][$index]['code'] = $value;
} elseif ($sectorVocabulary === '2') {
$this->setSectorCategoryCode($value, $index);
} elseif ($sectorVocabulary === '7') {
$this->setSectorSdgGoal($value, $index);
} elseif ($sectorVocabulary === '8') {
$this->setSectorSdgTarget($value, $index);
} else {
$this->setSectorText($value, $index);
}
match ($sectorVocabulary) {
'1' => $this->handleSectorVocabularyOne($value, $index),
'2' => $this->setSectorCategoryCode($value, $index),
'7' => $this->setSectorSdgGoal($value, $index),
'8' => $this->setSectorSdgTarget($value, $index),
default => $this->setSectorText($value, $index),
};
}
}

Expand All @@ -219,6 +223,33 @@ protected function setVocabularyUri($key, $value, $index): void
}
}

/**
* Handle for sector vocab 1.
*
* @param $value
* @param $index
*
* @return void
* @throws \JsonException
*/
protected function handleSectorVocabularyOne($value, $index): void
{
$value = $value ? trim($value) : $value;
$this->codes[] = $value;
$validSectorCode = $this->loadCodeList('SectorCode');

if ($value) {
foreach ($validSectorCode as $code => $name) {
if (strcasecmp($value, $name) === 0) {
$value = (string) $code;
break;
}
}
}

$this->data['sector'][$index]['code'] = $value;
}

/**
* Set sector category code for Sector.
*
Expand Down Expand Up @@ -301,7 +332,7 @@ protected function setSectorSdgTarget($value, $index): void
*/
protected function setSectorText($value, $index): void
{
($value) ?: $value = '';
$value = $value ?: '';
$this->codes[] = $value;
$this->data['sector'][$index]['text'] = $value;
}
Expand Down
69 changes: 44 additions & 25 deletions app/CsvImporter/Entities/Activity/Components/Elements/Tag.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,44 +136,63 @@ protected function setTagVocabulary($key, $value, $index): void
*/
protected function setTagCode($key, $value, $index): void
{
if (!isset($this->data['tag'][$index]['tag_text'])) {
$this->data['tag'][$index]['tag_text'] = '';
}

if ($key === $this->_csvHeaders[1]) {
if (!isset($this->data['tag'][$index]['tag_text'])) {
$this->data['tag'][$index]['tag_text'] = '';
}

$tagVocabulary = $this->data['tag'][$index]['tag_vocabulary'] ?? '';
$value = (!$value) ? '' : trim((string) $value);

if ($tagVocabulary === '2') {
$validTagCode = $this->loadCodeList('UNSDG-Goals');
switch ($tagVocabulary) {
case '2':
$validTagCode = $this->loadCodeList('UNSDG-Goals');

if ($value) {
foreach ($validTagCode as $code => $name) {
if (strcasecmp($value, $name) === 0) {
$value = (string) $code;
break;
if ($value) {
foreach ($validTagCode as $code => $name) {
if (strcasecmp($value, $name) === 0) {
$value = (string) $code;
break;
}
}
}
}

$this->data['tag'][$index]['goals_tag_code'] = $value;
} elseif ($tagVocabulary === '3') {
$validTagCode = $this->loadCodeList('UNSDG-Targets');
$this->data['tag'][$index]['goals_tag_code'] = $value;
$fields = ['tag_vocabulary', 'goals_tag_code', 'narrative'];

break;
case '3':
$validTagCode = $this->loadCodeList('UNSDG-Targets');

if (!is_float($value)) {
foreach ($validTagCode as $code => $name) {
if (strcasecmp($value, $name) === 0) {
$value = is_float($code) ? (float) $code : $code;
break;
if (!is_float($value)) {
foreach ($validTagCode as $code => $name) {
if (strcasecmp($value, $name) === 0) {
$value = is_float($code) ? (float) $code : $code;
break;
}
}
}
}

$this->data['tag'][$index]['targets_tag_code'] = $value;
} else {
$this->data['tag'][$index]['tag_text'] = $value;
$this->data['tag'][$index]['tag_vocabulary'] = $tagVocabulary;
$this->data['tag'][$index]['targets_tag_code'] = $value;
$fields = ['tag_vocabulary', 'targets_tag_code', 'narrative'];

break;
case '1':
case '4':
$this->data['tag'][$index]['tag_text'] = $value;
$this->data['tag'][$index]['tag_vocabulary'] = $tagVocabulary;
$fields = ['tag_vocabulary', 'tag_text', 'narrative'];

break;
default:
$this->data['tag'][$index]['tag_text'] = $value;
$this->data['tag'][$index]['tag_vocabulary'] = $tagVocabulary;
$fields = ['tag_vocabulary', 'tag_text', 'narrative', 'vocabulary_uri'];

break;
}

$this->data['tag'][$index] = Arr::only($this->data['tag'][$index], $fields);
}
}

Expand Down
46 changes: 46 additions & 0 deletions app/Helpers/general.php
Original file line number Diff line number Diff line change
Expand Up @@ -1549,3 +1549,49 @@ function regroupResponseForAllActivity(array $response, array $uniqueIdentifiers

return $groupedResponses;
}

/**
* Returns array of activity element names in snake case.
* Making this instead of using $activity->getAttributes() method that laravel has because:
* There were case where I was not getting attributes reliably.
* Need this function when using ElementCompleteService::refreshElementStatus().
*
* @return string[]
*/
function getActivityAttributes(): array
{
return [
'iati_identifier',
'other_identifier',
'title',
'description',
'activity_status',
'activity_date',
'contact_info',
'activity_scope',
'participating_org',
'recipient_country',
'recipient_region',
'location',
'sector',
'country_budget_items',
'humanitarian_scope',
'policy_marker',
'collaboration_type',
'default_flow_type',
'default_finance_type',
'default_aid_type',
'default_tied_status',
'budget',
'planned_disbursement',
'capital_spend',
'document_link',
'related_activity',
'legacy_data',
'conditions',
'tag',
'reporting_org',
'transactions',
'result',
];
}
4 changes: 2 additions & 2 deletions app/Http/Controllers/Admin/Activity/ActivityController.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public function index(): View|JsonResponse
$settingsDefaultValue = $this->settingService->getSetting()->default_values ?? [];
$defaultLanguage = getDefaultValue($settingsDefaultValue, 'language', 'Activity/Language.json' ?? []);

// User onboarding part
/** User onboarding part */
$organization = Auth::user()->organization;
$organizationOnboarding = $this->organizationOnboardingService->getOrganizationOnboarding($organization->id);
$isFirstTime = false;
Expand Down Expand Up @@ -203,7 +203,7 @@ public function store(ActivityCreateRequest $request): JsonResponse
'data' => $activity,
]);
} catch (Exception $e) {
logger()->error($e->getMessage());
logger()->error($e);

return response()->json(['success' => false, 'message' => 'Error has occurred while saving activity.', 'data' => []]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ public function destroy($id, $transactionId): JsonResponse
try {
$this->transactionService->deleteTransaction($transactionId);

$activity = $this->activityService->getActivity($id);
Session::flash('success', 'Transaction Deleted Successfully');

return response()->json([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,10 @@ public function getGroupedCountryCode($formFields): array
return [];
}

$column = array_map(function ($item) {
return $item ?? '';
}, $column);

$counted = !empty($column) ? array_count_values($column) : [];
$duplicates = array_filter($counted, static function ($value) {
return $value > 1;
Expand Down
Loading

0 comments on commit 828a4b6

Please sign in to comment.