Uploaded image for project: 'CiviCRM'
  1. CiviCRM
  2. CRM-18468

The wrong recurring contribution is canceled under certain circumstances

    Details

    • Type: Bug
    • Status: Done/Fixed
    • Priority: Major
    • Resolution: Fixed/Completed
    • Affects Version/s: 4.4.19, 4.6.15, 4.7.6
    • Fix Version/s: 4.6.17, 4.7.9
    • Component/s: CiviContribute, CiviMember
    • Labels:
      None
    • Documentation Required?:
      None
    • Funding Source:
      Contributed Code

      Description

      This bug has existed for years - but I finally tracked down the circumstances.

      If:

      • a contact has multiple recurring contributions tied to the same membership (e.g. renewing a recurring membership at a different rate, or replacing card info that will soon expire);
      • The payment processor supports reporting the cancellation;
      • You try to cancel the older of the two recurring contributions;

      The result is that the NEWER of the two recurring contributions is canceled.

      The heart of the reason is in two places:

      • CRM_Contribute_Form_CancelSubscription::preProcess calls a function CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails. It passes through a record ID' and the entity of that record (Contribution, ContributionRecur, Membership).
      • getSubscriptionDetails executes a SQL query and returns a single row from the results.

      The problem is that a membership can have multiple subscription details, but getSubscriptionDetails only returns one, the newest. So canceling subscription A can lead to subscription B being canceled.

      A subsidiary issue is that we throw a fatal error if someone tries canceling a recurring contribution for a membership that's already been canceled. If someone has two recurring contributions, we have to allow them to cancel both, so I'm removing this error check.

      Right now, CRM_Contribute_Form_CancelSubscription::preProcess calls getSubscriptionDetails twice if a record has both a crid and mid. I don't understand what code path would allow you to have an mid without a crid - but assuming there is one I'm unaware of, I'm going to submit a PR so that if you have both, we use the crid subscription details, not the mid's.

      It's arguable that it shouldn't be allowed to renew an auto-renewing membership, and instead it's treated as an "Update Billing Details" request. However, this disallows renewing at a different rate, so I think this is the best option for now.

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              palantejon Jon K Goldberg
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: