Merge pull request #884 from davecivicrm/CRM-12691
[civicrm-core.git] / CRM / Contribute / Form / UpdateSubscription.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.3 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
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 +--------------------------------------------------------------------+
26*/
27
28/**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2013
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 /**
64 * the id of the contact associated with this recurring contribution
65 *
66 * @var int
67 * @public
68 */
69 public $_contactID; function preProcess() {
70
71 $this->_crid = CRM_Utils_Request::retrieve('crid', 'Integer', $this, FALSE);
72 if ($this->_crid) {
73 $this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_crid, 'recur', 'info');
74 $this->_paymentProcessorObj = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_crid, 'recur', 'obj');
75 $this->_subscriptionDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($this->_crid);
76 }
77
78 $this->_coid = CRM_Utils_Request::retrieve('coid', 'Integer', $this, FALSE);
79 if ($this->_coid) {
80 $this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_coid, 'contribute', 'info');
81 $this->_paymentProcessorObj = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_coid, 'contribute', 'obj');
82 $this->_subscriptionDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($this->_coid, 'contribution');
83 }
84
85 if ((!$this->_crid && !$this->_coid) ||
86 ($this->_subscriptionDetails == CRM_Core_DAO::$_nullObject)
87 ) {
88 CRM_Core_Error::fatal('Required information missing.');
89 }
90
91 if ($this->_subscriptionDetails->membership_id && $this->_subscriptionDetails->auto_renew) {
92 CRM_Core_Error::fatal(ts('You cannot update the subscription.'));
93 }
94
95 if (!CRM_Core_Permission::check('edit contributions')) {
96 $userChecksum = CRM_Utils_Request::retrieve('cs', 'String', $this, FALSE);
97 if (!CRM_Contact_BAO_Contact_Utils::validChecksum($this->_subscriptionDetails->contact_id, $userChecksum)) {
98 CRM_Core_Error::fatal(ts('You do not have permission to update subscription.'));
99 }
100 $this->_selfService = TRUE;
101 }
102 $this->assign('self_service', $this->_selfService);
103
104 if (!$this->_paymentProcessorObj->isSupported('changeSubscriptionAmount')) {
105 $userAlert = "<span class='font-red'>" . 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.',
106 array( 1 => $this->_paymentProcessorObj->_processorName ) ) . '</span>';
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 /**
126 * This function sets the default values for the form. Note that in edit/view mode
127 * the default values are retrieved from the database
128 *
129 * @access public
130 *
131 * @return None
132 */
133 function setDefaultValues() {
134
135 $this->_defaults = array();
136 $this->_defaults['amount'] = $this->_subscriptionDetails->amount;
137 $this->_defaults['installments'] = $this->_subscriptionDetails->installments;
138 $this->_defaults['is_notify'] = 1;
139
140 return $this->_defaults;
141 }
142
143 /**
144 * Function to actually build the components of the form
145 *
146 * @return None
147 * @access public
148 */
149 public function buildQuickForm() {
150 // define the fields
151 $this->addMoney('amount', ts('Recurring Contribution Amount'), TRUE,
152 array(
153 'size' => 20), TRUE,
154 'currency', NULL, TRUE
155 );
156
157 $this->add('text', 'installments', ts('Number of Installments'), array('size' => 20), TRUE);
158
159 if ($this->_donorEmail) {
160 $this->add('checkbox', 'is_notify', ts('Notify Contributor?'));
161 }
162
163 $type = 'next';
164 if ( $this->_selfService ) {
165 $type = 'submit';
166 }
167
168 // define the buttons
169 $this->addButtons(array(
170 array(
171 'type' => $type,
172 'name' => ts('Save'),
173 'isDefault' => TRUE,
174 ),
175 array(
176 'type' => 'cancel',
177 'name' => ts('Cancel'),
178 ),
179 )
180 );
181 }
182
183 /**
184 * This function is called after the user submits the form
185 *
186 * @access public
187 *
188 * @return None
189 */
190 public function postProcess() {
191 // store the submitted values in an array
192 $params = $this->exportValues();
193
194 if ($this->_selfService && $this->_donorEmail) {
195 // for self service force notify
196 $params['is_notify'] = 1;
197 }
198
199 // if this is an update of an existing recurring contribution, pass the ID
200 $params['id'] = $this->_subscriptionDetails->recur_id;
201 $message = '';
202
203 $params['subscriptionId'] = $this->_subscriptionDetails->subscription_id;
204 $updateSubscription = true;
205 if ($this->_paymentProcessorObj->isSupported('changeSubscriptionAmount')) {
206 $updateSubscription = $this->_paymentProcessorObj->changeSubscriptionAmount($message, $params);
207 }
208 if (is_a($updateSubscription, 'CRM_Core_Error')) {
209 CRM_Core_Error::displaySessionError($updateSubscription);
210 $status = ts('Could not update the Recurring contribution details');
211 $msgTitle = ts('Update Error');
212 $msgType = 'error';
213 }
214 elseif ($updateSubscription) {
215 // save the changes
216 $result = CRM_Contribute_BAO_ContributionRecur::add($params);
217 $status = ts('Recurring contribution has been updated to: %1, every %2 %3(s) for %4 installments.',
218 array(1 => CRM_Utils_Money::format($params['amount'], $this->_subscriptionDetails->currency),
219 2 => $this->_subscriptionDetails->frequency_interval,
220 3 => $this->_subscriptionDetails->frequency_unit,
221 4 => $params['installments']
222 )
223 );
224
225 $msgTitle = ts('Update Success');
226 $msgType = 'success';
227
228 $contactID = $this->_subscriptionDetails->contact_id;
229
230 if ($this->_subscriptionDetails->amount != $params['amount']) {
231 $message .= "<br /> " . ts("Recurring contribution amount has been updated from %1 to %2 for this subscription.",
232 array(
233 1 => CRM_Utils_Money::format($this->_subscriptionDetails->amount, $this->_subscriptionDetails->currency),
234 2 => CRM_Utils_Money::format($params['amount'], $this->_subscriptionDetails->currency)
235 )) . ' ';
236 }
237
238 if ($this->_subscriptionDetails->installments != $params['installments']) {
239 $message .= "<br /> " . ts("Recurring contribution installments have been updated from %1 to %2 for this subscription.", array(1 => $this->_subscriptionDetails->installments, 2 => $params['installments'])) . ' ';
240 }
241
242 $activityParams = array(
243 'source_contact_id' => $contactID,
244 'activity_type_id' => CRM_Core_OptionGroup::getValue('activity_type',
245 'Update Recurring Contribution',
246 'name'
247 ),
248 'subject' => ts('Recurring Contribution Updated'),
249 'details' => $message,
250 'activity_date_time' => date('YmdHis'),
251 'status_id' => CRM_Core_OptionGroup::getValue('activity_status',
252 'Completed',
253 'name'
254 ),
255 );
256 $session = CRM_Core_Session::singleton();
257 $cid = $session->get('userID');
258
259 if ($cid) {
260 $activityParams['target_contact_id'][] = $activityParams['source_contact_id'];
261 $activityParams['source_contact_id'] = $cid;
262 }
263 CRM_Activity_BAO_Activity::create($activityParams);
264
265 if (CRM_Utils_Array::value('is_notify', $params)) {
266 // send notification
267 if ($this->_subscriptionDetails->contribution_page_id) {
268 CRM_Core_DAO::commonRetrieveAll('CRM_Contribute_DAO_ContributionPage', 'id',
269 $this->_subscriptionDetails->contribution_page_id, $value, array(
270 'title',
271 'receipt_from_name',
272 'receipt_from_email',
273 )
274 );
275 $receiptFrom = '"' . CRM_Utils_Array::value('receipt_from_name', $value[$this->_subscriptionDetails->contribution_page_id]) . '" <' . $value[$this->_subscriptionDetails->contribution_page_id]['receipt_from_email'] . '>';
276 }
277 else {
278 $domainValues = CRM_Core_BAO_Domain::getNameAndEmail();
279 $receiptFrom = "$domainValues[0] <$domainValues[1]>";
280 }
281
282 list($donorDisplayName, $donorEmail) = CRM_Contact_BAO_Contact::getContactDetails($contactID);
283
284 $tplParams = array(
285 'recur_frequency_interval' => $this->_subscriptionDetails->frequency_interval,
286 'recur_frequency_unit' => $this->_subscriptionDetails->frequency_unit,
287 'amount' => CRM_Utils_Money::format($params['amount']),
288 'installments' => $params['installments'],
289 );
290
291 $tplParams['contact'] = array('display_name' => $donorDisplayName);
292 $tplParams['receipt_from_email'] = $receiptFrom;
293
294 $sendTemplateParams = array(
295 'groupName' => 'msg_tpl_workflow_contribution',
296 'valueName' => 'contribution_recurring_edit',
297 'contactId' => $contactID,
298 'tplParams' => $tplParams,
299 'isTest' => $this->_subscriptionDetails->is_test,
300 'PDFFilename' => 'receipt.pdf',
301 'from' => $receiptFrom,
302 'toName' => $donorDisplayName,
303 'toEmail' => $donorEmail,
304 );
305 list($sent) = CRM_Core_BAO_MessageTemplates::sendTemplate($sendTemplateParams);
306 }
307 }
308
309 $session = CRM_Core_Session::singleton();
310 $userID = $session->get('userID');
311 if ( $userID && $status) {
312 CRM_Core_Session::setStatus($status, $msgTitle, $msgType);
313 } else if (!$userID) {
314 if ($status)
315 CRM_Utils_System::setUFMessage($status);
316 // keep result as 1, since we not displaying anything on the redirected page anyway
317 return CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contribute/subscriptionstatus',
318 "reset=1&task=update&result=1"));
319 }
320 }
321}
322