setAction(CRM_Core_Action::UPDATE); if ($this->_coid) { $this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_coid, 'contribute', 'info'); // @todo test & replace with $this->_paymentProcessorObj = Civi\Payment\System::singleton()->getById($this->_paymentProcessor['id']); $this->_paymentProcessorObj = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_coid, 'contribute', 'obj'); $this->contributionRecurID = $this->_subscriptionDetails->recur_id; } elseif ($this->contributionRecurID) { $this->_coid = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $this->contributionRecurID, 'id', 'contribution_recur_id'); } if (!$this->contributionRecurID || !$this->_subscriptionDetails) { CRM_Core_Error::statusBounce(ts('Required information missing.')); } if ($this->_subscriptionDetails->membership_id && $this->_subscriptionDetails->auto_renew) { // Add Membership details to form $membership = civicrm_api3('Membership', 'get', [ 'contribution_recur_id' => $this->contributionRecurID, ]); if (!empty($membership['count'])) { $membershipDetails = reset($membership['values']); $values['membership_id'] = $membershipDetails['id']; $values['membership_name'] = $membershipDetails['membership_name']; } $this->assign('recurMembership', $values); $this->assign('contactId', $this->_subscriptionDetails->contact_id); } $this->assign('self_service', $this->isSelfService()); $this->editableScheduleFields = $this->_paymentProcessorObj->getEditableRecurringScheduleFields(); $changeHelpText = $this->_paymentProcessorObj->getRecurringScheduleUpdateHelpText(); if (!in_array('amount', $this->editableScheduleFields)) { // Not sure if this is good behaviour - maintaining this existing behaviour for now. CRM_Core_Session::setStatus($changeHelpText, ts('Warning'), 'alert'); } else { $this->assign('changeHelpText', $changeHelpText); } $alreadyHardCodedFields = ['amount', 'installments']; foreach ($this->editableScheduleFields as $editableScheduleField) { if (!in_array($editableScheduleField, $alreadyHardCodedFields)) { $this->addField($editableScheduleField, ['entity' => 'ContributionRecur'], FALSE, FALSE); } } // when custom data is included in this page if (!empty($_POST['hidden_custom']) && !$this->isSelfService()) { CRM_Custom_Form_CustomData::preProcess($this, NULL, NULL, 1, 'ContributionRecur', $this->contributionRecurID); CRM_Custom_Form_CustomData::buildQuickForm($this); CRM_Custom_Form_CustomData::setDefaultValues($this); } $this->assign('editableScheduleFields', array_diff($this->editableScheduleFields, $alreadyHardCodedFields)); if ($this->_subscriptionDetails->contact_id) { list($this->_donorDisplayName, $this->_donorEmail) = CRM_Contact_BAO_Contact::getContactDetails($this->_subscriptionDetails->contact_id); } CRM_Utils_System::setTitle(ts('Update Recurring Contribution')); // Handle context redirection. CRM_Contribute_BAO_ContributionRecur::setSubscriptionContext(); } /** * Set default values for the form. * * Note that in edit/view mode the default values are retrieved from the database. */ public function setDefaultValues() { $this->_defaults = []; $this->_defaults['amount'] = $this->_subscriptionDetails->amount; $this->_defaults['installments'] = $this->_subscriptionDetails->installments; $this->_defaults['campaign_id'] = $this->_subscriptionDetails->campaign_id; $this->_defaults['financial_type_id'] = $this->_subscriptionDetails->financial_type_id; $this->_defaults['is_notify'] = 1; foreach ($this->editableScheduleFields as $field) { $this->_defaults[$field] = $this->_subscriptionDetails->$field ?? NULL; } return $this->_defaults; } /** * Actually build the components of the form. */ public function buildQuickForm() { // CRM-16398: If current recurring contribution got > 1 lineitems then make amount field readonly $amtAttr = ['size' => 20]; $lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($this->_coid); if (count($lineItems) > 1) { $amtAttr += ['readonly' => TRUE]; } $this->addMoney('amount', ts('Recurring Contribution Amount'), TRUE, $amtAttr, TRUE, 'currency', $this->_subscriptionDetails->currency, TRUE ); $this->add('text', 'installments', ts('Number of Installments'), ['size' => 20], FALSE); if ($this->_donorEmail) { $this->add('checkbox', 'is_notify', ts('Notify Contributor?')); } if (CRM_Core_Permission::check('edit contributions')) { CRM_Campaign_BAO_Campaign::addCampaign($this, $this->_subscriptionDetails->campaign_id); } if (CRM_Contribute_BAO_ContributionRecur::supportsFinancialTypeChange($this->contributionRecurID)) { $this->addEntityRef('financial_type_id', ts('Financial Type'), ['entity' => 'FinancialType'], !$this->isSelfService()); } // Add custom data $this->assign('customDataType', 'ContributionRecur'); $this->assign('entityID', $this->contributionRecurID); $type = 'next'; if ($this->isSelfService()) { $type = 'submit'; } // define the buttons $this->addButtons([ [ 'type' => $type, 'name' => ts('Save'), 'isDefault' => TRUE, ], [ 'type' => 'cancel', 'name' => ts('Cancel'), ], ]); } /** * Called after the user submits the form. */ public function postProcess() { // store the submitted values in an array $params = $this->exportValues(); if ($this->isSelfService() && $this->_donorEmail) { // for self service force notify $params['is_notify'] = 1; } // if this is an update of an existing recurring contribution, pass the ID $params['id'] = $this->_subscriptionDetails->recur_id; $message = ''; $params['subscriptionId'] = $this->getSubscriptionDetails()->processor_id; $updateSubscription = TRUE; if ($this->_paymentProcessorObj->supports('changeSubscriptionAmount')) { try { $updateSubscription = $this->_paymentProcessorObj->changeSubscriptionAmount($message, $params); } catch (\Civi\Payment\Exception\PaymentProcessorException $e) { CRM_Core_Error::statusBounce($e->getMessage()); } } if (is_a($updateSubscription, 'CRM_Core_Error')) { CRM_Core_Error::displaySessionError($updateSubscription); $status = ts('Could not update the Recurring contribution details'); $msgTitle = ts('Update Error'); $msgType = 'error'; } elseif ($updateSubscription) { // Handle custom data $params['custom'] = CRM_Core_BAO_CustomField::postProcess($params, $this->contributionRecurID, 'ContributionRecur'); // save the changes CRM_Contribute_BAO_ContributionRecur::add($params); $status = ts('Recurring contribution has been updated to: %1, every %2 %3(s) for %4 installments.', [ 1 => CRM_Utils_Money::format($params['amount'], $this->_subscriptionDetails->currency), 2 => $this->_subscriptionDetails->frequency_interval, 3 => $this->_subscriptionDetails->frequency_unit, 4 => $params['installments'], ] ); $msgTitle = ts('Update Success'); $msgType = 'success'; $msg = ts('Recurring Contribution Updated'); $contactID = $this->_subscriptionDetails->contact_id; if ($this->_subscriptionDetails->amount != $params['amount']) { $message .= "
" . ts("Recurring contribution amount has been updated from %1 to %2 for this subscription.", [ 1 => CRM_Utils_Money::format($this->_subscriptionDetails->amount, $this->_subscriptionDetails->currency), 2 => CRM_Utils_Money::format($params['amount'], $this->_subscriptionDetails->currency), ]) . ' '; if ($this->_subscriptionDetails->amount < $params['amount']) { $msg = ts('Recurring Contribution Updated - increased installment amount'); } else { $msg = ts('Recurring Contribution Updated - decreased installment amount'); } } if ($this->_subscriptionDetails->installments != $params['installments']) { $message .= "
" . ts("Recurring contribution installments have been updated from %1 to %2 for this subscription.", [ 1 => $this->_subscriptionDetails->installments, 2 => $params['installments'], ]) . ' '; } $activityParams = [ 'source_contact_id' => $contactID, 'activity_type_id' => CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Update Recurring Contribution'), 'subject' => $msg, 'details' => $message, 'activity_date_time' => date('YmdHis'), 'status_id' => CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_status_id', 'Completed'), ]; $session = CRM_Core_Session::singleton(); $cid = $session->get('userID'); if ($cid) { $activityParams['target_contact_id'][] = $activityParams['source_contact_id']; $activityParams['source_contact_id'] = $cid; } CRM_Activity_BAO_Activity::create($activityParams); if (!empty($params['is_notify'])) { // send notification if ($this->_subscriptionDetails->contribution_page_id) { CRM_Core_DAO::commonRetrieveAll('CRM_Contribute_DAO_ContributionPage', 'id', $this->_subscriptionDetails->contribution_page_id, $value, [ 'title', 'receipt_from_name', 'receipt_from_email', ] ); $receiptFrom = '"' . CRM_Utils_Array::value('receipt_from_name', $value[$this->_subscriptionDetails->contribution_page_id]) . '" <' . $value[$this->_subscriptionDetails->contribution_page_id]['receipt_from_email'] . '>'; } else { $domainValues = CRM_Core_BAO_Domain::getNameAndEmail(); $receiptFrom = "$domainValues[0] <$domainValues[1]>"; } list($donorDisplayName, $donorEmail) = CRM_Contact_BAO_Contact::getContactDetails($contactID); $tplParams = [ 'recur_frequency_interval' => $this->_subscriptionDetails->frequency_interval, 'recur_frequency_unit' => $this->_subscriptionDetails->frequency_unit, 'amount' => CRM_Utils_Money::format($params['amount']), 'installments' => $params['installments'], ]; $tplParams['contact'] = ['display_name' => $donorDisplayName]; $tplParams['receipt_from_email'] = $receiptFrom; $sendTemplateParams = [ 'groupName' => 'msg_tpl_workflow_contribution', 'valueName' => 'contribution_recurring_edit', 'contactId' => $contactID, 'tplParams' => $tplParams, 'isTest' => $this->_subscriptionDetails->is_test, 'PDFFilename' => 'receipt.pdf', 'from' => $receiptFrom, 'toName' => $donorDisplayName, 'toEmail' => $donorEmail, ]; list($sent) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams); } } $session = CRM_Core_Session::singleton(); $userID = $session->get('userID'); if ($userID && $status) { CRM_Core_Session::setStatus($status, $msgTitle, $msgType); } elseif (!$userID) { if ($status) { CRM_Utils_System::setUFMessage($status); } // keep result as 1, since we not displaying anything on the redirected page anyway return CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contribute/subscriptionstatus', "reset=1&task=update&result=1")); } } }