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

Membership Upsell and Ability to Change Membership at Renewal Maintaining Membership Continuity

    Details

    • Type: New Feature
    • Status: Done/Fixed
    • Priority: Minor
    • Resolution: Fixed/Completed
    • Affects Version/s: 3.3.1
    • Fix Version/s: 3.4.alpha
    • Component/s: CiviMember
    • Labels:
      None

      Description

      Requirements
      =========
      • Members renewing online (self-service) are invited / encouraged to upgrade their membership when they renew.
      • In-house staff can also change / upgrade membership types when processing a renewal (currently staff can only renew with the same membership type).
      • Membership record continuity is maintained (i.e. membership type is updated in existing membership record, membership join date is maintained, etc.)

      Implementation
      ===========
      1. Schema changes
      1.1 Add column to civicrm_membership_log table to record the current membership type when a membership is created and updated. For renewals, this records the "new" membership type:

      • membership_type_id INT FK to civicrm_membership_type.id

      2. Upgrade tasks

      • Alter table civicrm_membership_log to add new column (above)
      • Set civicrm_membership_log.membership_type_id equal to membership_type_id of corresponding civicrm_membership table.

      3. BAO changes
      3.1 CRM_Member_BAO_MembershipLog::add

      • This method simply takes params and passes to DAO functions, so if membership_type_id is passed (after schema and DAO files are updated) - it should work.
      • You'll need to check for / fix all invocations of this method in the codebase since membership_type_id will be a required parameter

      3.2 CRM_Member_BAO_Membership::renewMembership

      • On a quick review, it looks like this BAO takes the existing membership record ($form->_membershipId) and "renews" it, and it supports passed in membershipTypeID. You'll need to debug to see the methods handle passing in a different membershipTypeID. Existing rules which differentiate the condition where membership is currently "current" (e.g. status has is_current = TRUE) vs. membership is "not current" (e.g. Expired) should be maintained.
      • fixMembershipStatusBeforeRenew call CRM_Member_BAO_MembershipLog. You'll need to add a param for the membership type being renewed (example: if membership type was General, and is being renewed as Student - log should record 'Student').

      NOTE: Looks like there might be a bug in the code that sets membership_log.modified_id during renewal. I ran an offline renewal in 3.3.1 and modified_id was set to contact id of the member, should have been "my user's" contact id.

      4. Offline membership renewal
      The following modifications are needed to the offline membership renewal form/class - CRM/Member/Form/MembershipRenewal.php (civicrm/contact/view/membership?action=renew):

      4.1 Add link right side of Membership Organization and Type read-only field: "change membership type"

      • This link calls a local jquery function which unhides 2 <select> fields for the membership type org and membership type (see CRM/Member/Form/Membership buildQuickForm).

      4.2 Additional jquery function needed to update the value of conditionally displayed 'total_amount' when a different membership type is selected. This field value is currently set via setDefaultValues() based on the existing membership type.

      4.3 Check setDefaults() for other default values that are set based on passed in (existing) membership type, and then make sure these values are properly re-set in postProcess if membership type is changed.

      NOTE: Processing flow for Submit Credit Card Renewal (mode=test, mode=live) are a bit different, so check the code in postProcess where ( $this->_mode ) is TRUE and FALSE.

      5. Online (self-service) membership renewal
      Following modifications needed for online membership renewal

      5.1 Explicit renewal / logged in user:

      • I don't think we need to make any UI changes here. Organizations can already configure special text for the Renewal situation (inviting upsell etc.) and user is able to select a membership type other than the one we "recognize" if the "member" is logged in.
      • Processing: you'll need to dig into Contribute/Form/Contribution/Main.php and Confirm.php, as well as Member_BAO_Membership::buildMembershipBloc to see what changes are needed (if any) so that the membership id ($form->_mid) is maintained if the user selects a different membership type in the form's radio button. Currently, if user doesn't select the membership type identified ($row.current_membership in MembershipBlock.tpl) - the code will create a new membership record rather than renewing the existing mid.

      5.2 Anonymous user who has an existing membership
      I think handling this use case is out of scope. We don't really know what the user intends to do when they sign up for a membership w/o having their existing membership status identified to them (as we do in 5.1).

      5.3 Contact Dashboard - Renew link
      Logged in users get a "renew" link in their contact dashboard Memberships section IF there is an online contribution page associated with the contribution record which paid for the membership. Note that in 3.3.2+ u can "fake" this by editing the contribution record and setting a contrib page (under Additional Info). This link passes the existing membership id as a GET param (mid=xx) - so this is really the same as 5.1 (where the mid is set programmatically).

        Attachments

        1. crm-7297.patch
          40 kB
          Joe Murray
        2. crm-7297.v2.patch
          49 kB
          Joe Murray
        3. crm7297.v3.patch
          4 kB
          Joe Murray
        4. crm7297.v4.patch
          5 kB
          Joe Murray
        5. crm7297.v5.patch
          6 kB
          Joe Murray
        6. crm7297.v6.patch
          8 kB
          Joe Murray

          Activity

            People

            • Assignee:
              dgg David Greenberg
              Reporter:
              dgg David Greenberg
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: