CRM-17718 allow campaign id to be updated from contribution recur form
[civicrm-core.git] / CRM / Contribute / Form / UpdateSubscription.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
7e9e8871 4 | CiviCRM version 4.7 |
6a488035 5 +--------------------------------------------------------------------+
e7112fa7 6 | Copyright CiviCRM LLC (c) 2004-2015 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 *
30 * @package CRM
e7112fa7 31 * @copyright CiviCRM LLC (c) 2004-2015
6a488035
TO
32 */
33
34/**
35 * This class generates form components generic to recurring contributions
36 *
37 * It delegates the work to lower level subclasses and integrates the changes
38 * back in. It also uses a lot of functionality with the CRM API's, so any change
39 * made here could potentially affect the API etc. Be careful, be aware, use unit tests.
6a488035
TO
40 */
41class CRM_Contribute_Form_UpdateSubscription extends CRM_Core_Form {
42
43 /**
44 * The recurring contribution id, used when editing the recurring contribution
45 *
46 * @var int
47 */
48 protected $_crid = NULL;
49
50 protected $_coid = NULL;
51
52 protected $_subscriptionDetails = NULL;
53
54 protected $_selfService = FALSE;
55
56 public $_paymentProcessor = NULL;
57
58 public $_paymentProcessorObj = NULL;
59
60 /**
fe482240 61 * The id of the contact associated with this recurring contribution.
6a488035
TO
62 *
63 * @var int
6a488035 64 */
430ae6dd
TO
65 public $_contactID;
66
00be9182 67 public function preProcess() {
6a488035
TO
68
69 $this->_crid = CRM_Utils_Request::retrieve('crid', 'Integer', $this, FALSE);
70 if ($this->_crid) {
71 $this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_crid, 'recur', 'info');
72 $this->_paymentProcessorObj = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_crid, 'recur', 'obj');
73 $this->_subscriptionDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($this->_crid);
74 }
75
76 $this->_coid = CRM_Utils_Request::retrieve('coid', 'Integer', $this, FALSE);
77 if ($this->_coid) {
78 $this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_coid, 'contribute', 'info');
79 $this->_paymentProcessorObj = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_coid, 'contribute', 'obj');
80 $this->_subscriptionDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($this->_coid, 'contribution');
81 }
8de2c073 82 elseif ($this->_crid) {
83 $this->_coid = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $this->_crid, 'id', 'contribution_recur_id');
84 }
6a488035
TO
85
86 if ((!$this->_crid && !$this->_coid) ||
87 ($this->_subscriptionDetails == CRM_Core_DAO::$_nullObject)
88 ) {
89 CRM_Core_Error::fatal('Required information missing.');
90 }
91
92 if ($this->_subscriptionDetails->membership_id && $this->_subscriptionDetails->auto_renew) {
93 CRM_Core_Error::fatal(ts('You cannot update the subscription.'));
94 }
95
96 if (!CRM_Core_Permission::check('edit contributions')) {
97 $userChecksum = CRM_Utils_Request::retrieve('cs', 'String', $this, FALSE);
98 if (!CRM_Contact_BAO_Contact_Utils::validChecksum($this->_subscriptionDetails->contact_id, $userChecksum)) {
99 CRM_Core_Error::fatal(ts('You do not have permission to update subscription.'));
100 }
101 $this->_selfService = TRUE;
102 }
103 $this->assign('self_service', $this->_selfService);
104
105 if (!$this->_paymentProcessorObj->isSupported('changeSubscriptionAmount')) {
8de2c073 106 $userAlert = ts('Updates made using this form will change the recurring contribution information stored in your CiviCRM database, but will NOT be sent to the payment processor. You must enter the same changes using the payment processor web site.');
6a488035
TO
107 CRM_Core_Session::setStatus($userAlert, ts('Warning'), 'alert');
108 }
109
110 $this->assign('isChangeSupported', $this->_paymentProcessorObj->isSupported('changeSubscriptionAmount'));
111 $this->assign('paymentProcessor', $this->_paymentProcessor);
112 $this->assign('frequency_unit', $this->_subscriptionDetails->frequency_unit);
113 $this->assign('frequency_interval', $this->_subscriptionDetails->frequency_interval);
114
115 if ($this->_subscriptionDetails->contact_id) {
116 list($this->_donorDisplayName, $this->_donorEmail) = CRM_Contact_BAO_Contact::getContactDetails($this->_subscriptionDetails->contact_id);
117 }
118
119 CRM_Utils_System::setTitle(ts('Update Recurring Contribution'));
120
121 // handle context redirection
122 CRM_Contribute_BAO_ContributionRecur::setSubscriptionContext();
123 }
124
125 /**
347e061b 126 * Set default values for the form.
6a488035 127 *
347e061b 128 * Note that in edit/view mode the default values are retrieved from the database.
6a488035 129 */
00be9182 130 public function setDefaultValues() {
6a488035
TO
131
132 $this->_defaults = array();
133 $this->_defaults['amount'] = $this->_subscriptionDetails->amount;
134 $this->_defaults['installments'] = $this->_subscriptionDetails->installments;
7083dc2a 135 $this->_defaults['campaign_id'] = $this->_subscriptionDetails->campaign_id;
6a488035
TO
136 $this->_defaults['is_notify'] = 1;
137
138 return $this->_defaults;
139 }
140
141 /**
fe482240 142 * Actually build the components of the form.
6a488035
TO
143 */
144 public function buildQuickForm() {
8de2c073 145 // CRM-16398: If current recurring contribution got > 1 lineitems then make amount field readonly
146 $amtAttr = array('size' => 20);
147 $lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($this->_coid);
148 if (count($lineItems) > 1) {
149 $amtAttr += array('readonly' => TRUE);
150 }
151 $this->addMoney('amount', ts('Recurring Contribution Amount'), TRUE, $amtAttr,
152 TRUE, 'currency', $this->_subscriptionDetails->currency, TRUE
6a488035
TO
153 );
154
155 $this->add('text', 'installments', ts('Number of Installments'), array('size' => 20), TRUE);
156
157 if ($this->_donorEmail) {
158 $this->add('checkbox', 'is_notify', ts('Notify Contributor?'));
159 }
160
7083dc2a 161 if (CRM_Core_Permission::check('edit contributions')) {
162 $this->addEntityRef('campaign_id', 'Campaign', array('entity' => 'Campaign'));
163 }
164
6a488035 165 $type = 'next';
481a74f4 166 if ($this->_selfService) {
6a488035
TO
167 $type = 'submit';
168 }
169
170 // define the buttons
171 $this->addButtons(array(
172 array(
173 'type' => $type,
174 'name' => ts('Save'),
175 'isDefault' => TRUE,
176 ),
177 array(
178 'type' => 'cancel',
179 'name' => ts('Cancel'),
180 ),
181 )
182 );
183 }
184
185 /**
347e061b 186 * Called after the user submits the form.
6a488035
TO
187 */
188 public function postProcess() {
189 // store the submitted values in an array
190 $params = $this->exportValues();
191
192 if ($this->_selfService && $this->_donorEmail) {
193 // for self service force notify
194 $params['is_notify'] = 1;
195 }
196
197 // if this is an update of an existing recurring contribution, pass the ID
198 $params['id'] = $this->_subscriptionDetails->recur_id;
199 $message = '';
200
201 $params['subscriptionId'] = $this->_subscriptionDetails->subscription_id;
4eeb9a5b 202 $updateSubscription = TRUE;
6a488035 203 if ($this->_paymentProcessorObj->isSupported('changeSubscriptionAmount')) {
353ffa53 204 $updateSubscription = $this->_paymentProcessorObj->changeSubscriptionAmount($message, $params);
6a488035
TO
205 }
206 if (is_a($updateSubscription, 'CRM_Core_Error')) {
353ffa53
TO
207 CRM_Core_Error::displaySessionError($updateSubscription);
208 $status = ts('Could not update the Recurring contribution details');
209 $msgTitle = ts('Update Error');
210 $msgType = 'error';
6a488035
TO
211 }
212 elseif ($updateSubscription) {
353ffa53
TO
213 // save the changes
214 $result = CRM_Contribute_BAO_ContributionRecur::add($params);
215 $status = ts('Recurring contribution has been updated to: %1, every %2 %3(s) for %4 installments.',
216 array(
217 1 => CRM_Utils_Money::format($params['amount'], $this->_subscriptionDetails->currency),
218 2 => $this->_subscriptionDetails->frequency_interval,
219 3 => $this->_subscriptionDetails->frequency_unit,
220 4 => $params['installments'],
221 )
222 );
223
224 $msgTitle = ts('Update Success');
225 $msgType = 'success';
c6c91efc 226 $msg = ts('Recurring Contribution Updated');
353ffa53
TO
227 $contactID = $this->_subscriptionDetails->contact_id;
228
229 if ($this->_subscriptionDetails->amount != $params['amount']) {
230 $message .= "<br /> " . ts("Recurring contribution amount has been updated from %1 to %2 for this subscription.",
231 array(
232 1 => CRM_Utils_Money::format($this->_subscriptionDetails->amount, $this->_subscriptionDetails->currency),
233 2 => CRM_Utils_Money::format($params['amount'], $this->_subscriptionDetails->currency),
234 )) . ' ';
c6c91efc 235 if ($this->_subscriptionDetails->amount < $params['amount']) {
236 $msg = ts('Recurring Contribution Updated - increased installment amount');
237 }
238 else {
239 $msg = ts('Recurring Contribution Updated - decreased installment amount');
240 }
353ffa53 241 }
6a488035 242
353ffa53
TO
243 if ($this->_subscriptionDetails->installments != $params['installments']) {
244 $message .= "<br /> " . ts("Recurring contribution installments have been updated from %1 to %2 for this subscription.", array(
245 1 => $this->_subscriptionDetails->installments,
317fceb4 246 2 => $params['installments'],
353ffa53
TO
247 )) . ' ';
248 }
6a488035 249
353ffa53
TO
250 $activityParams = array(
251 'source_contact_id' => $contactID,
252 'activity_type_id' => CRM_Core_OptionGroup::getValue('activity_type',
253 'Update Recurring Contribution',
254 'name'
255 ),
c6c91efc 256 'subject' => $msg,
353ffa53
TO
257 'details' => $message,
258 'activity_date_time' => date('YmdHis'),
259 'status_id' => CRM_Core_OptionGroup::getValue('activity_status',
260 'Completed',
261 'name'
262 ),
263 );
264 $session = CRM_Core_Session::singleton();
265 $cid = $session->get('userID');
6a488035 266
353ffa53
TO
267 if ($cid) {
268 $activityParams['target_contact_id'][] = $activityParams['source_contact_id'];
269 $activityParams['source_contact_id'] = $cid;
270 }
271 CRM_Activity_BAO_Activity::create($activityParams);
272
273 if (!empty($params['is_notify'])) {
274 // send notification
275 if ($this->_subscriptionDetails->contribution_page_id) {
276 CRM_Core_DAO::commonRetrieveAll('CRM_Contribute_DAO_ContributionPage', 'id',
277 $this->_subscriptionDetails->contribution_page_id, $value, array(
278 'title',
279 'receipt_from_name',
280 'receipt_from_email',
281 )
6a488035 282 );
353ffa53
TO
283 $receiptFrom = '"' . CRM_Utils_Array::value('receipt_from_name', $value[$this->_subscriptionDetails->contribution_page_id]) . '" <' . $value[$this->_subscriptionDetails->contribution_page_id]['receipt_from_email'] . '>';
284 }
285 else {
286 $domainValues = CRM_Core_BAO_Domain::getNameAndEmail();
287 $receiptFrom = "$domainValues[0] <$domainValues[1]>";
6a488035 288 }
353ffa53
TO
289
290 list($donorDisplayName, $donorEmail) = CRM_Contact_BAO_Contact::getContactDetails($contactID);
291
292 $tplParams = array(
293 'recur_frequency_interval' => $this->_subscriptionDetails->frequency_interval,
294 'recur_frequency_unit' => $this->_subscriptionDetails->frequency_unit,
295 'amount' => CRM_Utils_Money::format($params['amount']),
296 'installments' => $params['installments'],
297 );
298
299 $tplParams['contact'] = array('display_name' => $donorDisplayName);
300 $tplParams['receipt_from_email'] = $receiptFrom;
301
302 $sendTemplateParams = array(
303 'groupName' => 'msg_tpl_workflow_contribution',
304 'valueName' => 'contribution_recurring_edit',
305 'contactId' => $contactID,
306 'tplParams' => $tplParams,
307 'isTest' => $this->_subscriptionDetails->is_test,
308 'PDFFilename' => 'receipt.pdf',
309 'from' => $receiptFrom,
310 'toName' => $donorDisplayName,
311 'toEmail' => $donorEmail,
312 );
313 list($sent) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams);
6a488035 314 }
353ffa53 315 }
6a488035
TO
316
317 $session = CRM_Core_Session::singleton();
353ffa53 318 $userID = $session->get('userID');
481a74f4 319 if ($userID && $status) {
6a488035 320 CRM_Core_Session::setStatus($status, $msgTitle, $msgType);
0db6c3e1 321 }
4c9b6178 322 elseif (!$userID) {
317fceb4 323 if ($status) {
6a488035 324 CRM_Utils_System::setUFMessage($status);
317fceb4 325 }
6a488035
TO
326 // keep result as 1, since we not displaying anything on the redirected page anyway
327 return CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contribute/subscriptionstatus',
353ffa53 328 "reset=1&task=update&result=1"));
6a488035
TO
329 }
330 }
96025800 331
6a488035 332}