You are here

private function WebformCivicrmPostProcess::contributionRecur in Webform CiviCRM Integration 8.5

Generate recurring contribution and transact the first one

2 calls to WebformCivicrmPostProcess::contributionRecur()
WebformCivicrmPostProcess::createDeferredPayment in src/WebformCivicrmPostProcess.php
Create Pending (Pay Later) Contribution
WebformCivicrmPostProcess::submitLivePayment in src/WebformCivicrmPostProcess.php
Execute payment processor transaction This happens during form validation and sets a form error if unsuccessful

File

src/WebformCivicrmPostProcess.php, line 1961
Front-end form validation and post-processing.

Class

WebformCivicrmPostProcess

Namespace

Drupal\webform_civicrm

Code

private function contributionRecur($contributionParams, $paymentType = 'live') {
  $utils = \Drupal::service('webform_civicrm.utils');
  $numInstallments = wf_crm_aval($contributionParams, 'installments', NULL, TRUE);

  // if ($installments === 0) or $installments is not defined we treat as an open-ended recur
  $contributionFirstAmount = $contributionRecurAmount = $contributionParams['total_amount'];
  $salesTaxFirstAmount = wf_crm_aval($contributionParams, 'tax_amount', NULL, TRUE);
  $nondeductibleFirstAmount = wf_crm_aval($contributionParams, 'non_deductible_amount', NULL, TRUE);
  if ($numInstallments > 0) {

    // DRU-2862396 - we must ensure to only present 2 decimals to CiviCRM:
    $contributionRecurAmount = round($contributionParams['total_amount'] / $numInstallments, 2, PHP_ROUND_HALF_UP);
    $contributionFirstAmount = $contributionRecurAmount;
    $salesTaxFirstAmount = round($salesTaxFirstAmount / $numInstallments, 2, PHP_ROUND_HALF_UP);
    $nondeductibleFirstAmount = round($nondeductibleFirstAmount / $numInstallments, 2, PHP_ROUND_HALF_UP);

    // Calculate the line_items for the first contribution:
    // At this point line_items are set to the full (non-installment) amounts.
    foreach ($this->line_items as $key => $k) {
      $this->line_items[$key]['unit_price'] = round($k['unit_price'] / $numInstallments, 2, PHP_ROUND_HALF_UP);
      $this->line_items[$key]['line_total'] = round($k['line_total'] / $numInstallments, 2, PHP_ROUND_HALF_UP);
      $this->line_items[$key]['tax_amount'] = round($k['tax_amount'] / $numInstallments, 2, PHP_ROUND_HALF_UP);
    }
  }

  // Create Params for Creating the Recurring Contribution Series and Create it
  $contributionRecurParams = [
    'contact_id' => $contributionParams['contact_id'],
    'frequency_interval' => wf_crm_aval($contributionParams, 'frequency_interval', 1),
    'frequency_unit' => wf_crm_aval($contributionParams, 'frequency_unit', 'month'),
    'installments' => $numInstallments,
    'amount' => $contributionRecurAmount,
    'contribution_status_id' => 'In Progress',
    'currency' => $contributionParams['currency'],
    'payment_processor_id' => $contributionParams['payment_processor_id'],
    'financial_type_id' => $contributionParams['financial_type_id'],
  ];
  if (empty($contributionParams['payment_processor_id'])) {
    $contributionRecurParams['payment_processor_id'] = 'null';
  }
  $resultRecur = $utils
    ->wf_civicrm_api('ContributionRecur', 'create', $contributionRecurParams);
  $this->ent['contribution_recur'][1]['id'] = $resultRecur['id'];

  // Run the Transaction - and Create the Contribution Record - relay Recurring Series information in addition to the already existing Params [and re-key where needed]; at times two keys are required
  $contributionParams['total_amount'] = $contributionFirstAmount;
  $contributionParams['tax_amount'] = $salesTaxFirstAmount;
  $contributionParams['non_deductible_amount'] = $nondeductibleFirstAmount;
  $additionalParams = [
    'contribution_recur_id' => $resultRecur['id'],
    'contributionRecurID' => $resultRecur['id'],
    'is_recur' => 1,
    'contactID' => $contributionParams['contact_id'],
    'frequency_interval' => wf_crm_aval($contributionParams, 'frequency_interval', 1),
    'frequency_unit' => wf_crm_aval($contributionParams, 'frequency_unit', 'month'),
  ];
  $APIAction = 'transact';
  if ($paymentType === 'deferred') {
    $APIAction = 'create';
  }
  $result = $utils
    ->wf_civicrm_api('contribution', $APIAction, $contributionParams + $additionalParams);

  // If transaction was successful - Update the Recurring Series - currency must be resubmitted or else it will re-default to USD; invoice_id is that of the initiating Contribution
  if (empty($result['error_message'])) {
    $recurParams = [
      'id' => $resultRecur['id'],
      'currency' => $contributionParams['currency'],
      'next_sched_contribution_date' => date("Y-m-d H:i:s", strtotime('+' . $contributionRecurParams['frequency_interval'] . ' ' . $contributionRecurParams['frequency_unit'])),
    ];
    if ($APIAction == 'transact') {

      // Now that we include Transact within webform_civicrm module it comes back flattened:
      $recurParams['invoice_id'] = $result['invoice_id'];
      $recurParams['payment_instrument_id'] = $result['payment_instrument_id'];
    }
    else {
      $recurParams['invoice_id'] = $result['values'][$result['id']]['invoice_id'];
      $recurParams['payment_instrument_id'] = $result['values'][$result['id']]['payment_instrument_id'];
    }
    $utils
      ->wf_civicrm_api('ContributionRecur', 'create', $recurParams);
  }
  return $result;
}