Skip to content

Commit

Permalink
fixed #514 (Merge remote-tracking branch 'origin/dev_514' into 1.2.x)
Browse files Browse the repository at this point in the history
  • Loading branch information
bjendres committed Oct 31, 2018
2 parents dafa999 + 0422674 commit 31daff9
Show file tree
Hide file tree
Showing 5 changed files with 748 additions and 99 deletions.
70 changes: 23 additions & 47 deletions CRM/Sepa/Logic/Group.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,56 +160,32 @@ static function received($txgroup_id) {
}

// step 1.1: fix contributions, that have no financial transactions. (happens due to a status-bug in civicrm)
$find_rotten_contributions_sql = "
SELECT
contribution.id AS contribution_id
FROM
civicrm_sdd_contribution_txgroup AS txn_to_contribution
LEFT JOIN
civicrm_contribution AS contribution ON contribution.id = txn_to_contribution.contribution_id
WHERE
txn_to_contribution.txgroup_id IN ($txgroup_id)
AND
contribution.id NOT IN (SELECT entity_id FROM civicrm_entity_financial_trxn WHERE entity_table='civicrm_contribution');
";
$rotten_contribution = CRM_Core_DAO::executeQuery($find_rotten_contributions_sql);
while ($rotten_contribution->fetch()) {
$contribution_id = $rotten_contribution->contribution_id;
// set these rotten contributions to 'Pending', no 'pay_later'
CRM_Core_DAO::executeQuery("UPDATE civicrm_contribution SET contribution_status_id=$status_pending, is_pay_later=0 WHERE id=$contribution_id;");
// now they will get their transactions back when they get set to 'completed' in the next step...
error_log("org.project60.sepa: reset bad contribution [$contribution_id] to 'Pending'.");
}

// step 1.2: in CiviCRM before 4.4.4, the status 'In Progress' => 'Completed' was not allowed:
if (version_compare(CRM_Utils_System::version(), '4.4.4', '<')) {
// therefore, we change all these contributions' statuses back to 'Pending'
$fix_status_query = "
UPDATE
civicrm_contribution
SET
contribution_status_id = $status_pending,
is_pay_later = 0
WHERE
contribution_status_id = $status_inprogress
AND id IN (SELECT contribution_id FROM civicrm_sdd_contribution_txgroup WHERE txgroup_id=$txgroup_id);
";
CRM_Core_DAO::executeQuery($fix_status_query);
// this should only be done in CiviCRM < 4.7.0, otherwise it causes the linked recurring contribution to
// switch status, see SEPA-514
if (version_compare(CRM_Utils_System::version(), '4.7.0', '<')) {
$find_rotten_contributions_sql = "
SELECT contribution.id AS contribution_id
FROM civicrm_sdd_contribution_txgroup AS txn_to_contribution
LEFT JOIN civicrm_contribution AS contribution ON contribution.id = txn_to_contribution.contribution_id
WHERE txn_to_contribution.txgroup_id IN ($txgroup_id)
AND contribution.id NOT IN (SELECT entity_id FROM civicrm_entity_financial_trxn WHERE entity_table='civicrm_contribution');";
$rotten_contribution = CRM_Core_DAO::executeQuery($find_rotten_contributions_sql);
while ($rotten_contribution->fetch()) {
$contribution_id = $rotten_contribution->contribution_id;
// set these rotten contributions to 'Pending', no 'pay_later'
CRM_Core_DAO::executeQuery("UPDATE civicrm_contribution SET contribution_status_id=$status_pending, is_pay_later=0 WHERE id=$contribution_id;");
// now they will get their transactions back when they get set to 'completed' in the next step...
CRM_Core_Error::debug_log_message("org.project60.sepa: reset bad contribution [$contribution_id] to 'Pending'.");
}
}

// step 2: update all the contributions
$find_txgroup_contributions_sql = "
SELECT
contribution.id AS contribution_id
FROM
civicrm_sdd_contribution_txgroup AS txn_to_contribution
LEFT JOIN
civicrm_contribution AS contribution ON contribution.id = txn_to_contribution.contribution_id
WHERE
contribution_status_id IN ($status_pending,$status_inprogress)
AND
txn_to_contribution.txgroup_id IN ($txgroup_id);
";
SELECT contribution.id AS contribution_id
FROM civicrm_sdd_contribution_txgroup AS txn_to_contribution
LEFT JOIN civicrm_contribution AS contribution ON contribution.id = txn_to_contribution.contribution_id
WHERE contribution_status_id IN ($status_pending,$status_inprogress)
AND txn_to_contribution.txgroup_id IN ($txgroup_id);";
$contribution = CRM_Core_DAO::executeQuery($find_txgroup_contributions_sql);
$error_count = 0;
while ($contribution->fetch()) {
Expand All @@ -222,7 +198,7 @@ static function received($txgroup_id) {
'receive_date' => date('YmdHis', strtotime($txgroup['collection_date']))));
if (!empty($result['is_error'])) {
$error_count += 1;
error_log("org.project60.sepa: ".$result['error_message']);
CRM_Core_Error::debug_log_message("org.project60.sepa: ".$result['error_message']);
}
}

Expand Down
10 changes: 8 additions & 2 deletions CRM/Sepa/Logic/Queue/Close.php
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,14 @@ protected function updateContributionStatus($contributions) {
// this status cannot be set via the API -> use SQL
CRM_Core_DAO::executeQuery("UPDATE civicrm_contribution SET contribution_status_id={$status_inProgress} WHERE id IN ({$contribution_id_list});");

} else {
// this should be status 'Completed', but it doesn't really matter
} else { // this should be status 'Completed', but it doesn't really matter
// first, some sanity checks:
if (version_compare(CRM_Utils_System::version(), '4.7.0', '>=')) {
// make sure they're all in status 'In Progress' to avoid SEPA-514
CRM_Core_DAO::executeQuery("UPDATE civicrm_contribution SET contribution_status_id={$status_inProgress} WHERE id IN ({$contribution_id_list});");
}

// then: set them all to the new status
foreach ($contributions as $contribution) {
civicrm_api3('Contribution', 'create', array(
'id' => $contribution['id'],
Expand Down
58 changes: 58 additions & 0 deletions CRM/Sepa/Upgrader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
/*-------------------------------------------------------+
| Project 60 - SEPA direct debit |
| Copyright (C) 2018 Project60 |
+--------------------------------------------------------+
| This program is released as free software under the |
| Affero GPL license. You can redistribute it and/or |
| modify it under the terms of this license which you |
| can read by viewing the included agpl.txt or online |
| at www.gnu.org/licenses/agpl.html. Removal of this |
| copyright header is strictly prohibited without |
| written permission from the original author(s). |
+--------------------------------------------------------*/

use CRM_Sepa_ExtensionUtil as E;

/**
* Collection of upgrade steps.
*/
class CRM_Sepa_Upgrader extends CRM_Sepa_Upgrader_Base {

/**
* Fixes the damages caused by SEPA-514
*
* @return TRUE on success
* @throws Exception
*/
public function upgrade_1260() {
$this->ctx->log->info('Applying update 1260');
// set all SEPA recurring contributions in status 'In Progress' to 'Pending'
$status_pending = (int) CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending');
$status_inprogress = (int) CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'In Progress');
CRM_Core_DAO::executeQuery("
UPDATE civicrm_contribution_recur rcur
LEFT JOIN civicrm_sdd_mandate mandate ON mandate.entity_id = rcur.id
AND mandate.entity_table = 'civicrm_contribution_recur'
SET rcur.contribution_status_id = {$status_pending}
WHERE rcur.contribution_status_id = {$status_inprogress}
AND mandate.id IS NOT NULL;");

// count number of loose 'In Progress' SEPA contributions,
// i.e. the ones that are not in any batch group
$lost_contributions = CRM_Core_DAO::singleValueQuery("
SELECT COUNT(*)
FROM civicrm_contribution contribution
LEFT JOIN civicrm_sdd_contribution_txgroup c2txg ON c2txg.contribution_id = contribution.id
LEFT JOIN civicrm_sdd_mandate mandate ON mandate.entity_id = contribution.contribution_recur_id
AND mandate.entity_table = 'civicrm_contribution_recur'
WHERE contribution.contribution_status_id = {$status_inprogress}
AND mandate.id IS NOT NULL
AND c2txg.id IS NULL;");
if ($lost_contributions) {
CRM_Core_Session::setStatus("There seems to be {$lost_contributions} SEPA contributions in status 'In Progress', that are not in any transaction group. This is likely due to the bug SEPA-514, and you might want to check, if these shouldn't be deleted.");
}

return TRUE;
}
}
Loading

0 comments on commit 31daff9

Please sign in to comment.