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