-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
880 additions
and
167 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
<?php | ||
|
||
use Civi\Api4\PriceFieldValue; | ||
use Civi\Api4\SavedSearch; | ||
use Civi\Api4\SearchDisplay; | ||
use Civi\Core\Event\GenericHookEvent; | ||
use Symfony\Component\EventDispatcher\EventSubscriberInterface; | ||
|
||
use CRM_Membershiputils_ExtensionUtil as E; | ||
|
||
class CRM_Membershiputils_ProcessHooks implements EventSubscriberInterface { | ||
|
||
const comparisonSearch = 'Excluded_from_Renewal'; | ||
|
||
protected CRM_Core_Form $form; | ||
|
||
protected array $type_ids; | ||
|
||
public static function getSubscribedEvents(): array { | ||
return [ | ||
'hook_civicrm_buildForm' => 'buildForm', | ||
]; | ||
} | ||
|
||
protected function hasContactRenewed() { | ||
$contact = $this->form->getContactID(); | ||
|
||
$contacts_changed = SearchDisplay::run(FALSE) | ||
->setSavedSearch(self::comparisonSearch) | ||
->setFilters([ | ||
'contact_id' => $contact, | ||
'membership_type_id' => $this->type_ids, | ||
]) | ||
->execute(); | ||
|
||
return $contacts_changed->count() | ||
? ($contacts_changed->first()['data']['membership_type_id:label'] ?? TRUE) | ||
: FALSE; | ||
} | ||
|
||
protected function hasMembershipPriceFields(): bool { | ||
$priceSetID = $this->form->getPriceSetID() ?: 0; | ||
|
||
$this->type_ids = array_unique(array_map( | ||
fn($pfv) => $pfv['membership_type_id'], | ||
PriceFieldValue::get(FALSE) | ||
->addSelect('membership_type_id') | ||
->addWhere('price_field_id.price_set_id', '=', $priceSetID) | ||
->addWhere('membership_type_id', 'IS NOT EMPTY') | ||
->execute() | ||
->getArrayCopy() | ||
)); | ||
|
||
return count($this->type_ids) > 0; | ||
} | ||
|
||
public function validateForm(GenericHookEvent $event): void {} | ||
|
||
public function buildForm(GenericHookEvent $event): void { | ||
$this->form = &$event->form; | ||
|
||
if ($this->form instanceof CRM_Contribute_Form_Contribution_Main | ||
&& Civi::settings()->get('membershiputils_prevent_double_renewal')) { | ||
$this->buildForm_Contribute_Form_Contribution_main($event); | ||
} | ||
elseif ($this->form instanceof CRM_Admin_Form_Generic) { | ||
$this->buildForm_Admin_Form_Generic($event); | ||
} | ||
} | ||
|
||
public function buildForm_Contribute_Form_Contribution_main(GenericHookEvent $event): void { | ||
if (!$this->hasMembershipPriceFields()) { | ||
return; | ||
} | ||
|
||
$type = $this->hasContactRenewed(); | ||
|
||
if (!$type) { | ||
return; | ||
} | ||
|
||
if (is_array($type)) { | ||
$type = $type[0]; | ||
} | ||
|
||
throw new CRM_Core_Exception(E::ts( | ||
'A renewal has already been submitted for your %1 Membership', | ||
[1 => is_string($type) ? "<em>$type</em>" : ''] | ||
)); | ||
} | ||
|
||
public function buildForm_Admin_Form_Generic(GenericHookEvent $event): void { | ||
if (!$this->form->elementExists('membershiputils_prevent_double_renewal')) { | ||
return; | ||
} | ||
|
||
$field_prevent_double_renewal = $this->form->getElement('membershiputils_prevent_double_renewal'); | ||
|
||
$field_prevent_double_renewal->setComment( | ||
E::ts('When enabled, prevents Contribution Pages from loading that include Membership renewal if the using contact has a membership of one of the included types that has already been renewed. You can customise how it is determined that memberships have already been used by changing the parameters of the <a href="%1">Saved Search, "%2"</a>', | ||
$this->search_admin_params()) | ||
); | ||
} | ||
|
||
private function search_admin_params() { | ||
try { | ||
$excluded_from_renewal_search = SavedSearch::get(FALSE) | ||
->addWhere('name', '=', 'Excluded_from_Renewal') | ||
->addSelect('id', 'label') | ||
->execute(); | ||
|
||
if ($excluded_from_renewal_search->count()) { | ||
$excluded_from_renewal_search = $excluded_from_renewal_search->first(); | ||
return [ | ||
1 => CRM_Utils_System::url( | ||
'civicrm/admin/search', | ||
'', | ||
FALSE, | ||
'/edit/' . $excluded_from_renewal_search['id'], | ||
TRUE, | ||
FALSE, | ||
TRUE | ||
), | ||
2 => $excluded_from_renewal_search['label'], | ||
]; | ||
} | ||
} | ||
catch (Exception $e) { | ||
} | ||
|
||
return [ | ||
1 => CRM_Utils_System::url( | ||
'civicrm/admin/search', | ||
'', | ||
FALSE, | ||
'/list?tab=packaged', | ||
TRUE, | ||
FALSE, | ||
TRUE | ||
), | ||
2 => E::ts('Excluded from Renewal'), | ||
]; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
|
||
use CRM_Membershiputils_ExtensionUtil as E; | ||
|
||
use Civi\Core\Event\GenericHookEvent; | ||
use Symfony\Component\EventDispatcher\EventSubscriberInterface; | ||
|
||
class CRM_Membershiputils_ResourceHooks implements EventSubscriberInterface { | ||
|
||
/** | ||
* Returns an array of events this subscriber wants to listen to. | ||
* | ||
* @return array | ||
*/ | ||
public static function getSubscribedEvents() { | ||
return [ | ||
'hook_civicrm_pageRun' => 'pageRun', | ||
'hook_civicrm_buildForm' => 'buildForm', | ||
]; | ||
} | ||
|
||
private function addTypeChangeResources() { | ||
Civi::resources()->addVars('membershipUtils', [ | ||
'typeChangeMessage' => Civi::settings()->get('membershiputils_type_change_message'), | ||
'typeChangeNotification' => (bool) Civi::settings()->get('membershiputils_type_change_notification'), | ||
]); | ||
|
||
Civi::resources()->addScriptFile(E::LONG_NAME, 'js/typechange.js'); | ||
} | ||
|
||
public function pageRun(GenericHookEvent $event) { | ||
if ($event->page instanceof CRM_Contribute_Page_ContributionPage) { | ||
$this->addTypeChangeResources(); | ||
} | ||
} | ||
|
||
public function buildForm(GenericHookEvent $event) { | ||
if ($event->form instanceof CRM_Contribute_Form_Contribution_Main) { | ||
$this->addTypeChangeResources(); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
ang/afsearchMembersWhoHaveChangedTheirMembershipType.aff.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<div af-fieldset="" af-title="Members who have changed their membership type"> | ||
<details class="af-container" af-title="Filters" open=""> | ||
<af-field name="Contact_ActivityContact_Activity_01.activity_date_time" defn="{input_type: 'Select', search_range: true, default_date_type: 'fixed', input_attrs: {}, afform_default: 'ending_60.day', options: [{id: '{}', label: 'Choose Date Range'}, {id: 'this.day', label: 'Today'}, {id: 'this.week', label: 'This week'}, {id: 'this.month', label: 'This calendar month'}, {id: 'this.quarter', label: 'This quarter'}, {id: 'this.fiscal_year', label: 'This fiscal year'}, {id: 'this.year', label: 'This calendar year'}, {id: 'previous.day', label: 'Yesterday'}, {id: 'previous.week', label: 'Previous week'}, {id: 'previous.month', label: 'Previous calendar month'}, {id: 'previous.quarter', label: 'Previous quarter'}, {id: 'previous.fiscal_year', label: 'Previous fiscal year'}, {id: 'previous.year', label: 'Previous calendar year'}, {id: 'ending.week', label: 'Last 7 days including today'}, {id: 'ending_30.day', label: 'Last 30 days including today'}, {id: 'ending_60.day', label: 'Last 60 days including today'}, {id: 'ending_90.day', label: 'Last 90 days including today'}, {id: 'ending.year', label: 'Last 12 months including today'}, {id: 'ending_2.year', label: 'Last 2 years including today'}, {id: 'ending_3.year', label: 'Last 3 years including today'}, {id: 'starting.day', label: 'Tomorrow'}, {id: 'next.week', label: 'Next week'}, {id: 'next.month', label: 'Next calendar month'}, {id: 'next.quarter', label: 'Next quarter'}, {id: 'next.fiscal_year', label: 'Next fiscal year'}, {id: 'next.year', label: 'Next calendar year'}, {id: 'starting.week', label: 'Next 7 days including today'}, {id: 'starting.month', label: 'Next 30 days including today'}, {id: 'starting_2.month', label: 'Next 60 days including today'}, {id: 'starting.quarter', label: 'Next 90 days including today'}, {id: 'starting.year', label: 'Next 12 months including today'}, {id: 'current.week', label: 'Current week to-date'}, {id: 'current.month', label: 'Current calendar month to-date'}, {id: 'current.quarter', label: 'Current quarter to-date'}, {id: 'current.year', label: 'Current calendar year to-date'}, {id: 'earlier.day', label: 'To end of yesterday'}, {id: 'earlier.week', label: 'To end of previous week'}, {id: 'earlier.month', label: 'To end of previous calendar month'}, {id: 'earlier.quarter', label: 'To end of previous quarter'}, {id: 'earlier.year', label: 'To end of previous calendar year'}, {id: 'greater.day', label: 'From start of current day'}, {id: 'greater.week', label: 'From start of current week'}, {id: 'greater.month', label: 'From start of current calendar month'}, {id: 'greater.quarter', label: 'From start of current quarter'}, {id: 'greater.year', label: 'From start of current calendar year'}, {id: 'less.week', label: 'To end of current week'}, {id: 'less.month', label: 'To end of current calendar month'}, {id: 'less.quarter', label: 'To end of current quarter'}, {id: 'less.year', label: 'To end of current calendar year'}, {id: 'previous_2.day', label: 'Previous 2 days'}, {id: 'previous_2.week', label: 'Previous 2 weeks'}, {id: 'previous_2.month', label: 'Previous 2 calendar months'}, {id: 'previous_2.quarter', label: 'Previous 2 quarters'}, {id: 'previous_2.year', label: 'Previous 2 calendar years'}, {id: 'previous_before.day', label: 'Day prior to yesterday'}, {id: 'previous_before.week', label: 'Week prior to previous week'}, {id: 'previous_before.month', label: 'Month prior to previous calendar month'}, {id: 'previous_before.quarter', label: 'Quarter prior to previous quarter'}, {id: 'previous_before.year', label: 'Year prior to previous calendar year'}, {id: 'greater_previous.week', label: 'From end of previous week'}, {id: 'greater_previous.month', label: 'From end of previous calendar month'}, {id: 'greater_previous.quarter', label: 'From end of previous quarter'}, {id: 'greater_previous.year', label: 'From end of previous calendar year'}, {id: 'previous_2.fiscal_year', label: 'Previous 2 fiscal years'}, {id: 'previous_before.fiscal_year', label: 'Fiscal year prior to previous fiscal year'}]}" /> | ||
<button class="af-button btn btn-warning" type="reset" crm-icon="fa-undo">Reset</button> | ||
</details> | ||
<crm-search-display-table search-name="Members_that_changed_type" display-name="Members_who_have_changed_type_Table_1"></crm-search-display-table> | ||
</div> |
15 changes: 15 additions & 0 deletions
15
ang/afsearchMembersWhoHaveChangedTheirMembershipType.aff.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
use CRM_Membershiputils_ExtensionUtil as E; | ||
|
||
return [ | ||
'type' => 'search', | ||
'title' => E::ts('Members who have changed their membership type'), | ||
'icon' => 'fa-list-alt', | ||
'server_route' => 'civicrm/member/type-changed-report', | ||
'permission' => [ | ||
'access CiviMember', | ||
], | ||
'search_displays' => [ | ||
'Members_that_changed_type.Members_who_have_changed_type_Table_1', | ||
], | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.