Merge pull request #6680 from colemanw/cleanup
[civicrm-core.git] / CRM / Contribute / Form / UpdateSubscription.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
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-2015
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.
40 */
41 class 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 /**
61 * The id of the contact associated with this recurring contribution.
62 *
63 * @var int
64 */
65 public $_contactID;
66
67 public function preProcess() {
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 }
82 elseif ($this->_crid) {
83 $this->_coid = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $this->_crid, 'id', 'contribution_recur_id');
84 }
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')) {
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.');
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 * Set default values for the form.
127 *
128 * Note that in edit/view mode the default values are retrieved from the database.
129 */
130 public function setDefaultValues() {
131
132 $this->_defaults = array();
133 $this->_defaults['amount'] = $this->_subscriptionDetails->amount;
134 $this->_defaults['installments'] = $this->_subscriptionDetails->installments;
135 $this->_defaults['is_notify'] = 1;
136
137 return $this->_defaults;
138 }
139
140 /**
141 * Actually build the components of the form.
142 */
143 public function buildQuickForm() {
144 // CRM-16398: If current recurring contribution got > 1 lineitems then make amount field readonly
145 $amtAttr = array('size' => 20);
146 $lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($this->_coid);
147 if (count($lineItems) > 1) {
148 $amtAttr += array('readonly' => TRUE);
149 }
150 $this->addMoney('amount', ts('Recurring Contribution Amount'), TRUE, $amtAttr,
151 TRUE, 'currency', $this->_subscriptionDetails->currency, TRUE
152 );
153
154 $this->add('text', 'installments', ts('Number of Installments'), array('size' => 20), TRUE);
155
156 if ($this->_donorEmail) {
157 $this->add('checkbox', 'is_notify', ts('Notify Contributor?'));
158 }
159
160 $type = 'next';
161 if ($this->_selfService) {
162 $type = 'submit';
163 }
164
165 // define the buttons
166 $this->addButtons(array(
167 array(
168 'type' => $type,
169 'name' => ts('Save'),
170 'isDefault' => TRUE,
171 ),
172 array(
173 'type' => 'cancel',
174 'name' => ts('Cancel'),
175 ),
176 )
177 );
178 }
179
180 /**
181 * Called after the user submits the form.
182 */
183 public function postProcess() {
184 // store the submitted values in an array
185 $params = $this->exportValues();
186
187 if ($this->_selfService && $this->_donorEmail) {
188 // for self service force notify
189 $params['is_notify'] = 1;
190 }
191
192 // if this is an update of an existing recurring contribution, pass the ID
193 $params['id'] = $this->_subscriptionDetails->recur_id;
194 $message = '';
195
196 $params['subscriptionId'] = $this->_subscriptionDetails->subscription_id;
197 $updateSubscription = TRUE;
198 if ($this->_paymentProcessorObj->isSupported('changeSubscriptionAmount')) {
199 $updateSubscription = $this->_paymentProcessorObj->changeSubscriptionAmount($message, $params);
200 }
201 if (is_a($updateSubscription, 'CRM_Core_Error')) {
202 CRM_Core_Error::displaySessionError($updateSubscription);
203 $status = ts('Could not update the Recurring contribution details');
204 $msgTitle = ts('Update Error');
205 $msgType = 'error';
206 }
207 elseif ($updateSubscription) {
208 // save the changes
209 $result = CRM_Contribute_BAO_ContributionRecur::add($params);
210 $status = ts('Recurring contribution has been updated to: %1, every %2 %3(s) for %4 installments.',
211 array(
212 1 => CRM_Utils_Money::format($params['amount'], $this->_subscriptionDetails->currency),
213 2 => $this->_subscriptionDetails->frequency_interval,
214 3 => $this->_subscriptionDetails->frequency_unit,
215 4 => $params['installments'],
216 )
217 );
218
219 $msgTitle = ts('Update Success');
220 $msgType = 'success';
221 $msg = ts('Recurring Contribution Updated');
222 $contactID = $this->_subscriptionDetails->contact_id;
223
224 if ($this->_subscriptionDetails->amount != $params['amount']) {
225 $message .= "<br /> " . ts("Recurring contribution amount has been updated from %1 to %2 for this subscription.",
226 array(
227 1 => CRM_Utils_Money::format($this->_subscriptionDetails->amount, $this->_subscriptionDetails->currency),
228 2 => CRM_Utils_Money::format($params['amount'], $this->_subscriptionDetails->currency),
229 )) . ' ';
230 if ($this->_subscriptionDetails->amount < $params['amount']) {
231 $msg = ts('Recurring Contribution Updated - increased installment amount');
232 }
233 else {
234 $msg = ts('Recurring Contribution Updated - decreased installment amount');
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(
240 1 => $this->_subscriptionDetails->installments,
241 2 => $params['installments'],
242 )) . ' ';
243 }
244
245 $activityParams = array(
246 'source_contact_id' => $contactID,
247 'activity_type_id' => CRM_Core_OptionGroup::getValue('activity_type',
248 'Update Recurring Contribution',
249 'name'
250 ),
251 'subject' => $msg,
252 'details' => $message,
253 'activity_date_time' => date('YmdHis'),
254 'status_id' => CRM_Core_OptionGroup::getValue('activity_status',
255 'Completed',
256 'name'
257 ),
258 );
259 $session = CRM_Core_Session::singleton();
260 $cid = $session->get('userID');
261
262 if ($cid) {
263 $activityParams['target_contact_id'][] = $activityParams['source_contact_id'];
264 $activityParams['source_contact_id'] = $cid;
265 }
266 CRM_Activity_BAO_Activity::create($activityParams);
267
268 if (!empty($params['is_notify'])) {
269 // send notification
270 if ($this->_subscriptionDetails->contribution_page_id) {
271 CRM_Core_DAO::commonRetrieveAll('CRM_Contribute_DAO_ContributionPage', 'id',
272 $this->_subscriptionDetails->contribution_page_id, $value, array(
273 'title',
274 'receipt_from_name',
275 'receipt_from_email',
276 )
277 );
278 $receiptFrom = '"' . CRM_Utils_Array::value('receipt_from_name', $value[$this->_subscriptionDetails->contribution_page_id]) . '" <' . $value[$this->_subscriptionDetails->contribution_page_id]['receipt_from_email'] . '>';
279 }
280 else {
281 $domainValues = CRM_Core_BAO_Domain::getNameAndEmail();
282 $receiptFrom = "$domainValues[0] <$domainValues[1]>";
283 }
284
285 list($donorDisplayName, $donorEmail) = CRM_Contact_BAO_Contact::getContactDetails($contactID);
286
287 $tplParams = array(
288 'recur_frequency_interval' => $this->_subscriptionDetails->frequency_interval,
289 'recur_frequency_unit' => $this->_subscriptionDetails->frequency_unit,
290 'amount' => CRM_Utils_Money::format($params['amount']),
291 'installments' => $params['installments'],
292 );
293
294 $tplParams['contact'] = array('display_name' => $donorDisplayName);
295 $tplParams['receipt_from_email'] = $receiptFrom;
296
297 $sendTemplateParams = array(
298 'groupName' => 'msg_tpl_workflow_contribution',
299 'valueName' => 'contribution_recurring_edit',
300 'contactId' => $contactID,
301 'tplParams' => $tplParams,
302 'isTest' => $this->_subscriptionDetails->is_test,
303 'PDFFilename' => 'receipt.pdf',
304 'from' => $receiptFrom,
305 'toName' => $donorDisplayName,
306 'toEmail' => $donorEmail,
307 );
308 list($sent) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams);
309 }
310 }
311
312 $session = CRM_Core_Session::singleton();
313 $userID = $session->get('userID');
314 if ($userID && $status) {
315 CRM_Core_Session::setStatus($status, $msgTitle, $msgType);
316 }
317 elseif (!$userID) {
318 if ($status) {
319 CRM_Utils_System::setUFMessage($status);
320 }
321 // keep result as 1, since we not displaying anything on the redirected page anyway
322 return CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contribute/subscriptionstatus',
323 "reset=1&task=update&result=1"));
324 }
325 }
326
327 }