Commit 12f2be04 authored by mattwire's avatar mattwire
Browse files

Merge branch 'giftaid_updatedeclarations' into 'master'

3.4.1

See merge request extensions/ukgiftaid!10
parents d074cb30 89eb4657
......@@ -27,6 +27,18 @@ class CRM_Civigiftaid_Declaration {
* @throws \CiviCRM_API3_Exception
*/
public static function update($contributionID) {
// If declaration updated via contribution page etc. it will have been set in postProcess
$session = CRM_Core_Session::singleton();
if ($session->get('uktaxpayer', E::LONG_NAME)) {
$contactGiftAidEligibleStatus = $session->get('uktaxpayer', E::LONG_NAME);
}
// Get the gift aid eligible status
// If it's not a valid number don't do any further processing
if (!isset($contactGiftAidEligibleStatus)) {
return;
}
$contributionCustomGiftAidEligibleFieldName = CRM_Civigiftaid_Utils::getCustomByName('Eligible_for_Gift_Aid', 'Gift_Aid');
$contributionCustomGiftAidBatchNameFieldName = CRM_Civigiftaid_Utils::getCustomByName('Batch_Name', 'Gift_Aid');
......@@ -40,24 +52,14 @@ class CRM_Civigiftaid_Declaration {
]
]);
// If declaration updated via contribution page etc. it will have been set in postProcess
$session = CRM_Core_Session::singleton();
if ($session->get('uktaxpayer', E::LONG_NAME)) {
$contactGiftAidEligibleStatus = $session->get('uktaxpayer', E::LONG_NAME);
}
// Get the gift aid eligible status
// If it's not a valid number don't do any further processing
if (!isset($contactGiftAidEligibleStatus)) {
return;
}
list($addressDetails, $postCode) = self::getAddressAndPostalCode($contribution['contact_id']);
$startDate = $givenDate = $contribution['receive_date'];
$contactID = $contribution['contact_id'];
list($addressDetails, $postCode) = self::getAddressAndPostalCode($contactID);
$declarationParams = [
'entity_id' => $contribution['contact_id'],
'start_date' => CRM_Utils_Date::isoToMysql($contribution['receive_date']),
'given_date' => CRM_Utils_Date::isoToMysql($contribution['receive_date']),
'entity_id' => $contactID,
'start_date' => CRM_Utils_Date::isoToMysql($startDate),
'given_date' => CRM_Utils_Date::isoToMysql($givenDate),
'address' => $addressDetails,
'post_code' => $postCode,
'eligible_for_gift_aid' => $contactGiftAidEligibleStatus,
......@@ -208,7 +210,7 @@ class CRM_Civigiftaid_Declaration {
*
* @param array $params
*/
private static function insertDeclaration($params) {
public static function insertDeclaration($params) {
$cols = [
'entity_id' => 'Integer',
'eligible_for_gift_aid' => 'Integer',
......@@ -222,7 +224,7 @@ class CRM_Civigiftaid_Declaration {
'notes' => 'String',
];
if (CRM_Utils_Array::value('id', $params)) {
if (isset($params['id'])) {
// We will update an existing record.
$keyVals = [];
$queryParams[1] = [$params['id'], 'Integer'];
......@@ -231,7 +233,7 @@ class CRM_Civigiftaid_Declaration {
if (isset($params[$colName])) {
$keyVals[] = "{$colName}=%{$count}";
$queryParams[$count] = [
CRM_Utils_Array::value($colName, $params, ''),
$params[$colName] ?? '',
$colType
];
}
......@@ -249,10 +251,10 @@ class CRM_Civigiftaid_Declaration {
}
$count = 1;
foreach ($cols as $colName => $colType) {
$insertVals[$colName] = CRM_Utils_Array::value($colName, $params, '');
$insertVals[$colName] = $params[$colName] ?? '';
$values[] = "%{$count}";
$queryParams[$count] = [
CRM_Utils_Array::value($colName, $params, ''),
$params[$colName] ?? '',
$colType
];
$count++;
......@@ -476,6 +478,9 @@ class CRM_Civigiftaid_Declaration {
* @param int $contactID - the Individual for whom we retrieve declaration
* @param date $date - date for which we retrieve declaration (in ISO date format)
* - e.g. the date for which you would like to check if the contact has a valid declaration
* - If you pass NULL it will look for a declaration with date = now.
* - If you pass '' it will look for any declaration matching the contact ID.
* - The first declaration it finds will always be returned.
*
* @return array - declaration record as associative array, else empty array.
*/
......@@ -493,10 +498,13 @@ class CRM_Civigiftaid_Declaration {
// Note that a record with an end_date will be chosen over one with a NULL
// end_date, since ORDER BY end_date DESC will put NULL values last.
$currentDeclaration = [];
if (!empty($date)) {
$dateClause = "AND start_date <= %2 AND (end_date > %2 OR end_date IS NULL)";
}
$sql = "
SELECT id, entity_id, eligible_for_gift_aid, start_date, end_date, reason_ended, source, notes, address, post_code
FROM civicrm_value_gift_aid_declaration
WHERE entity_id = %1 AND start_date <= %2 AND (end_date > %2 OR end_date IS NULL)
WHERE entity_id = %1 {$dateClause}
ORDER BY end_date DESC";
$sqlParams = [
1 => [$contactID, 'Integer'],
......
......@@ -34,12 +34,15 @@ class CRM_Civigiftaid_Form_Task_AddToBatch extends CRM_Contribute_Form_Task {
public function preProcess() {
parent::preProcess();
// Generate Gift Aid batch name/title
$this->batchTitle = 'GiftAid ' . CRM_Batch_BAO_Batch::generateBatchName();
$this->batchName = CRM_Utils_String::titleToVar($this->batchTitle, 63);
if ($this->isSubmitted()) {
return;
}
list($totalContributionCount, $addedContributionIDs, $alreadyAddedContributionIDs, $notValidContributionIDs)
= CRM_Civigiftaid_Utils_Contribution::validateContributionToBatch($this->_contributionIds);
$session = new CRM_Core_Session();
......@@ -90,6 +93,12 @@ class CRM_Civigiftaid_Form_Task_AddToBatch extends CRM_Contribute_Form_Task {
public function postProcess() {
$batchParams = [];
// Get submitted Gift Aid batch title
if (isset($this->_submitValues['title'])) {
$this->batchTitle = $this->_submitValues['title'];
}
if (empty($this->batchTitle)) {
CRM_Core_Error::statusBounce('Missing name for new GiftAid batch - try creating the batch again?', NULL, 'GiftAid - Add to Batch');
}
......
......@@ -454,6 +454,7 @@ class CRM_Civigiftaid_Upgrader extends CRM_Civigiftaid_Upgrader_Base {
public function enable() {
$this->setOptionGroups();
$this->enableOptionGroups(1);
$this->ensureCustomGroups();
$this->ensureCustomFields();
}
......
......@@ -17,11 +17,6 @@ function _civicrm_api3_gift_aid_updateeligiblecontributions_spec(&$params) {
$params['contribution_id']['description'] = 'Optional contribution ID to update';
$params['contribution_id']['type'] = CRM_Utils_Type::T_INT;
$params['contribution_id']['api.required'] = FALSE;
$params['limit'] = [
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Limit number to process in one go'),
'description' => 'If there are a lot of contributions this can be quite intensive. Optionally limit the number to process in a batch and run this API call multiple times',
];
$params['recalculate_amount']['title'] = 'Recalculate amounts';
$params['recalculate_amount']['description'] = 'Recalculate Gift Aid amounts even if they already have the eligible flag set. This will not touch contributions already in a batch.';
$params['recalculate_amount']['type'] = CRM_Utils_Type::T_BOOLEAN;
......@@ -35,10 +30,11 @@ function _civicrm_api3_gift_aid_updateeligiblecontributions_spec(&$params) {
* @throws \CiviCRM_API3_Exception
*/
function civicrm_api3_gift_aid_updateeligiblecontributions($params) {
$customBatchName = CRM_Civigiftaid_Utils::getCustomByName('batch_name', 'Gift_Aid');
$customEligible = CRM_Civigiftaid_Utils::getCustomByName('Eligible_for_Gift_Aid', 'Gift_Aid');
$params['options']['limit'] = $params['options']['limit'] ?? 0;
$contributionParams = [
'return' => [
'id',
......@@ -48,7 +44,7 @@ function civicrm_api3_gift_aid_updateeligiblecontributions($params) {
$customBatchName,
$customEligible,
],
'options' => ['limit' => $params['limit'] ?? 0],
'options' => $params['options'],
];
if (empty($params['recalculate_amount'])) {
// Only retrieve contributions that do not have eligibility set
......@@ -66,15 +62,149 @@ function civicrm_api3_gift_aid_updateeligiblecontributions($params) {
return civicrm_api3_create_error('No contributions found or all have Eligible flag set!');
}
foreach ($contributions as $contributionID => $contributionDetail) {
// Check batch name here because it may be NULL or empty string and we can't check that using API3.
if (!empty($contributionDetail[$customBatchName])) {
// Contribution is part of a batch so we must not change/process it.
continue;
// Disable logging
$loggingSchema = new \CRM_Logging_Schema();
$loggingEnabled = $loggingSchema->isEnabled();
if ($loggingEnabled) {
$loggingSchema->disableLogging();
Civi::settings()->set('logging', '0');
}
try {
foreach ($contributions as $contributionID => $contributionDetail) {
// Check batch name here because it may be NULL or empty string and we can't check that using API3.
if (!empty($contributionDetail[$customBatchName])) {
// Contribution is part of a batch so we must not change/process it.
continue;
}
CRM_Civigiftaid_SetContributionGiftAidEligibility::setGiftAidEligibilityStatus($contributionID);
$updatedIDs[] = $contributionID;
}
}
finally {
// Re-enable logging
if ($loggingEnabled) {
$loggingSchema->enableLogging();
Civi::settings()->set('logging', '1');
}
CRM_Civigiftaid_SetContributionGiftAidEligibility::setGiftAidEligibilityStatus($contributionID);
$updatedIDs[] = $contributionID;
}
return civicrm_api3_create_success($updatedIDs ?? [], $params, 'GiftAid', 'updateeligiblecontributions');
}
function _civicrm_api3_gift_aid_updatedeclarations_spec(&$params) {
$params['contact_id']['title'] = 'Contact ID';
$params['start_date']['title'] = 'Declaration start date';
$params['start_date']['description'] = 'Start date - if not set defaults to existing date or contact created_date';
$params['given_date']['title'] = 'Declaration given date';
$params['given_date']['description'] = 'Given date - if not set defaults to existing date or start_date or contact created_date';
$params['source']['title'] = 'Source text';
$params['source']['description'] = 'Source text if existing declaration source text is empty.';
$params['has_start_date']['title'] = 'Existing declaration has start date?';
$params['has_start_date']['type'] = CRM_Utils_Type::T_BOOLEAN;
$params['has_start_date']['description'] = 'Choose whether to update declarations which have/have not a start_date set';
$params['has_start_date']['api.default'] = FALSE;
}
function civicrm_api3_gift_aid_updatedeclarations($params) {
if (empty($params['contact_id'])) {
$contacts = civicrm_api3('Contact', 'get', [
'return' => ["id"],
'contact_type' => "Individual",
'options' => $params['options'] ?? [],
'is_deleted' => 0,
])['values'];
$contactIDs = array_column($contacts, 'id');
}
elseif (isset($params['contact_id']['IN'])) {
$contactIDs = $params['contact_id']['IN'];
}
else {
$contactIDs[] = $params['contact_id'];
}
$startDate = '';
if (isset($params['start_date'])) {
$startDate = $params['start_date'];
}
if (isset($params['given_date'])) {
$givenDate = $params['given_date'];
}
// Disable logging
$loggingSchema = new \CRM_Logging_Schema();
$loggingEnabled = $loggingSchema->isEnabled();
if ($loggingEnabled) {
$loggingSchema->disableLogging();
Civi::settings()->set('logging', '0');
}
try {
foreach ($contactIDs as $contactID) {
list($addressDetails, $postCode) = CRM_Civigiftaid_Declaration::getAddressAndPostalCode($contactID);
$currentDeclaration = CRM_Civigiftaid_Declaration::getDeclaration($contactID, '');
if (empty($currentDeclaration)) {
$updated['contactIDNoDeclaration'][] = $contactID;
continue;
}
// Check if we should update declaration based api param if it has a start date
if (empty($currentDeclaration['start_date'])) {
if ($params['has_start_date']) {
// Current declaration has no start date but we require one
$updated['contactIDSkippedNoStartDate'][] = $contactID;
continue;
}
}
elseif (!empty($currentDeclaration['start_date'])) {
if (!$params['has_start_date']) {
// Current declaration has a start date and we are only updating ones that don't
$updated['contactIDSkippedHasStartDate'][] = $contactID;
continue;
}
}
if (!empty($currentDeclaration['given_date'])) {
$givenDate = $currentDeclaration['given_date'];
}
if (!empty($currentDeclaration['start_date'])) {
$startDate = $currentDeclaration['start_date'];
}
elseif (empty($currentDeclaration['start_date']) && empty($startDate)) {
// Set start date to contact create date
$startDate = civicrm_api3('Contact', 'getvalue', [
'id' => $contactID,
'return' => 'created_date'
]);
}
if (empty($givenDate)) {
$givenDate = $startDate;
}
$declarationParams = [
'id' => $currentDeclaration['id'],
'entity_id' => $contactID,
'start_date' => CRM_Utils_Date::isoToMysql($startDate),
'given_date' => CRM_Utils_Date::isoToMysql($givenDate),
'address' => $addressDetails,
'post_code' => $postCode,
];
if (empty($currentDeclaration['source']) && isset($params['source'])) {
$declarationParams['source'] = $params['source'];
}
CRM_Civigiftaid_Declaration::insertDeclaration($declarationParams);
$updated['contactIDs'][] = $contactID;
}
}
finally {
// Re-enable logging
if ($loggingEnabled) {
$loggingSchema->enableLogging();
Civi::settings()->set('logging', '1');
}
}
return civicrm_api3_create_success($updated, $params, 'GiftAid', 'Updatedeclarations');
}
......@@ -2,6 +2,8 @@
## GiftAid
You can use the `limit` and `offset` API3 options to control how many entities these APIs will process each run.
### Update Eligible Contributions
GiftAid.updateeligiblecontributions - API to set "Eligible for Gift Aid" on all contributions where
it was not previously set.
......@@ -14,7 +16,19 @@ Note that a contribution's eligibility is based on the financial types of the li
#### Parameters
- `contribution_id` (int): Contribution ID: Optional contribution ID to update.
- `limit` (int): Limit number to process in one go: If there are a lot of contributions this can be quite intensive. Optionally limit the number to process in a batch and run this API call multiple times.
- `recalculate_amount` (bool): Recalculate amounts:
- If missing/false (default), only calculate amounts (and eligibility) for contributions that do not have eligibility known.
- If true, recalculate Gift Aid amounts (but not eligibility) for contributions that have the eligible flag set.
### Update Declarations
GiftAid.updatedeclarations - API to update existing declarations that may be invalid (eg. were imported, missing address etc.).
!! note
This API only updates the first declaration for a contact
#### Parameters
- `contact_id` (int/array): Contact IDs to check and update declarations. Use the API3 ['IN' => [123,223]] format for multiple contact IDs.
- `start_date` (string): Declaration start date - if not set defaults to existing date or contact created_date.
- `given_date` (string): Declaration given date - if not set defaults to existing date or start_date or contact created_date.
- `source` (string): Source text if existing declaration source text is empty.
- `has_start_date` (bool): Existing declaration has start date? Choose whether to update declarations which have/have not a start_date set. This is useful for updating ones with a start_date differently to ones without (eg. adding different source text).
## Release 3.4.1
* Add GiftAid.Updatedeclarations API
* Use title that user entered when adding to batch
* Disable logging when fixing declarations/contributions via API
* Fix crash with disable then enable extension
## Release 3.4
This release adds unit tests, fixes multiple issues, improves documentation and adds a field "Given Date" to the declaration.
......
......@@ -18,8 +18,8 @@
<author>MJW Consulting, Rich Lott (Artful Robot) Erawat Chamanont, Jamie Novick, Guanhuan Chen, Robin Mitra</author>
<email>mjw@mjwconsult.co.uk, https://artfulrobot.uk, jamie@compucorp.co.uk, guanhuan@compucorp.co.uk</email>
</maintainer>
<releaseDate>2020-06-05</releaseDate>
<version>3.4</version>
<releaseDate>2020-07-08</releaseDate>
<version>3.4.1</version>
<develStage>stable</develStage>
<compatibility>
<ver>5.24</ver>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment