From c7b5ab9f3242fcffdc37cd6bc3d1ffc7ae6f8598 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Fri, 1 Dec 2023 19:57:05 +1300 Subject: [PATCH] Attempt at adding is_new to membership status --- CRM/Member/BAO/MembershipStatus.php | 19 ++++++ .../MembershipStatusGetSpecProvider.php | 65 +++++++++++++++++++ .../phpunit/api/v4/Entity/MembershipTest.php | 35 ++++++++++ 3 files changed, 119 insertions(+) create mode 100644 ext/civi_member/Civi/Api4/Service/Spec/Provider/MembershipStatusGetSpecProvider.php diff --git a/CRM/Member/BAO/MembershipStatus.php b/CRM/Member/BAO/MembershipStatus.php index 48175688ff..f85fec9cec 100644 --- a/CRM/Member/BAO/MembershipStatus.php +++ b/CRM/Member/BAO/MembershipStatus.php @@ -339,4 +339,23 @@ class CRM_Member_BAO_MembershipStatus extends CRM_Member_DAO_MembershipStatus im return $statusIds; } + /** + * Get the id of the status to be used for new memberships. + * + * @return int + * @throws \CRM_Core_Exception + */ + public static function getNewMembershipTypeID(): int { + $cacheKey = __CLASS__ . __FUNCTION__; + if (!isset(\Civi::$statics[$cacheKey])) { + \Civi::$statics[$cacheKey] = (bool) CRM_Core_DAO::singleValueQuery( + 'SELECT id FROM civicrm_membership_status + WHERE start_event = "join_date" + AND start_event_adjust_unit IS NULL + ORDER BY weight LIMIT 1' + ); + } + return \Civi::$statics[$cacheKey]; + } + } diff --git a/ext/civi_member/Civi/Api4/Service/Spec/Provider/MembershipStatusGetSpecProvider.php b/ext/civi_member/Civi/Api4/Service/Spec/Provider/MembershipStatusGetSpecProvider.php new file mode 100644 index 0000000000..83f52d42fa --- /dev/null +++ b/ext/civi_member/Civi/Api4/Service/Spec/Provider/MembershipStatusGetSpecProvider.php @@ -0,0 +1,65 @@ +addFieldSpec(new FieldSpec('is_new', 'Membership', 'Integer')); + $field = (new FieldSpec('is_new', 'Membership', 'Boolean')) + ->setTitle(ts('Is new membership status')) + ->setDescription(ts('Is this the status for new members')) + ->setInputType('Number') + ->setType('Extra') + ->setColumnName('id') + ->setSqlRenderer([__CLASS__, 'isNewMembership']); + $spec->addFieldSpec($field); + } + + /** + * When does this apply. + * + * @param string $entity + * @param string $action + * + * @return bool + */ + public function applies(string $entity, string $action): bool { + return $entity === 'MembershipStatus' && $action === 'get'; + } + + /** + * Determine if the membership status is the status used for new memberships. + * + * @param array $id + * @param \Civi\Api4\Query\Api4SelectQuery $query + * return string + */ + public static function isNewMembership(array $fieldSpec, Api4SelectQuery $query): string { + $newID = \CRM_Member_BAO_MembershipStatus::getNewMembershipTypeID(); + return "IF ({id} = $newID, 1, 0)"; + } + +} diff --git a/tests/phpunit/api/v4/Entity/MembershipTest.php b/tests/phpunit/api/v4/Entity/MembershipTest.php index c94f99f651..48caa0298a 100644 --- a/tests/phpunit/api/v4/Entity/MembershipTest.php +++ b/tests/phpunit/api/v4/Entity/MembershipTest.php @@ -21,13 +21,16 @@ namespace api\v4\Entity; use api\v4\Api4TestBase; use Civi\Api4\Contact; use Civi\Api4\Domain; +use Civi\Api4\Membership; use Civi\Api4\MembershipType; +use Civi\Test\EntityTrait; use Civi\Test\TransactionalInterface; /** * @group headless */ class MembershipTest extends Api4TestBase implements TransactionalInterface { + use EntityTrait; public function testUpdateWeights(): void { $getValues = function($domain) { @@ -85,4 +88,36 @@ class MembershipTest extends Api4TestBase implements TransactionalInterface { $this->assertEquals('Rolling', $fields['period_type']['options'][0]['label']); } + public function testGetIsMembershipNew() : void { + $this->createTestEntity('MembershipType', [ + 'name' => 'General', + 'duration_unit' => 'year', + 'duration_interval' => 1, + 'period_type' => 'rolling', + 'member_of_contact_id' => 1, + 'domain_id' => 1, + 'financial_type_id' => 2, + 'is_active' => 1, + 'sequential' => 1, + 'visibility' => 'Public']); + $this->createTestEntity('Contact', ['first_name', 'Bob', 'contact_type' => 'Individual'], 1); + $this->createTestEntity('Contact', ['first_name', 'Bob too', 'contact_type' => 'Individual'], 2); + $this->createTestEntity('Membership', [ + 'contact_id' => $this->ids['Contact'][1], + 'start_date' => 'now', + 'membership_type_id:name' => 'General', + 'status_id:name' => 'New', + ], 1); + $this->createTestEntity('Membership', [ + 'contact_id' => $this->ids['Contact'][2], + 'start_date' => '4 months ago', + 'membership_type_id.name' => 'General', + 'status_id:name' => 'Current', + ], 2); + $memberships = Membership::get()->addSelect('status_id.is_new')->execute(); + $this->assertTrue($memberships[0]['is_new']); + $this->assertFalse($memberships[1]['is_new']); + } + + } -- 2.25.1