3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2017 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2017
35 * This class generates form components for processing a pledge
37 class CRM_Pledge_Form_Pledge
extends CRM_Core_Form
{
41 * The id of the pledge that we are proceessing.
48 * The id of the contact associated with this pledge.
55 * The Pledge values if an existing pledge.
60 * The Pledge frequency Units.
65 * Is current pledge pending.
67 public $_isPending = FALSE;
70 * Set variables up before form is built.
72 public function preProcess() {
73 $this->_contactID
= CRM_Utils_Request
::retrieve('cid', 'Positive', $this);
74 $this->_action
= CRM_Utils_Request
::retrieve('action', 'String',
77 $this->_id
= CRM_Utils_Request
::retrieve('id', 'Positive', $this);
78 $this->_context
= CRM_Utils_Request
::retrieve('context', 'String', $this);
80 // check for action permissions.
81 if (!CRM_Core_Permission
::checkActionPermission('CiviPledge', $this->_action
)) {
82 CRM_Core_Error
::fatal(ts('You do not have permission to access this page.'));
85 $this->assign('action', $this->_action
);
86 $this->assign('context', $this->_context
);
87 if ($this->_action
& CRM_Core_Action
::DELETE
) {
91 $this->userDisplayName
= $this->userEmail
= NULL;
92 if ($this->_contactID
) {
93 list($this->userDisplayName
,
95 ) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($this->_contactID
);
96 $this->assign('displayName', $this->userDisplayName
);
99 $this->setPageTitle(ts('Pledge'));
102 CRM_Custom_Form_CustomData
::preProcess($this, NULL, NULL, 1, 'Pledge', $this->_id
);
103 $this->_values
= array();
106 // get the contribution id
107 $this->_contributionID
= CRM_Core_DAO
::getFieldValue('CRM_Pledge_DAO_PledgePayment',
108 $this->_id
, 'contribution_id', 'pledge_id'
110 $params = array('id' => $this->_id
);
111 CRM_Pledge_BAO_Pledge
::getValues($params, $this->_values
);
113 $this->_isPending
= (CRM_Pledge_BAO_Pledge
::pledgeHasFinancialTransactions($this->_id
, CRM_Utils_Array
::value('status_id', $this->_values
))) ?
FALSE : TRUE;
116 // get the pledge frequency units.
117 $this->_freqUnits
= CRM_Core_OptionGroup
::values('recur_frequency_units');
119 $this->_fromEmails
= CRM_Core_BAO_Email
::getFromEmail();
124 * Set default values for the form.
125 * The default values are retrieved from the database.
127 public function setDefaultValues() {
128 $defaults = $this->_values
;
131 if ($this->_action
& CRM_Core_Action
::DELETE
) {
135 if (!empty($defaults['is_test'])) {
136 $this->assign('is_test', TRUE);
140 $startDate = CRM_Utils_Array
::value('start_date', $this->_values
);
141 $createDate = CRM_Utils_Array
::value('create_date', $this->_values
);
142 list($defaults['start_date']) = CRM_Utils_Date
::setDateDefaults($startDate);
143 list($defaults['create_date']) = CRM_Utils_Date
::setDateDefaults($createDate);
145 if ($ackDate = CRM_Utils_Array
::value('acknowledge_date', $this->_values
)) {
146 list($defaults['acknowledge_date']) = CRM_Utils_Date
::setDateDefaults($ackDate);
149 // check is this pledge pending.
150 // fix the display of the monetary value, CRM-4038.
151 if ($this->_isPending
) {
152 $defaults['eachPaymentAmount'] = $this->_values
['amount'] / $this->_values
['installments'];
153 $defaults['eachPaymentAmount'] = CRM_Utils_Money
::format($defaults['eachPaymentAmount'], NULL, '%a');
156 $this->assign('start_date', $startDate);
157 $this->assign('create_date', $createDate);
159 // fix the display of the monetary value, CRM-4038
160 if (isset($this->_values
['amount'])) {
161 $defaults['amount'] = CRM_Utils_Money
::format($this->_values
['amount'], NULL, '%a');
163 $this->assign('amount', $this->_values
['amount']);
164 $this->assign('installments', $defaults['installments']);
168 list($now) = CRM_Utils_Date
::setDateDefaults();
169 $defaults['create_date'] = $now;
170 $defaults['start_date'] = $now;
171 $defaults['installments'] = 12;
172 $defaults['frequency_interval'] = 1;
173 $defaults['frequency_day'] = 1;
174 $defaults['initial_reminder_day'] = 5;
175 $defaults['max_reminders'] = 1;
176 $defaults['additional_reminder_day'] = 5;
177 $defaults['frequency_unit'] = array_search('month', $this->_freqUnits
);
178 $defaults['financial_type_id'] = array_search('Donation', CRM_Contribute_PseudoConstant
::financialType());
181 $pledgeStatus = CRM_Pledge_BAO_Pledge
::buildOptions('status_id');
182 $pledgeStatusNames = CRM_Core_OptionGroup
::values('pledge_status',
183 FALSE, FALSE, FALSE, NULL, 'name', TRUE
185 // get default status label (pending)
186 $defaultPledgeStatus = CRM_Utils_Array
::value(array_search('Pending', $pledgeStatusNames),
191 $this->assign('status', CRM_Utils_Array
::value(CRM_Utils_Array
::value('status_id', $this->_values
),
196 if (isset($this->userEmail
)) {
197 $this->assign('email', $this->userEmail
);
200 // custom data set defaults
201 $defaults +
= CRM_Custom_Form_CustomData
::setDefaultValues($this);
207 * Build the form object.
209 public function buildQuickForm() {
210 if ($this->_action
& CRM_Core_Action
::DELETE
) {
211 $this->addButtons(array(
214 'name' => ts('Delete'),
215 'spacing' => ' ',
220 'name' => ts('Cancel'),
227 if ($this->_context
== 'standalone') {
228 $this->addEntityRef('contact_id', ts('Contact'), array(
230 'api' => array('extra' => array('email')),
234 $showAdditionalInfo = FALSE;
235 $this->_formType
= CRM_Utils_Array
::value('formType', $_GET);
240 'Payment Reminders' => 'PaymentReminders',
242 foreach ($paneNames as $name => $type) {
243 $urlParams = "snippet=4&formType={$type}";
244 $allPanes[$name] = array(
245 'url' => CRM_Utils_System
::url('civicrm/contact/view/pledge', $urlParams),
249 // see if we need to include this paneName in the current form
250 if ($this->_formType
== $type ||
!empty($_POST["hidden_{$type}"]) ||
251 CRM_Utils_Array
::value("hidden_{$type}", $defaults)
253 $showAdditionalInfo = TRUE;
254 $allPanes[$name]['open'] = 'true';
256 $fnName = "build{$type}";
257 CRM_Contribute_Form_AdditionalInfo
::$fnName($this);
260 $this->assign('allPanes', $allPanes);
261 $this->assign('showAdditionalInfo', $showAdditionalInfo);
263 if ($this->_formType
) {
264 $this->assign('formType', $this->_formType
);
268 $this->applyFilter('__ALL__', 'trim');
271 $attributes = CRM_Core_DAO
::getAttribute('CRM_Pledge_DAO_Pledge');
273 $this->assign('isPending', $this->_isPending
);
276 'onblur' => "calculatedPaymentAmount( );",
277 'onkeyup' => "calculatedPaymentAmount( );",
280 $currencyFreeze = FALSE;
284 $currencyFreeze = TRUE;
287 $element = $this->addMoney('amount', ts('Total Pledge Amount'), TRUE,
288 array_merge($attributes['pledge_amount'], $js), TRUE,
289 'currency', NULL, $currencyFreeze
298 $element = &$this->add('text', 'installments', ts('To be paid in'),
299 array_merge($attributes['installments'], $js), TRUE
301 $this->addRule('installments', ts('Please enter a valid number of installments.'), 'positiveInteger');
308 $element = &$this->add('text', 'frequency_interval', ts('every'),
309 $attributes['pledge_frequency_interval'], TRUE
311 $this->addRule('frequency_interval', ts('Please enter a number for frequency (e.g. every "3" months).'), 'positiveInteger');
318 // Fix frequency unit display for use with frequency_interval
319 $freqUnitsDisplay = array();
320 foreach ($this->_freqUnits
as $val => $label) {
321 $freqUnitsDisplay[$val] = ts('%1(s)', array(1 => $label));
323 $element = &$this->add('select', 'frequency_unit',
325 array('' => ts('- select -')) +
$freqUnitsDisplay,
335 $element = &$this->add('text', 'frequency_day', ts('Payments are due on the'), $attributes['frequency_day'], TRUE);
336 $this->addRule('frequency_day', ts('Please enter a valid payment due day.'), 'positiveInteger');
343 $this->add('text', 'eachPaymentAmount', ts('each'), array(
345 'style' => "background-color:#EBECE4",
346 0 => 'READONLY', // WTF, preserved because its inexplicable
350 if (!$this->_id ||
$this->_isPending
) {
351 $this->addDate('create_date', ts('Pledge Made'), TRUE);
352 $this->addDate('start_date', ts('Payments Start'), TRUE);
355 if (!empty($this->_values
['currency'])) {
356 $this->assign('currency', $this->_values
['currency']);
358 elseif (!empty($this->_submitValues
['currency'])) {
359 $this->assign('currency', $this->_submitValues
['currency']);
365 $eachPaymentAmount = $this->_values
['original_installment_amount'];
366 $this->assign('eachPaymentAmount', $eachPaymentAmount);
367 $this->assign('hideCalender', TRUE);
370 if (CRM_Utils_Array
::value('status_id', $this->_values
) !=
371 CRM_Core_PseudoConstant
::getKey('CRM_Pledge_BAO_Pledge', 'status_id', 'Cancelled')
374 $this->addElement('checkbox', 'is_acknowledge', ts('Send Acknowledgment?'), NULL,
375 array('onclick' => "showHideByValue( 'is_acknowledge', '', 'acknowledgeDate', 'table-row', 'radio', true); showHideByValue( 'is_acknowledge', '', 'fromEmail', 'table-row', 'radio', false );")
378 $this->add('select', 'from_email_address', ts('Receipt From'), $this->_fromEmails
);
381 $this->addDate('acknowledge_date', ts('Acknowledgment Date'));
383 $this->add('select', 'financial_type_id',
384 ts('Financial Type'),
385 array('' => ts('- select -')) + CRM_Contribute_PseudoConstant
::financialType(),
389 // CRM-7362 --add campaigns.
390 CRM_Campaign_BAO_Campaign
::addCampaign($this, CRM_Utils_Array
::value('campaign_id', $this->_values
));
393 CRM_Core_DAO
::commonRetrieveAll('CRM_Pledge_DAO_PledgeBlock', 'entity_table',
394 'civicrm_contribution_page', $pageIds, array('entity_id')
396 $pages = CRM_Contribute_PseudoConstant
::contributionPage();
397 $pledgePages = array();
398 foreach ($pageIds as $key => $value) {
399 $pledgePages[$value['entity_id']] = $pages[$value['entity_id']];
401 $ele = $this->add('select', 'contribution_page_id', ts('Self-service Payments Page'),
402 array('' => ts('- select -')) +
$pledgePages
405 $mailingInfo = Civi
::settings()->get('mailing_backend');
406 $this->assign('outBound_option', $mailingInfo['outBound_option']);
409 CRM_Custom_Form_CustomData
::buildQuickForm($this);
411 // make this form an upload since we dont know if the custom data injected dynamically
412 // is of type file etc $uploadNames = $this->get( 'uploadNames' );
413 $this->addButtons(array(
416 'name' => ts('Save'),
417 'js' => array('onclick' => "return verify( );"),
422 'name' => ts('Save and New'),
423 'js' => array('onclick' => "return verify( );"),
428 'name' => ts('Cancel'),
433 $this->addFormRule(array('CRM_Pledge_Form_Pledge', 'formRule'), $this);
435 if ($this->_action
& CRM_Core_Action
::VIEW
) {
443 * @param array $fields
444 * The input form values.
445 * @param array $files
446 * The uploaded files if any.
451 * true if no errors, else array of errors
453 public static function formRule($fields, $files, $self) {
456 if ($fields['amount'] <= 0) {
457 $errors['amount'] = ts('Total Pledge Amount should be greater than zero.');
459 if ($fields['installments'] <= 0) {
460 $errors['installments'] = ts('Installments should be greater than zero.');
463 if ($fields['frequency_unit'] != 'week') {
464 if ($fields['frequency_day'] > 31 ||
$fields['frequency_day'] == 0) {
465 $errors['frequency_day'] = ts('Please enter a valid frequency day ie. 1 through 31.');
468 elseif ($fields['frequency_unit'] == 'week') {
469 if ($fields['frequency_day'] > 7 ||
$fields['frequency_day'] == 0) {
470 $errors['frequency_day'] = ts('Please enter a valid frequency day ie. 1 through 7.');
477 * Process the form submission.
479 public function postProcess() {
480 if ($this->_action
& CRM_Core_Action
::DELETE
) {
481 CRM_Pledge_BAO_Pledge
::deletePledge($this->_id
);
485 // get the submitted form values.
486 $formValues = $this->controller
->exportValues($this->_name
);
488 // set the contact, when contact is selected
489 if (!empty($formValues['contact_id'])) {
490 $this->_contactID
= $formValues['contact_id'];
493 $session = CRM_Core_Session
::singleton();
497 'frequency_interval',
501 'initial_reminder_day',
503 'additional_reminder_day',
504 'contribution_page_id',
507 foreach ($fields as $f) {
508 $params[$f] = CRM_Utils_Array
::value($f, $formValues);
512 $params['amount'] = CRM_Utils_Rule
::cleanMoney(CRM_Utils_Array
::value('amount', $formValues));
513 $params['currency'] = CRM_Utils_Array
::value('currency', $formValues);
514 $params['original_installment_amount'] = ($params['amount'] / $params['installments']);
516 $dates = array('create_date', 'start_date', 'acknowledge_date', 'cancel_date');
517 foreach ($dates as $d) {
518 if ($this->_id
&& (!$this->_isPending
) && !empty($this->_values
[$d])) {
519 if ($d == 'start_date') {
520 $params['scheduled_date'] = CRM_Utils_Date
::processDate($this->_values
[$d]);
522 $params[$d] = CRM_Utils_Date
::processDate($this->_values
[$d]);
524 elseif (!empty($formValues[$d]) && !CRM_Utils_System
::isNull($formValues[$d])) {
525 if ($d == 'start_date') {
526 $params['scheduled_date'] = CRM_Utils_Date
::processDate($formValues[$d]);
528 $params[$d] = CRM_Utils_Date
::processDate($formValues[$d]);
531 $params[$d] = 'null';
535 if (!empty($formValues['is_acknowledge'])) {
536 $params['acknowledge_date'] = date('Y-m-d');
539 // assign id only in update mode
540 if ($this->_action
& CRM_Core_Action
::UPDATE
) {
541 $params['id'] = $this->_id
;
544 $params['contact_id'] = $this->_contactID
;
546 // format custom data
547 if (!empty($formValues['hidden_custom'])) {
548 $params['hidden_custom'] = 1;
550 $customFields = CRM_Core_BAO_CustomField
::getFields('Pledge');
551 $params['custom'] = CRM_Core_BAO_CustomField
::postProcess($formValues,
557 // handle pending pledge.
558 $params['is_pledge_pending'] = $this->_isPending
;
560 // create pledge record.
561 $pledge = CRM_Pledge_BAO_Pledge
::create($params);
566 // set the status msg.
567 if ($this->_action
& CRM_Core_Action
::ADD
) {
568 $statusMsg = ts('Pledge has been recorded and the payment schedule has been created.<br />');
570 elseif ($this->_action
& CRM_Core_Action
::UPDATE
) {
571 $statusMsg = ts('Pledge has been updated.<br />');
575 // handle Acknowledgment.
576 if (!empty($formValues['is_acknowledge']) && $pledge->id
) {
578 // calculate scheduled amount.
579 $params['scheduled_amount'] = round($params['amount'] / $params['installments']);
580 $params['total_pledge_amount'] = $params['amount'];
581 // get some required pledge values in params.
582 $params['id'] = $pledge->id
;
583 $params['acknowledge_date'] = $pledge->acknowledge_date
;
584 $params['is_test'] = $pledge->is_test
;
585 $params['currency'] = $pledge->currency
;
586 // retrieve 'from email id' for acknowledgement
587 $params['from_email_id'] = $formValues['from_email_address'];
589 $this->paymentId
= NULL;
590 // send Acknowledgment mail.
591 CRM_Pledge_BAO_Pledge
::sendAcknowledgment($this, $params);
593 if (!isset($this->userEmail
)) {
594 list($this->userDisplayName
,
596 ) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($this->_contactID
);
599 $statusMsg .= ' ' . ts("An acknowledgment email has been sent to %1.<br />", array(1 => $this->userEmail
));
601 // build the payment urls.
602 if ($this->paymentId
) {
603 $urlParams = "reset=1&action=add&cid={$this->_contactID}&ppid={$this->paymentId}&context=pledge";
604 $contribURL = CRM_Utils_System
::url('civicrm/contact/view/contribution', $urlParams);
605 $urlParams .= "&mode=live";
606 $creditURL = CRM_Utils_System
::url('civicrm/contact/view/contribution', $urlParams);
608 // check if we can process credit card payment.
609 $processors = CRM_Core_PseudoConstant
::paymentProcessor(FALSE, FALSE,
610 "billing_mode IN ( 1, 3 )"
612 if (count($processors) > 0) {
613 $statusMsg .= ' ' . ts("If a payment is due now, you can record <a href='%1'>a check, EFT, or cash payment for this pledge</a> OR <a href='%2'>submit a credit card payment</a>.", array(
619 $statusMsg .= ' ' . ts("If a payment is due now, you can record <a href='%1'>a check, EFT, or cash payment for this pledge</a>.", array(1 => $contribURL));
623 CRM_Core_Session
::setStatus($statusMsg, ts('Payment Due'), 'info');
625 $buttonName = $this->controller
->getButtonName();
626 if ($this->_context
== 'standalone') {
627 if ($buttonName == $this->getButtonName('upload', 'new')) {
628 $session->replaceUserContext(CRM_Utils_System
::url('civicrm/pledge/add',
629 'reset=1&action=add&context=standalone'
633 $session->replaceUserContext(CRM_Utils_System
::url('civicrm/contact/view',
634 "reset=1&cid={$this->_contactID}&selectedChild=pledge"
638 elseif ($buttonName == $this->getButtonName('upload', 'new')) {
639 $session->replaceUserContext(CRM_Utils_System
::url('civicrm/contact/view/pledge',
640 "reset=1&action=add&context=pledge&cid={$this->_contactID}"