Answers.Body: <p>I ended up using the buildAmount hook - (in a custom extension) - very similar to how CiviDiscount works! July 01 is the roll over day. After that we don't need to discount anymore. This is my first pass at it:</p>
  
  <pre><code>function membershippro_civicrm_buildAmount($pageType, &amp;$form, &amp;$amounts) {
  
    //retrieve price set field associated with this priceset
    $priceSetInfo = CRM_CiviDiscount_Utils::getPriceSetsInfo($psid);
    $originalAmounts = $amounts;
  
    $discountApplied = FALSE;
      foreach ($amounts as $fee_id =&gt; &amp;$fee) {
      if (!is_array($fee['options'])) {
        continue;
      }
  
    foreach ($fee['options'] as $option_id =&gt; &amp;$option) {
      $originalLabel = $originalAmounts[$fee_id]['options'][$option_id]['label'];
      $originalAmount = CRM_Utils_Rule::cleanMoney($originalAmounts[$fee_id]['options'][$option_id]['amount']);
  
      $now = time(); // or your date as well
      $to_date = strtotime("2017-07-01");
      $datediff = $to_date - $now;
  
      $num_days = floor($datediff / (60 * 60 * 24));
  
      if ($num_days &gt;= 1) {
        $discountAmount = $originalAmounts[$fee_id]['options'][$option_id]['amount'] * $num_days / 365;
      }
  
      $amount = $originalAmount - $discountAmount;
  
      $option['amount'] = $amount;
      $option['discount_applied'] = $discountAmount;
  
      $recalculateTaxAmount = array();
      if (array_key_exists('tax_amount', $originalAmounts[$fee_id]['options'][$option_id]) &amp;&amp;
        array_key_exists('tax_rate', $originalAmounts[$fee_id]['options'][$option_id])
      ) {
        $recalculateTaxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($amount, $originalAmounts[$fee_id]['options'][$option_id]['tax_rate']);
          if (!empty($recalculateTaxAmount)) {
            $option['tax_amount'] = round($recalculateTaxAmount['tax_amount'], 2);
          }
        }
  
          $discountApplied = TRUE;
  
        }
      }
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-03-02T16:27:59.560Z
Answers.Text: Nice, this looks like a useful hook for other purposes also - e.g. I've got a custom price multiplier (membership x chapters) and bulk discount option, thanks. Also - you might consider packaging this up in an extension?
Answers.UserDisplayName: Alan Dixon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-09-09T18:36:50.370Z
Answers.Text: Would this need to be a custom CiviCRM extension or would it largely work in a Drupal or Backdrop module instead? Just curious as I feel a bit more at home there and usually have a custom module for minor tweaks like this. I just don't know if a CiviCRM hook will get triggered if it's in a Drupal module...
Answers.UserDisplayName: Laryn
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-09-09T21:06:43.383Z
Answers.Text: Yes - CiviCRM hooks get triggered when they are in a Drupal module! I often go that route for the exact same reason.
Answers.UserDisplayName: KarinG - Semper IT
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-02-25T23:38:55.097Z
Answers.LastActivityDate: 2017-03-02T00:19:19.533Z
Answers.LastEditDate: 2017-03-02T00:19:19.533Z
Answers.UserDisplayName: KarinG - Semper IT
Body: <p>To avoid having members pay full price for a fixed Membership Type Plan? We are using the rollover but need something that kicks in before the complete rollover takes affect. </p>
  
Tags: <civimember>
Title: Code example of how to pro-rate Fixed Calendar Year Membership in CiviCRM
ThreadText: # Code example of how to pro-rate Fixed Calendar Year Membership in CiviCRM
  
  (Asked by: username_0 on 2017-02-23)
  
  To avoid having members pay full price for a fixed Membership Type Plan? We are using the rollover but need something that kicks in before the complete rollover takes affect.
  
  **Tags:** civimember
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2017-02-25. Score: 2 | Accepted answer
  
  I ended up using the buildAmount hook - (in a custom extension) - very similar to how CiviDiscount works! July 01 is the roll over day. After that we don't need to discount anymore. This is my first pass at it:
  
  ```
  function membershippro_civicrm_buildAmount($pageType, &$form, &$amounts) {
  
    //retrieve price set field associated with this priceset
    $priceSetInfo = CRM_CiviDiscount_Utils::getPriceSetsInfo($psid);
    $originalAmounts = $amounts;
  
    $discountApplied = FALSE;
      foreach ($amounts as $fee_id => &$fee) {
      if (!is_array($fee['options'])) {
        continue;
      }
  
    foreach ($fee['options'] as $option_id => &$option) {
      $originalLabel = $originalAmounts[$fee_id]['options'][$option_id]['label'];
      $originalAmount = CRM_Utils_Rule::cleanMoney($originalAmounts[$fee_id]['options'][$option_id]['amount']);
  
      $now = time(); // or your date as well
      $to_date = strtotime("2017-07-01");
      $datediff = $to_date - $now;
  
      $num_days = floor($datediff / (60 * 60 * 24));
  
      if ($num_days >= 1) {
        $discountAmount = $originalAmounts[$fee_id]['options'][$option_id]['amount'] * $num_days / 365;
      }
  
      $amount = $originalAmount - $discountAmount;
  
      $option['amount'] = $amount;
      $option['discount_applied'] = $discountAmount;
  
      $recalculateTaxAmount = array();
      if (array_key_exists('tax_amount', $originalAmounts[$fee_id]['options'][$option_id]) &&
        array_key_exists('tax_rate', $originalAmounts[$fee_id]['options'][$option_id])
      ) {
        $recalculateTaxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($amount, $originalAmounts[$fee_id]['options'][$option_id]['tax_rate']);
          if (!empty($recalculateTaxAmount)) {
            $option['tax_amount'] = round($recalculateTaxAmount['tax_amount'], 2);
          }
        }
  
          $discountApplied = TRUE;
  
        }
      }
  }
  
  ```
  
  > **Comments:**
  > **username_1**: Nice, this looks like a useful hook for other purposes also - e.g. I've got a custom price multiplier (membership x chapters) and bulk discount option, thanks. Also - you might consider packaging this up in an extension?  
  > **username_2**: Would this need to be a custom CiviCRM extension or would it largely work in a Drupal or Backdrop module instead? Just curious as I feel a bit more at home there and usually have a custom module for minor tweaks like this. I just don't know if a CiviCRM hook will get triggered if it's in a Drupal module...  
  > **username_0**: Yes - CiviCRM hooks get triggered when they are in a Drupal module! I often go that route for the exact same reason.  
  
  ---
  
  