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