Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HPC-9947: Add new plan element for plan caseload trend charts #1346

Merged
merged 1 commit into from
Mar 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,15 @@ place them in **_.docksal_/backups**
To import a snapshot and run all the steps that a deployment would run please
use this command:

fin post-deploy -i
fin deploy -i

If you have multiple database snapshots available locally, running this command
will let you select which one you want to import.
Running this without the _-i_ argument, will just run the deployment actions on
the current database without importing a snapshot.


Data migrations
DATA MIGRATIONS
---------------

The data migrations can be run locally with this command:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Drupal\ghi_base_objects\Entity;

use Drupal\ghi_base_objects\ApiObjects\Country;

/**
* Provides an interface for defining base object that have a focus country.
*
* @ingroup ghi_base_objects
*/
interface BaseObjectFocusCountryInterface {

/**
* Get the focus country for the plan.
*
* @return \Drupal\ghi_base_objects\Entity\BaseObjectInterface|null
* The country base object or NULL.
*/
public function getFocusCountry();

/**
* Get the focus country override for the plan.
*
* @return object|null
* A latLng object or NULL.
*/
public function getFocusCountryOverride();

/**
* Get the focus country map location for the plan.
*
* @return \Drupal\ghi_base_objects\ApiObjects\Country|null
* An object describing the map location or NULL.
*/
public function getFocusCountryMapLocation(?Country $default_country = NULL);

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Drupal\Core\Entity\EntityChangedInterface;

/**
* Provides an interface for defining Base object entities.
* Provides an interface for defining base object entities.
*
* @ingroup ghi_base_objects
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Drupal\ghi_base_objects\Entity;

/**
* Provides an interface for defining Base object entities.
* Provides an interface for defining base object entities with meta data.
*
* @ingroup ghi_base_objects
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ protected function setUp(): void {
public function testBaseObjectEditForm() {
$base_object = $this->createBaseObject([
'type' => 'plan',
'field_year' => 2025,
]);
$this->drupalGet($base_object->toUrl('edit-form')->toString());
$assert_session = $this->assertSession();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use Drupal\Core\Url;
use Drupal\KernelTests\KernelTestBase;
use Drupal\Tests\ghi_base_objects\Traits\BaseObjectTestTrait;
use Drupal\ghi_base_objects\Entity\BaseObjectType;

/**
* Tests the base object entity.
Expand Down Expand Up @@ -112,15 +111,11 @@ public function testBaseObjectSourceId() {
$this->assertEquals(20, $base_object->getSourceId());
$this->assertEquals('plan--20', $base_object->getUniqueIdentifier());

$base_object_type_incomplete = BaseObjectType::create([
'id' => $this->randomMachineName(),
'label' => $this->randomString(),
'hasYear' => FALSE,
]);
$base_object_type_incomplete = $this->createBaseObjectType();
$base_object = $this->createBaseObject([
'type' => $base_object_type_incomplete->id(),
'name' => 'base_object_name',
'field_original_id' => 20,
'field_original_id' => NULL,
]);
$this->assertNull($base_object->getSourceId());
}
Expand All @@ -129,20 +124,12 @@ public function testBaseObjectSourceId() {
* Tests base object needsYear() method.
*/
public function testBaseObjectNeedsYear() {
$base_object_type = $this->createBaseObjectType([
'hasYear' => FALSE,
]);
$base_object = $this->createBaseObject([
'type' => $base_object_type->id(),
]);
$base_object_type = $this->createBaseObjectType();
$base_object = $this->createBaseObject(['type' => $base_object_type->id()]);
$this->assertTrue($base_object->needsYear());

$base_object_type = $this->createBaseObjectType([
'hasYear' => TRUE,
]);
$base_object = $this->createBaseObject([
'type' => $base_object_type->id(),
]);
$base_object_type = $this->createBaseObjectType(['field_year' => 'Year']);
$base_object = $this->createBaseObject(['type' => $base_object_type->id()]);
$this->assertFalse($base_object->needsYear());
}

Expand All @@ -158,4 +145,28 @@ public function testBaseObjectCreatedTime() {
$this->assertEquals($timestamp, $base_object->getCreatedTime());
}

/**
* Tests base object created timestamps.
*/
public function testApiCacheTagsToInvalidate() {
$this->createBaseObjectType(['id' => 'custom_base_object_type']);
$base_object = $this->createBaseObject([
'type' => 'custom_base_object_type',
'field_original_id' => 20,
]);
$cache_tags = $base_object->getApiCacheTagsToInvalidate();
$this->assertNotEmpty($cache_tags);
$this->assertIsArray($cache_tags);
$this->assertArrayHasKey(0, $cache_tags);
$this->assertEquals('custom_base_object_type_id:20', $cache_tags[0]);

$base_object = $this->createBaseObject([
'type' => 'custom_base_object_type',
'field_original_id' => NULL,
]);
$cache_tags = $base_object->getApiCacheTagsToInvalidate();
$this->assertEmpty($cache_tags);
$this->assertIsArray($cache_tags);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Drupal\ghi_base_objects\Entity\BaseObjectInterface;
use Drupal\ghi_base_objects\Entity\BaseObjectType;
use Drupal\ghi_base_objects\Entity\BaseObjectTypeInterface;
use Drupal\Tests\field\Traits\EntityReferenceFieldCreationTrait;

/**
* Provides methods to create base objects in tests.
Expand All @@ -15,17 +16,21 @@
trait BaseObjectTestTrait {

use FieldTestTrait;
use EntityReferenceFieldCreationTrait;

/**
* Create a base object type.
*
* @param mixed[] $values
* (optional) Additional values for the base object type entity:
* (optional) Additional key-value pairs for the base object type entity:
* - id: The ID of the base object type. If none is provided, a random value
* will be used.
* - label: The human-readable label of the base object type. If none is
* provided, a random value will be used.
* - hasYear: Whether the base object type handles years already.
* - field_year: When not empty, this will create a year field with the
* provided label.
* - field_plan: When not empty, this will create a plan field with the
* provided label.
*
* @return \Drupal\ghi_base_objects\Entity\BaseObjectTypeInterface
* A base object type.
Expand All @@ -37,14 +42,25 @@ protected function createBaseObjectType(array $values = []) {
$values += [
'id' => $this->randomMachineName(),
'label' => $this->randomString(),
'hasYear' => FALSE,
'hasYear' => !empty($values['field_year']),
'field_year' => NULL,
'field_plan' => NULL,
];
$base_object_type = BaseObjectType::create($values);
$this->assertSame(SAVED_NEW, $base_object_type->save());
$this->assertInstanceOf(BaseObjectTypeInterface::class, $base_object_type);
$this->createField('base_object', $base_object_type->id(), 'integer', 'field_original_id', 'Source id');
if (!empty($values['hasYear'])) {
$this->createField('base_object', $base_object_type->id(), 'integer', 'field_year', 'Year');
$base_object_type = BaseObjectType::load($values['id']) ?: BaseObjectType::create($values);
if ($base_object_type->isNew()) {
$this->assertSame(SAVED_NEW, $base_object_type->save());
$this->assertInstanceOf(BaseObjectTypeInterface::class, $base_object_type);
$this->createField('base_object', $base_object_type->id(), 'integer', 'field_original_id', 'Source id');
if (!empty($values['field_year'])) {
$this->createField('base_object', $base_object_type->id(), 'integer', 'field_year', $values['field_year']);
}
if (!empty($values['field_plan'])) {
$this->createEntityReferenceField('base_object', $base_object_type->id(), 'field_plan', $values['field_plan'], 'base_object', 'default', [
'target_bundles' => [
'plan' => 'plan',
],
]);
}
}
return $base_object_type;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ public function hasDefaultTitle() {
/**
* Get the default title.
*
* @return string
* @return \Drupal\Core\StringTranslation\TranslatableMarkup|string
* The default title if one is set in the plugin definition.
*/
public function getDefaultTitle() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Drupal\ghi_blocks\Traits\GlobalSettingsTrait;
use Drupal\ghi_blocks\Traits\PlanFootnoteTrait;
use Drupal\ghi_blocks\Traits\TableSoftLimitTrait;
use Drupal\ghi_blocks\Traits\TableTrait;
use Drupal\ghi_plans\ApiObjects\Mocks\PlanOverviewPlanMock;
use Drupal\ghi_plans\Traits\FtsLinkTrait;
use Drupal\hpc_common\Helpers\ArrayHelper;
Expand Down Expand Up @@ -44,6 +45,7 @@ class PlanTable extends GHIBlockBase implements HPCDownloadExcelInterface, HPCDo
use GlobalPlanOverviewBlockTrait;
use GlobalSettingsTrait;
use PlanFootnoteTrait;
use TableTrait;
use TableSoftLimitTrait;
use BlockCommentTrait;
use FtsLinkTrait;
Expand Down Expand Up @@ -142,62 +144,22 @@ public function buildTableData($export = FALSE) {
$header += [
'name' => $this->t('Plans'),
'type' => $this->t('Plan type'),
'inneed' => [
'data' => $this->t('People in need'),
'data-column-type' => 'amount',
],
'targeted' => [
'data' => $this->t('People targeted'),
'data-column-type' => 'amount',
],
'expected_reach' => [
'data' => $this->t('Estimated Reach'),
'data-column-type' => 'amount',
],
'expected_reached' => [
'data' => $this->t('% Reached'),
'data-column-type' => 'amount',
],
'latest_reach' => [
'data' => $this->t('People reached'),
'data-column-type' => 'percentage',
],
'reached' => [
'data' => $this->t('% Reached'),
'data-column-type' => 'percentage',
],
'requirements' => [
'data' => $this->t('Requirements'),
'data-column-type' => 'currency',
],
'funding' => [
'data' => $this->t('Funding'),
'data-column-type' => 'currency',
],
'coverage' => [
'data' => $this->t('% Funded'),
'data-column-type' => 'percentage',
],
'status' => [
'data' => $this->t('Status'),
'data-column-type' => 'status',
'sortable' => FALSE,
],
'inneed' => $this->buildHeaderColumn($this->t('People in need'), 'amount'),
'targeted' => $this->buildHeaderColumn($this->t('People targeted'), 'amount'),
'expected_reach' => $this->buildHeaderColumn($this->t('Estimated Reach'), 'amount'),
'expected_reached' => $this->buildHeaderColumn($this->t('% Reached'), 'percentage'),
'latest_reach' => $this->buildHeaderColumn($this->t('People reached'), 'percentage'),
'reached' => $this->buildHeaderColumn($this->t('% Reached'), 'percentage'),
'requirements' => $this->buildHeaderColumn($this->t('Requirements'), 'currency'),
'funding' => $this->buildHeaderColumn($this->t('Funding'), 'currency'),
'coverage' => $this->buildHeaderColumn($this->t('% Funded'), 'percentage'),
'status' => $this->buildHeaderColumn($this->t('Status'), 'status'),
];
if ($export) {
$header['in_gho'] = $this->t('In GHO');
$header['document'] = [
'data' => $this->t('Document'),
'data-column-type' => 'document',
];
$header['link_ha'] = [
'data' => $this->t('Link to HA page'),
'data-column-type' => 'document',
];
$header['link_fts'] = [
'data' => $this->t('Link to FTS page'),
'data-column-type' => 'document',
];
$header['document'] = $this->buildHeaderColumn($this->t('Document'), 'document');
$header['link_ha'] = $this->buildHeaderColumn($this->t('Link to HA page'), 'document');
$header['link_fts'] = $this->buildHeaderColumn($this->t('Link to FTS page'), 'document');
}

$cache_tags = [];
Expand Down Expand Up @@ -241,19 +203,15 @@ public function buildTableData($export = FALSE) {
$document_uri = $plan->getPlanDocumentUri();

// Setup the column values.
$value_in_need = $in_need ? [
$value_in_need = [
'#theme' => 'hpc_amount',
'#amount' => $in_need,
'#amount' => $in_need ?: '-',
'#decimals' => $decimals,
] : [
'#markup' => '-',
];
$value_targeted = $target ? [
$value_targeted = [
'#theme' => 'hpc_amount',
'#amount' => $target,
'#amount' => $target ?: '-',
'#decimals' => $decimals,
] : [
'#markup' => '-',
];
$value_expected_reach = [
'#theme' => 'hpc_amount',
Expand All @@ -264,12 +222,10 @@ public function buildTableData($export = FALSE) {
'#theme' => 'hpc_percent',
'#ratio' => $expected_reached / 100,
];
$value_latest_reached = $latest_reached !== NULL ? [
$value_latest_reached = [
'#theme' => 'hpc_amount',
'#amount' => $latest_reached,
'#amount' => $latest_reached ?? $this->t('Pending'),
'#decimals' => $decimals,
] : [
'#markup' => $this->t('Pending'),
];
$value_reached = $reached_percent ? [
'#theme' => 'hpc_percent',
Expand Down
Loading