Ian province abbreviation patch - issue 724
[civicrm-core.git] / CRM / Member / Form / Membership.php
... / ...
CommitLineData
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 for offline membership form.
36 */
37class CRM_Member_Form_Membership extends CRM_Member_Form {
38
39 protected $_memType = NULL;
40
41 protected $_onlinePendingContributionId;
42
43 public $_mode;
44
45 public $_contributeMode = 'direct';
46
47 protected $_recurMembershipTypes;
48
49 protected $_memTypeSelected;
50
51 /**
52 * Display name of the member.
53 *
54 * @var string
55 */
56 protected $_memberDisplayName = NULL;
57
58 /**
59 * email of the person paying for the membership (used for receipts)
60 */
61 protected $_memberEmail = NULL;
62
63 /**
64 * Contact ID of the member.
65 *
66 * @var int
67 */
68 public $_contactID = NULL;
69
70 /**
71 * Display name of the person paying for the membership (used for receipts)
72 *
73 * @var string
74 */
75 protected $_contributorDisplayName = NULL;
76
77 /**
78 * email of the person paying for the membership (used for receipts)
79 */
80 protected $_contributorEmail = NULL;
81
82 /**
83 * email of the person paying for the membership (used for receipts)
84 *
85 * @var int
86 */
87 protected $_contributorContactID = NULL;
88
89 /**
90 * ID of the person the receipt is to go to.
91 *
92 * @var int
93 */
94 protected $_receiptContactId = NULL;
95
96 /**
97 * Keep a class variable for ALL membership IDs so
98 * postProcess hook function can do something with it
99 *
100 * @var array
101 */
102 protected $_membershipIDs = array();
103
104 /**
105 * An array to hold a list of date fields on the form
106 * so that they can be converted to ISO in a consistent manner
107 *
108 * @var array
109 */
110 protected $_dateFields = array(
111 'receive_date' => array('default' => 'now'),
112 );
113
114 /**
115 * Get selected membership type from the form values.
116 *
117 * @param array $priceSet
118 * @param array $params
119 *
120 * @return array
121 */
122 public static function getSelectedMemberships($priceSet, $params) {
123 $memTypeSelected = array();
124 $priceFieldIDS = self::getPriceFieldIDs($params, $priceSet);
125 if (isset($params['membership_type_id']) && !empty($params['membership_type_id'][1])) {
126 $memTypeSelected = array($params['membership_type_id'][1] => $params['membership_type_id'][1]);
127 }
128 else {
129 foreach ($priceFieldIDS as $priceFieldId) {
130 if ($id = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceFieldValue', $priceFieldId, 'membership_type_id')) {
131 $memTypeSelected[$id] = $id;
132 }
133 }
134 }
135 return $memTypeSelected;
136 }
137
138 /**
139 * Extract price set fields and values from $params.
140 *
141 * @param array $params
142 * @param array $priceSet
143 *
144 * @return array
145 */
146 public static function getPriceFieldIDs($params, $priceSet) {
147 $priceFieldIDS = $fieldIds = array();
148 if (isset($priceSet['fields']) && is_array($priceSet['fields'])) {
149 $fieldIds = array_keys($priceSet['fields']);
150 foreach ($fieldIds as $fieldId) {
151 if (!empty($params['price_' . $fieldId])) {
152 if (is_array($params['price_' . $fieldId])) {
153 foreach ($params['price_' . $fieldId] as $priceFldVal => $isSet) {
154 if ($isSet) {
155 $priceFieldIDS[] = $priceFldVal;
156 }
157 }
158 }
159 else {
160 $priceFieldIDS[] = $params['price_' . $fieldId];
161 }
162 }
163 }
164 }
165 return $priceFieldIDS;
166 }
167
168 /**
169 * Form preProcess function.
170 *
171 * @throws \Exception
172 */
173 public function preProcess() {
174 // This string makes up part of the class names, differentiating them (not sure why) from the membership fields.
175 $this->assign('formClass', 'membership');
176 parent::preProcess();
177 // get price set id.
178 $this->_priceSetId = CRM_Utils_Array::value('priceSetId', $_GET);
179 $this->set('priceSetId', $this->_priceSetId);
180 $this->assign('priceSetId', $this->_priceSetId);
181
182 if ($this->_action & CRM_Core_Action::DELETE) {
183 $contributionID = CRM_Member_BAO_Membership::getMembershipContributionId($this->_id);
184 // check delete permission for contribution
185 if ($this->_id && $contributionID && !CRM_Core_Permission::checkActionPermission('CiviContribute', $this->_action)) {
186 CRM_Core_Error::fatal(ts("This Membership is linked to a contribution. You must have 'delete in CiviContribute' permission in order to delete this record."));
187 }
188 }
189
190 if ($this->_action & CRM_Core_Action::ADD) {
191 if (!CRM_Member_BAO_Membership::statusAvailabilty($this->_contactID)) {
192 // all possible statuses are disabled - redirect back to contact form
193 CRM_Core_Error::statusBounce(ts('There are no configured membership statuses. You cannot add this membership until your membership statuses are correctly configured'));
194 }
195 if ($this->_contactID) {
196 //check whether contact has a current membership so we can alert user that they may want to do a renewal instead
197 $contactMemberships = array();
198 $memParams = array('contact_id' => $this->_contactID);
199 CRM_Member_BAO_Membership::getValues($memParams, $contactMemberships, TRUE);
200 $cMemTypes = array();
201 foreach ($contactMemberships as $mem) {
202 $cMemTypes[] = $mem['membership_type_id'];
203 }
204 if (count($cMemTypes) > 0) {
205 $memberorgs = CRM_Member_BAO_MembershipType::getMemberOfContactByMemTypes($cMemTypes);
206 $mems_by_org = array();
207 foreach ($contactMemberships as $mem) {
208 $mem['member_of_contact_id'] = CRM_Utils_Array::value($mem['membership_type_id'], $memberorgs);
209 if (!empty($mem['membership_end_date'])) {
210 $mem['membership_end_date'] = CRM_Utils_Date::customformat($mem['membership_end_date']);
211 }
212 $mem['membership_type'] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType',
213 $mem['membership_type_id'],
214 'name', 'id'
215 );
216 $mem['membership_status'] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipStatus',
217 $mem['status_id'],
218 'label', 'id'
219 );
220 $mem['renewUrl'] = CRM_Utils_System::url('civicrm/contact/view/membership',
221 "reset=1&action=renew&cid={$this->_contactID}&id={$mem['id']}&context=membership&selectedChild=member"
222 . ($this->_mode ? '&mode=live' : '')
223 );
224 $mem['membershipTab'] = CRM_Utils_System::url('civicrm/contact/view',
225 "reset=1&force=1&cid={$this->_contactID}&selectedChild=member"
226 );
227 $mems_by_org[$mem['member_of_contact_id']] = $mem;
228 }
229 $this->assign('existingContactMemberships', $mems_by_org);
230 }
231 }
232 else {
233 // In standalone mode we don't have a contact id yet so lookup will be done client-side with this script:
234 $resources = CRM_Core_Resources::singleton();
235 $resources->addScriptFile('civicrm', 'templates/CRM/Member/Form/MembershipStandalone.js');
236 $passthru = array(
237 'typeorgs' => CRM_Member_BAO_MembershipType::getMembershipTypeOrganization(),
238 'memtypes' => CRM_Core_PseudoConstant::get('CRM_Member_BAO_Membership', 'membership_type_id'),
239 'statuses' => CRM_Core_PseudoConstant::get('CRM_Member_BAO_Membership', 'status_id'),
240 );
241 $resources->addSetting(array('existingMems' => $passthru));
242 }
243 }
244
245 // when custom data is included in this page
246 if (!empty($_POST['hidden_custom'])) {
247 CRM_Custom_Form_CustomData::preProcess($this);
248 CRM_Custom_Form_CustomData::buildQuickForm($this);
249 CRM_Custom_Form_CustomData::setDefaultValues($this);
250 }
251
252 // CRM-4395, get the online pending contribution id.
253 $this->_onlinePendingContributionId = NULL;
254 if (!$this->_mode && $this->_id && ($this->_action & CRM_Core_Action::UPDATE)) {
255 $this->_onlinePendingContributionId = CRM_Contribute_BAO_Contribution::checkOnlinePendingContribution($this->_id,
256 'Membership'
257 );
258 }
259 $this->assign('onlinePendingContributionId', $this->_onlinePendingContributionId);
260
261 $this->setPageTitle(ts('Membership'));
262 }
263
264 /**
265 * Set default values for the form.
266 */
267 public function setDefaultValues() {
268
269 if ($this->_priceSetId) {
270 return CRM_Price_BAO_PriceSet::setDefaultPriceSet($this, $defaults);
271 }
272
273 $defaults = parent::setDefaultValues();
274
275 //setting default join date and receive date
276 list($now, $currentTime) = CRM_Utils_Date::setDateDefaults();
277 if ($this->_action == CRM_Core_Action::ADD) {
278 $defaults['receive_date'] = $now;
279 $defaults['receive_date_time'] = $currentTime;
280 }
281
282 if (is_numeric($this->_memType)) {
283 $defaults['membership_type_id'] = array();
284 $defaults['membership_type_id'][0] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType',
285 $this->_memType,
286 'member_of_contact_id',
287 'id'
288 );
289 $defaults['membership_type_id'][1] = $this->_memType;
290 }
291 else {
292 $defaults['membership_type_id'] = $this->_memType;
293 }
294
295 $defaults['num_terms'] = 1;
296
297 if (!empty($defaults['id'])) {
298 if ($this->_onlinePendingContributionId) {
299 $defaults['record_contribution'] = $this->_onlinePendingContributionId;
300 }
301 else {
302 $contributionId = CRM_Core_DAO::singleValueQuery("
303 SELECT contribution_id
304 FROM civicrm_membership_payment
305 WHERE membership_id = $this->_id
306 ORDER BY contribution_id
307 DESC limit 1");
308
309 if ($contributionId) {
310 $defaults['record_contribution'] = $contributionId;
311 }
312 }
313 }
314
315 //set Soft Credit Type to Gift by default
316 $scTypes = CRM_Core_OptionGroup::values("soft_credit_type");
317 $defaults['soft_credit_type_id'] = CRM_Utils_Array::value(ts('Gift'), array_flip($scTypes));
318
319 if (!empty($defaults['record_contribution']) && !$this->_mode) {
320 $contributionParams = array('id' => $defaults['record_contribution']);
321 $contributionIds = array();
322
323 //keep main object campaign in hand.
324 $memberCampaignId = CRM_Utils_Array::value('campaign_id', $defaults);
325
326 CRM_Contribute_BAO_Contribution::getValues($contributionParams, $defaults, $contributionIds);
327
328 //get back original object campaign id.
329 $defaults['campaign_id'] = $memberCampaignId;
330
331 if (!empty($defaults['receive_date'])) {
332 list($defaults['receive_date']) = CRM_Utils_Date::setDateDefaults($defaults['receive_date']);
333 }
334
335 // Contribution::getValues() over-writes the membership record's source field value - so we need to restore it.
336 if (!empty($defaults['membership_source'])) {
337 $defaults['source'] = $defaults['membership_source'];
338 }
339 }
340 //CRM-13420
341 if (empty($defaults['payment_instrument_id'])) {
342 $defaults['payment_instrument_id'] = key(CRM_Core_OptionGroup::values('payment_instrument', FALSE, FALSE, FALSE, 'AND is_default = 1'));
343 }
344
345 // User must explicitly choose to send a receipt in both add and update mode.
346 $defaults['send_receipt'] = 0;
347
348 if ($this->_action & CRM_Core_Action::UPDATE) {
349 // in this mode by default uncheck this checkbox
350 unset($defaults['record_contribution']);
351 }
352
353 $subscriptionCancelled = FALSE;
354 if (!empty($defaults['id'])) {
355 $subscriptionCancelled = CRM_Member_BAO_Membership::isSubscriptionCancelled($this->_id);
356 }
357
358 $alreadyAutoRenew = FALSE;
359 if (!empty($defaults['contribution_recur_id']) && !$subscriptionCancelled) {
360 $defaults['auto_renew'] = 1;
361 $alreadyAutoRenew = TRUE;
362 }
363 $this->assign('alreadyAutoRenew', $alreadyAutoRenew);
364
365 $this->assign('member_is_test', CRM_Utils_Array::value('member_is_test', $defaults));
366
367 $this->assign('membership_status_id', CRM_Utils_Array::value('status_id', $defaults));
368
369 if (!empty($defaults['is_pay_later'])) {
370 $this->assign('is_pay_later', TRUE);
371 }
372 if ($this->_mode) {
373 $defaults = $this->getBillingDefaults($defaults);
374 // hack to simplify credit card entry for testing
375 // $defaults['credit_card_type'] = 'Visa';
376 // $defaults['credit_card_number'] = '4807731747657838';
377 // $defaults['cvv2'] = '000';
378 // $defaults['credit_card_exp_date'] = array( 'Y' => '2012', 'M' => '05' );
379 }
380
381 $dates = array('join_date', 'start_date', 'end_date');
382 foreach ($dates as $key) {
383 if (!empty($defaults[$key])) {
384 list($defaults[$key]) = CRM_Utils_Date::setDateDefaults(CRM_Utils_Array::value($key, $defaults));
385 }
386 }
387
388 //setting default join date if there is no join date
389 if (empty($defaults['join_date'])) {
390 $defaults['join_date'] = $now;
391 }
392
393 if (!empty($defaults['membership_end_date'])) {
394 $this->assign('endDate', $defaults['membership_end_date']);
395 }
396
397 return $defaults;
398 }
399
400 /**
401 * Build the form object.
402 */
403 public function buildQuickForm() {
404
405 $this->assign('taxRates', json_encode(CRM_Core_PseudoConstant::getTaxRates()));
406
407 $this->assign('currency', CRM_Core_Config::singleton()->defaultCurrencySymbol);
408 $invoiceSettings = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME, 'contribution_invoice_settings');
409 $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings);
410 if (isset($invoicing)) {
411 $this->assign('taxTerm', CRM_Utils_Array::value('tax_term', $invoiceSettings));
412 }
413 // build price set form.
414 $buildPriceSet = FALSE;
415 if ($this->_priceSetId || !empty($_POST['price_set_id'])) {
416 if (!empty($_POST['price_set_id'])) {
417 $buildPriceSet = TRUE;
418 }
419 $getOnlyPriceSetElements = TRUE;
420 if (!$this->_priceSetId) {
421 $this->_priceSetId = $_POST['price_set_id'];
422 $getOnlyPriceSetElements = FALSE;
423 }
424
425 $this->set('priceSetId', $this->_priceSetId);
426 CRM_Price_BAO_PriceSet::buildPriceSet($this);
427
428 $optionsMembershipTypes = array();
429 foreach ($this->_priceSet['fields'] as $pField) {
430 if (empty($pField['options'])) {
431 continue;
432 }
433 foreach ($pField['options'] as $opId => $opValues) {
434 $optionsMembershipTypes[$opId] = CRM_Utils_Array::value('membership_type_id', $opValues, 0);
435 }
436 }
437
438 $this->assign('autoRenewOption', CRM_Price_BAO_PriceSet::checkAutoRenewForPriceSet($this->_priceSetId));
439
440 $this->assign('optionsMembershipTypes', $optionsMembershipTypes);
441 $this->assign('contributionType', CRM_Utils_Array::value('financial_type_id', $this->_priceSet));
442
443 // get only price set form elements.
444 if ($getOnlyPriceSetElements) {
445 return;
446 }
447 }
448
449 // use to build form during form rule.
450 $this->assign('buildPriceSet', $buildPriceSet);
451
452 if ($this->_action & CRM_Core_Action::ADD) {
453 $buildPriceSet = FALSE;
454 $priceSets = CRM_Price_BAO_PriceSet::getAssoc(FALSE, 'CiviMember');
455 if (!empty($priceSets)) {
456 $buildPriceSet = TRUE;
457 }
458
459 if ($buildPriceSet) {
460 $this->add('select', 'price_set_id', ts('Choose price set'),
461 array(
462 '' => ts('Choose price set'),
463 ) + $priceSets,
464 NULL, array('onchange' => "buildAmount( this.value );")
465 );
466 }
467 $this->assign('hasPriceSets', $buildPriceSet);
468 }
469
470 //need to assign custom data type and subtype to the template
471 $this->assign('customDataType', 'Membership');
472 $this->assign('customDataSubType', $this->_memType);
473 $this->assign('entityID', $this->_id);
474
475 if ($this->_action & CRM_Core_Action::DELETE) {
476 $this->addButtons(array(
477 array(
478 'type' => 'next',
479 'name' => ts('Delete'),
480 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
481 'isDefault' => TRUE,
482 ),
483 array(
484 'type' => 'cancel',
485 'name' => ts('Cancel'),
486 ),
487 )
488 );
489 return;
490 }
491
492 if ($this->_context == 'standalone') {
493 $this->addEntityRef('contact_id', ts('Contact'), array(
494 'create' => TRUE,
495 'api' => array('extra' => array('email')),
496 ), TRUE);
497 }
498
499 $selOrgMemType[0][0] = $selMemTypeOrg[0] = ts('- select -');
500
501 // retrieve all memberships
502 $allMembershipInfo = array();
503 foreach ($this->allMembershipTypeDetails as $key => $values) {
504 if ($this->_mode && empty($values['minimum_fee'])) {
505 continue;
506 }
507 else {
508 $memberOfContactId = CRM_Utils_Array::value('member_of_contact_id', $values);
509 if (empty($selMemTypeOrg[$memberOfContactId])) {
510 $selMemTypeOrg[$memberOfContactId] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
511 $memberOfContactId,
512 'display_name',
513 'id'
514 );
515
516 $selOrgMemType[$memberOfContactId][0] = ts('- select -');
517 }
518 if (empty($selOrgMemType[$memberOfContactId][$key])) {
519 $selOrgMemType[$memberOfContactId][$key] = CRM_Utils_Array::value('name', $values);
520 }
521 }
522
523 // build membership info array, which is used when membership type is selected to:
524 // - set the payment information block
525 // - set the max related block
526 $allMembershipInfo[$key] = array(
527 'financial_type_id' => CRM_Utils_Array::value('financial_type_id', $values),
528 'total_amount' => CRM_Utils_Money::format($values['minimum_fee'], NULL, '%a'),
529 'total_amount_numeric' => CRM_Utils_Array::value('minimum_fee', $values),
530 'auto_renew' => CRM_Utils_Array::value('auto_renew', $values),
531 'has_related' => isset($values['relationship_type_id']),
532 'max_related' => CRM_Utils_Array::value('max_related', $values),
533 );
534 }
535
536 $this->assign('allMembershipInfo', json_encode($allMembershipInfo));
537
538 // show organization by default, if only one organization in
539 // the list
540 if (count($selMemTypeOrg) == 2) {
541 unset($selMemTypeOrg[0], $selOrgMemType[0][0]);
542 }
543 //sort membership organization and type, CRM-6099
544 natcasesort($selMemTypeOrg);
545 foreach ($selOrgMemType as $index => $orgMembershipType) {
546 natcasesort($orgMembershipType);
547 $selOrgMemType[$index] = $orgMembershipType;
548 }
549
550 $memTypeJs = array(
551 'onChange' => "buildMaxRelated(this.value,true); CRM.buildCustomData('Membership', this.value);",
552 );
553
554 if (!empty($this->_recurPaymentProcessors)) {
555 $memTypeJs['onChange'] = "" . $memTypeJs['onChange'] . 'buildAutoRenew(this.value, null);';
556 }
557
558 $this->add('text', 'max_related', ts('Max related'),
559 CRM_Core_DAO::getAttribute('CRM_Member_DAO_Membership', 'max_related')
560 );
561
562 $sel = &$this->addElement('hierselect',
563 'membership_type_id',
564 ts('Membership Organization and Type'),
565 $memTypeJs
566 );
567
568 $sel->setOptions(array($selMemTypeOrg, $selOrgMemType));
569 $elements = array();
570 if ($sel) {
571 $elements[] = $sel;
572 }
573
574 $this->applyFilter('__ALL__', 'trim');
575
576 if ($this->_action & CRM_Core_Action::ADD) {
577 $this->add('text', 'num_terms', ts('Number of Terms'), array('size' => 6));
578 }
579
580 $this->addDate('join_date', ts('Member Since'), FALSE, array('formatType' => 'activityDate'));
581 $this->addDate('start_date', ts('Start Date'), FALSE, array('formatType' => 'activityDate'));
582 $endDate = $this->addDate('end_date', ts('End Date'), FALSE, array('formatType' => 'activityDate'));
583 if ($endDate) {
584 $elements[] = $endDate;
585 }
586
587 $this->add('text', 'source', ts('Source'),
588 CRM_Core_DAO::getAttribute('CRM_Member_DAO_Membership', 'source')
589 );
590
591 //CRM-7362 --add campaigns.
592 $campaignId = NULL;
593 if ($this->_id) {
594 $campaignId = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $this->_id, 'campaign_id');
595 }
596 CRM_Campaign_BAO_Campaign::addCampaign($this, $campaignId);
597
598 if (!$this->_mode) {
599 $this->add('select', 'status_id', ts('Membership Status'),
600 array('' => ts('- select -')) + CRM_Member_PseudoConstant::membershipStatus(NULL, NULL, 'label')
601 );
602 $statusOverride = $this->addElement('checkbox', 'is_override',
603 ts('Status Override?'), NULL,
604 array('onClick' => 'showHideMemberStatus()')
605 );
606 if ($statusOverride) {
607 $elements[] = $statusOverride;
608 }
609
610 $this->addElement('checkbox', 'record_contribution', ts('Record Membership Payment?'));
611
612 $this->add('text', 'total_amount', ts('Amount'));
613 $this->addRule('total_amount', ts('Please enter a valid amount.'), 'money');
614
615 $this->addDate('receive_date', ts('Received'), FALSE, array('formatType' => 'activityDateTime'));
616
617 $this->add('select', 'payment_instrument_id',
618 ts('Payment Method'),
619 array('' => ts('- select -')) + CRM_Contribute_PseudoConstant::paymentInstrument(),
620 FALSE, array('onChange' => "return showHideByValue('payment_instrument_id','4','checkNumber','table-row','select',false);")
621 );
622 $this->add('text', 'trxn_id', ts('Transaction ID'));
623 $this->addRule('trxn_id', ts('Transaction ID already exists in Database.'),
624 'objectExists', array(
625 'CRM_Contribute_DAO_Contribution',
626 $this->_id,
627 'trxn_id',
628 )
629 );
630
631 $allowStatuses = array();
632 $statuses = CRM_Contribute_PseudoConstant::contributionStatus();
633 if ($this->_onlinePendingContributionId) {
634 $statusNames = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
635 foreach ($statusNames as $val => $name) {
636 if (in_array($name, array(
637 'In Progress',
638 'Overdue',
639 ))
640 ) {
641 continue;
642 }
643 $allowStatuses[$val] = $statuses[$val];
644 }
645 }
646 else {
647 $allowStatuses = $statuses;
648 }
649 $this->add('select', 'contribution_status_id',
650 ts('Payment Status'), $allowStatuses
651 );
652 $this->add('text', 'check_number', ts('Check Number'),
653 CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Contribution', 'check_number')
654 );
655 }
656 else {
657 //add field for amount to allow an amount to be entered that differs from minimum
658 $this->add('text', 'total_amount', ts('Amount'));
659 }
660 $this->add('select', 'financial_type_id',
661 ts('Financial Type'),
662 array('' => ts('- select -')) + CRM_Contribute_PseudoConstant::financialType()
663 );
664
665 $this->addElement('checkbox', 'is_different_contribution_contact', ts('Record Payment from a Different Contact?'));
666
667 $this->addSelect('soft_credit_type_id', array('entity' => 'contribution_soft'));
668 $this->addEntityRef('soft_credit_contact_id', ts('Payment From'), array('create' => TRUE));
669
670 $this->addElement('checkbox',
671 'send_receipt',
672 ts('Send Confirmation and Receipt?'), NULL,
673 array('onclick' => "showHideByValue( 'send_receipt', '', 'notice', 'table-row', 'radio', false); showHideByValue( 'send_receipt', '', 'fromEmail', 'table-row', 'radio', false);")
674 );
675
676 $this->add('select', 'from_email_address', ts('Receipt From'), $this->_fromEmails);
677
678 $this->add('textarea', 'receipt_text', ts('Receipt Message'));
679
680 // Retrieve the name and email of the contact - this will be the TO for receipt email
681 if ($this->_contactID) {
682 list($this->_memberDisplayName,
683 $this->_memberEmail
684 ) = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactID);
685
686 $this->assign('emailExists', $this->_memberEmail);
687 $this->assign('displayName', $this->_memberDisplayName);
688 }
689
690 $isRecur = FALSE;
691 if ($this->_action & CRM_Core_Action::UPDATE) {
692 $recurContributionId = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $this->_id,
693 'contribution_recur_id'
694 );
695 if ($recurContributionId && !CRM_Member_BAO_Membership::isSubscriptionCancelled($this->_id)) {
696 $isRecur = TRUE;
697 if (CRM_Member_BAO_Membership::isCancelSubscriptionSupported($this->_id)) {
698 $this->assign('cancelAutoRenew',
699 CRM_Utils_System::url('civicrm/contribute/unsubscribe', "reset=1&mid={$this->_id}")
700 );
701 }
702 foreach ($elements as $elem) {
703 $elem->freeze();
704 }
705 }
706 }
707 $this->assign('isRecur', $isRecur);
708
709 $this->addFormRule(array('CRM_Member_Form_Membership', 'formRule'), $this);
710
711 $this->assign('outBound_option', CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME,
712 'mailing_backend'));
713
714 parent::buildQuickForm();
715 }
716
717 /**
718 * Validation.
719 *
720 * @param array $params
721 * (ref.) an assoc array of name/value pairs.
722 *
723 * @param array $files
724 * @param CRM_Member_Form_Membership $self
725 *
726 * @throws CiviCRM_API3_Exception
727 * @return bool|array
728 * mixed true or array of errors
729 */
730 public static function formRule($params, $files, $self) {
731 $errors = array();
732
733 $priceSetId = self::getPriceSetID($params);
734 $priceSetDetails = self::getPriceSetDetails($params);
735
736 $selectedMemberships = self::getSelectedMemberships($priceSetDetails[$priceSetId], $params);
737
738 if (!empty($params['price_set_id'])) {
739 CRM_Price_BAO_PriceField::priceSetValidation($priceSetId, $params, $errors);
740
741 $priceFieldIDS = self::getPriceFieldIDs($params, $priceSetDetails);
742
743 if (!empty($priceFieldIDS)) {
744 $ids = implode(',', $priceFieldIDS);
745
746 $count = CRM_Price_BAO_PriceSet::getMembershipCount($ids);
747 foreach ($count as $occurrence) {
748 if ($occurrence > 1) {
749 $errors['_qf_default'] = ts('Select at most one option associated with the same membership type.');
750 }
751 }
752 }
753 // Return error if empty $self->_memTypeSelected
754 if (empty($errors) && empty($selectedMemberships)) {
755 $errors['_qf_default'] = ts('Select at least one membership option.');
756 }
757 if (!$self->_mode && empty($params['record_contribution'])) {
758 $errors['record_contribution'] = ts('Record Membership Payment is required when you use a price set.');
759 }
760 }
761 else {
762 if (empty($params['membership_type_id'][1])) {
763 $errors['membership_type_id'] = ts('Please select a membership type.');
764 }
765 $numterms = CRM_Utils_Array::value('num_terms', $params);
766 if ($numterms && intval($numterms) != $numterms) {
767 $errors['num_terms'] = ts('Please enter an integer for the number of terms.');
768 }
769
770 if (($self->_mode || isset($params['record_contribution'])) && empty($params['financial_type_id'])) {
771 $errors['financial_type_id'] = ts('Please enter the financial Type.');
772 }
773 }
774
775 if (!empty($errors) && (count($selectedMemberships) > 1)) {
776 $memberOfContacts = CRM_Member_BAO_MembershipType::getMemberOfContactByMemTypes($selectedMemberships);
777 $duplicateMemberOfContacts = array_count_values($memberOfContacts);
778 foreach ($duplicateMemberOfContacts as $countDuplicate) {
779 if ($countDuplicate > 1) {
780 $errors['_qf_default'] = ts('Please do not select more than one membership associated with the same organization.');
781 }
782 }
783 }
784
785 if (!empty($errors)) {
786 return $errors;
787 }
788
789 if (!empty($params['record_contribution']) && empty($params['payment_instrument_id'])) {
790 $errors['payment_instrument_id'] = ts('Payment Method is a required field.');
791 }
792
793 if (!empty($params['is_different_contribution_contact'])) {
794 if (empty($params['soft_credit_type_id'])) {
795 $errors['soft_credit_type_id'] = ts('Please Select a Soft Credit Type');
796 }
797 if (empty($params['soft_credit_contact_id'])) {
798 $errors['soft_credit_contact_id'] = ts('Please select a contact');
799 }
800 }
801
802 if (!empty($params['payment_processor_id'])) {
803 // validate payment instrument (e.g. credit card number)
804 CRM_Core_Payment_Form::validatePaymentInstrument($params['payment_processor_id'], $params, $errors, $self);
805 }
806
807 $joinDate = NULL;
808 if (!empty($params['join_date'])) {
809
810 $joinDate = CRM_Utils_Date::processDate($params['join_date']);
811
812 foreach ($selectedMemberships as $memType) {
813 $startDate = NULL;
814 if (!empty($params['start_date'])) {
815 $startDate = CRM_Utils_Date::processDate($params['start_date']);
816 }
817
818 // if end date is set, ensure that start date is also set
819 // and that end date is later than start date
820 $endDate = NULL;
821 if (!empty($params['end_date'])) {
822 $endDate = CRM_Utils_Date::processDate($params['end_date']);
823 }
824
825 $membershipDetails = CRM_Member_BAO_MembershipType::getMembershipTypeDetails($memType);
826
827 if ($startDate && CRM_Utils_Array::value('period_type', $membershipDetails) == 'rolling') {
828 if ($startDate < $joinDate) {
829 $errors['start_date'] = ts('Start date must be the same or later than Member since.');
830 }
831 }
832
833 if ($endDate) {
834 if ($membershipDetails['duration_unit'] == 'lifetime') {
835 // Check if status is NOT cancelled or similar. For lifetime memberships, there is no automated
836 // process to update status based on end-date. The user must change the status now.
837 $result = civicrm_api3('MembershipStatus', 'get', array(
838 'sequential' => 1,
839 'is_current_member' => 0,
840 ));
841 $tmp_statuses = $result['values'];
842 $status_ids = array();
843 foreach ($tmp_statuses as $cur_stat) {
844 $status_ids[] = $cur_stat['id'];
845 }
846 if (empty($params['status_id']) || in_array($params['status_id'], $status_ids) == FALSE) {
847 $errors['status_id'] = ts('Please enter a status that does NOT represent a current membership status.');
848 $errors['is_override'] = ts('This must be checked because you set an End Date for a lifetime membership');
849 }
850 }
851 else {
852 if (!$startDate) {
853 $errors['start_date'] = ts('Start date must be set if end date is set.');
854 }
855 if ($endDate < $startDate) {
856 $errors['end_date'] = ts('End date must be the same or later than start date.');
857 }
858 }
859 }
860
861 // Default values for start and end dates if not supplied on the form.
862 $defaultDates = CRM_Member_BAO_MembershipType::getDatesForMembershipType($memType,
863 $joinDate,
864 $startDate,
865 $endDate
866 );
867
868 if (!$startDate) {
869 $startDate = CRM_Utils_Array::value('start_date',
870 $defaultDates
871 );
872 }
873 if (!$endDate) {
874 $endDate = CRM_Utils_Array::value('end_date',
875 $defaultDates
876 );
877 }
878
879 //CRM-3724, check for availability of valid membership status.
880 if (empty($params['is_override']) && !isset($errors['_qf_default'])) {
881 $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($startDate,
882 $endDate,
883 $joinDate,
884 'today',
885 TRUE,
886 $memType,
887 $params
888 );
889 if (empty($calcStatus)) {
890 $url = CRM_Utils_System::url('civicrm/admin/member/membershipStatus', 'reset=1&action=browse');
891 $errors['_qf_default'] = ts('There is no valid Membership Status available for selected membership dates.');
892 $status = ts('Oops, it looks like there is no valid membership status available for the given membership dates. You can <a href="%1">Configure Membership Status Rules</a>.', array(1 => $url));
893 if (!$self->_mode) {
894 $status .= ' ' . ts('OR You can sign up by setting Status Override? to true.');
895 }
896 CRM_Core_Session::setStatus($status, ts('Membership Status Error'), 'error');
897 }
898 }
899 }
900 }
901 else {
902 $errors['join_date'] = ts('Please enter the Member Since.');
903 }
904
905 if (isset($params['is_override']) &&
906 $params['is_override'] && empty($params['status_id'])
907 ) {
908 $errors['status_id'] = ts('Please enter the status.');
909 }
910
911 //total amount condition arise when membership type having no
912 //minimum fee
913 if (isset($params['record_contribution'])) {
914 if (CRM_Utils_System::isNull($params['total_amount'])) {
915 $errors['total_amount'] = ts('Please enter the contribution.');
916 }
917 }
918
919 // validate contribution status for 'Failed'.
920 if ($self->_onlinePendingContributionId && !empty($params['record_contribution']) &&
921 (CRM_Utils_Array::value('contribution_status_id', $params) ==
922 array_search('Failed', CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'))
923 )
924 ) {
925 $errors['contribution_status_id'] = ts('Please select a valid payment status before updating.');
926 }
927
928 return empty($errors) ? TRUE : $errors;
929 }
930
931 /**
932 * Process the form submission.
933 */
934 public function postProcess() {
935 if ($this->_action & CRM_Core_Action::DELETE) {
936 CRM_Member_BAO_Membership::del($this->_id);
937 return;
938 }
939 // get the submitted form values.
940 $this->_params = $this->controller->exportValues($this->_name);
941
942 $this->submit();
943
944 $this->setUserContext();
945 }
946
947 /**
948 * Send email receipt.
949 *
950 * @param CRM_Core_Form $form
951 * Form object.
952 * @param array $formValues
953 * @param object $membership
954 * Object.
955 *
956 * @return bool
957 * true if mail was sent successfully
958 */
959 public static function emailReceipt(&$form, &$formValues, &$membership) {
960 // retrieve 'from email id' for acknowledgement
961 $receiptFrom = $formValues['from_email_address'];
962
963 if (!empty($formValues['payment_instrument_id'])) {
964 $paymentInstrument = CRM_Contribute_PseudoConstant::paymentInstrument();
965 $formValues['paidBy'] = $paymentInstrument[$formValues['payment_instrument_id']];
966 }
967
968 // retrieve custom data
969 $customFields = $customValues = array();
970 if (property_exists($form, '_groupTree')
971 && !empty($form->_groupTree)
972 ) {
973 foreach ($form->_groupTree as $groupID => $group) {
974 if ($groupID == 'info') {
975 continue;
976 }
977 foreach ($group['fields'] as $k => $field) {
978 $field['title'] = $field['label'];
979 $customFields["custom_{$k}"] = $field;
980 }
981 }
982 }
983
984 $members = array(array('member_id', '=', $membership->id, 0, 0));
985 // check whether its a test drive
986 if ($form->_mode == 'test') {
987 $members[] = array('member_test', '=', 1, 0, 0);
988 }
989
990 CRM_Core_BAO_UFGroup::getValues($formValues['contact_id'], $customFields, $customValues, FALSE, $members);
991 $form->assign('customValues', $customValues);
992
993 if ($form->_mode) {
994 // assign the address formatted up for display
995 $addressParts = array(
996 "street_address-{$form->_bltID}",
997 "city-{$form->_bltID}",
998 "postal_code-{$form->_bltID}",
999 "state_province-{$form->_bltID}",
1000 "country-{$form->_bltID}",
1001 );
1002 $addressFields = array();
1003 foreach ($addressParts as $part) {
1004 list($n, $id) = explode('-', $part);
1005 if (isset($form->_params['billing_' . $part])) {
1006 $addressFields[$n] = $form->_params['billing_' . $part];
1007 }
1008 }
1009 $form->assign('address', CRM_Utils_Address::format($addressFields));
1010
1011 $date = CRM_Utils_Date::format($form->_params['credit_card_exp_date']);
1012 $date = CRM_Utils_Date::mysqlToIso($date);
1013 $form->assign('credit_card_exp_date', $date);
1014 $form->assign('credit_card_number',
1015 CRM_Utils_System::mungeCreditCard($form->_params['credit_card_number'])
1016 );
1017 $form->assign('credit_card_type', $form->_params['credit_card_type']);
1018 $form->assign('contributeMode', 'direct');
1019 $form->assign('isAmountzero', 0);
1020 $form->assign('is_pay_later', 0);
1021 $form->assign('isPrimary', 1);
1022 }
1023
1024 $form->assign('module', 'Membership');
1025 $form->assign('contactID', $formValues['contact_id']);
1026
1027 $form->assign('membershipID', CRM_Utils_Array::value('membership_id', $form->_params, CRM_Utils_Array::value('membership_id', $form->_defaultValues)));
1028
1029 if (!empty($formValues['contribution_id'])) {
1030 $form->assign('contributionID', $formValues['contribution_id']);
1031 }
1032 elseif (isset($form->_onlinePendingContributionId)) {
1033 $form->assign('contributionID', $form->_onlinePendingContributionId);
1034 }
1035
1036 if (!empty($formValues['contribution_status_id'])) {
1037 $form->assign('contributionStatusID', $formValues['contribution_status_id']);
1038 $form->assign('contributionStatus', CRM_Contribute_PseudoConstant::contributionStatus($formValues['contribution_status_id'], 'name'));
1039 }
1040
1041 if (!empty($formValues['is_renew'])) {
1042 $form->assign('receiptType', 'membership renewal');
1043 }
1044 else {
1045 $form->assign('receiptType', 'membership signup');
1046 }
1047 $form->assign('receive_date', CRM_Utils_Date::processDate(CRM_Utils_Array::value('receive_date', $formValues)));
1048 $form->assign('formValues', $formValues);
1049
1050 if (empty($lineItem)) {
1051 $form->assign('mem_start_date', CRM_Utils_Date::customFormat($membership->start_date, '%B %E%f, %Y'));
1052 if (!CRM_Utils_System::isNull($membership->end_date)) {
1053 $form->assign('mem_end_date', CRM_Utils_Date::customFormat($membership->end_date, '%B %E%f, %Y'));
1054 }
1055 $form->assign('membership_name', CRM_Member_PseudoConstant::membershipType($membership->membership_type_id));
1056 }
1057
1058 $isBatchProcess = is_a($form, 'CRM_Batch_Form_Entry');
1059 if ((empty($form->_contributorDisplayName) || empty($form->_contributorEmail)) || $isBatchProcess) {
1060 // in this case the form is being called statically from the batch editing screen
1061 // having one class in the form layer call another statically is not greate
1062 // & we should aim to move this function to the BAO layer in future.
1063 // however, we can assume that the contact_id passed in by the batch
1064 // function will be the recipient
1065 list($form->_contributorDisplayName, $form->_contributorEmail)
1066 = CRM_Contact_BAO_Contact_Location::getEmailDetails($formValues['contact_id']);
1067 if (empty($form->_receiptContactId) || $isBatchProcess) {
1068 $form->_receiptContactId = $formValues['contact_id'];
1069 }
1070 }
1071 $template = CRM_Core_Smarty::singleton();
1072 $taxAmt = $template->get_template_vars('dataArray');
1073 $eventTaxAmt = $template->get_template_vars('totalTaxAmount');
1074 $prefixValue = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME, 'contribution_invoice_settings');
1075 $invoicing = CRM_Utils_Array::value('invoicing', $prefixValue);
1076 if ((!empty($taxAmt) || isset($eventTaxAmt)) && (isset($invoicing) && isset($prefixValue['is_email_pdf']))) {
1077 $isEmailPdf = TRUE;
1078 }
1079 else {
1080 $isEmailPdf = FALSE;
1081 }
1082
1083 list($mailSend, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate::sendTemplate(
1084 array(
1085 'groupName' => 'msg_tpl_workflow_membership',
1086 'valueName' => 'membership_offline_receipt',
1087 'contactId' => $form->_receiptContactId,
1088 'from' => $receiptFrom,
1089 'toName' => $form->_contributorDisplayName,
1090 'toEmail' => $form->_contributorEmail,
1091 'PDFFilename' => ts('receipt') . '.pdf',
1092 'isEmailPdf' => $isEmailPdf,
1093 'contributionId' => $formValues['contribution_id'],
1094 'isTest' => (bool) ($form->_action & CRM_Core_Action::PREVIEW),
1095 )
1096 );
1097
1098 return TRUE;
1099 }
1100
1101 /**
1102 * Submit function.
1103 *
1104 * This is also accessed by unit tests.
1105 *
1106 * @return array
1107 */
1108 public function submit() {
1109 $isTest = ($this->_mode == 'test') ? 1 : 0;
1110 $this->storeContactFields($this->_params);
1111 $this->beginPostProcess();
1112 $formValues = $this->_params;
1113 $joinDate = $startDate = $endDate = NULL;
1114 $membershipTypes = $membership = $calcDate = array();
1115 $membershipType = NULL;
1116
1117 $mailSend = FALSE;
1118 $formValues = $this->setPriceSetParameters($formValues);
1119 $params = $softParams = $ids = array();
1120
1121 $allMemberStatus = CRM_Member_PseudoConstant::membershipStatus();
1122 $allContributionStatus = CRM_Contribute_PseudoConstant::contributionStatus();
1123 $this->processBillingAddress();
1124
1125 if ($this->_id) {
1126 $ids['membership'] = $params['id'] = $this->_id;
1127 }
1128 $ids['userId'] = CRM_Core_Session::singleton()->get('userID');
1129
1130 // Set variables that we normally get from context.
1131 // In form mode these are set in preProcess.
1132 //TODO: set memberships, fixme
1133 $this->setContextVariables($formValues);
1134
1135 $this->_memTypeSelected = self::getSelectedMemberships(
1136 $this->_priceSet,
1137 $formValues
1138 );
1139 if (empty($formValues['financial_type_id'])) {
1140 $formValues['financial_type_id'] = $this->_priceSet['financial_type_id'];
1141 }
1142
1143 $config = CRM_Core_Config::singleton();
1144
1145 $this->convertDateFieldsToMySQL($formValues);
1146
1147 $membershipTypeValues = array();
1148 foreach ($this->_memTypeSelected as $memType) {
1149 $membershipTypeValues[$memType]['membership_type_id'] = $memType;
1150 }
1151
1152 //take the required membership recur values.
1153 if ($this->_mode && !empty($formValues['auto_renew'])) {
1154 $params['is_recur'] = $formValues['is_recur'] = TRUE;
1155 $mapping = array(
1156 'frequency_interval' => 'duration_interval',
1157 'frequency_unit' => 'duration_unit',
1158 );
1159
1160 $count = 0;
1161 foreach ($this->_memTypeSelected as $memType) {
1162 $recurMembershipTypeValues = CRM_Utils_Array::value($memType,
1163 $this->_recurMembershipTypes, array()
1164 );
1165 foreach ($mapping as $mapVal => $mapParam) {
1166 $membershipTypeValues[$memType][$mapVal] = CRM_Utils_Array::value($mapParam,
1167 $recurMembershipTypeValues
1168 );
1169 if (!$count) {
1170 $formValues[$mapVal] = CRM_Utils_Array::value($mapParam,
1171 $recurMembershipTypeValues
1172 );
1173 }
1174 }
1175 $count++;
1176 }
1177 }
1178
1179 $isQuickConfig = $this->_priceSet['is_quick_config'];
1180
1181 $termsByType = array();
1182
1183 $lineItem = array($this->_priceSetId => array());
1184
1185 CRM_Price_BAO_PriceSet::processAmount($this->_priceSet['fields'],
1186 $formValues, $lineItem[$this->_priceSetId]);
1187
1188 if (CRM_Utils_Array::value('tax_amount', $formValues)) {
1189 $params['tax_amount'] = $formValues['tax_amount'];
1190 }
1191 $params['total_amount'] = CRM_Utils_Array::value('amount', $formValues);
1192 $submittedFinancialType = CRM_Utils_Array::value('financial_type_id', $formValues);
1193 if (!empty($lineItem[$this->_priceSetId])) {
1194 foreach ($lineItem[$this->_priceSetId] as &$li) {
1195 if (!empty($li['membership_type_id'])) {
1196 if (!empty($li['membership_num_terms'])) {
1197 $termsByType[$li['membership_type_id']] = $li['membership_num_terms'];
1198 }
1199 }
1200
1201 ///CRM-11529 for quick config backoffice transactions
1202 //when financial_type_id is passed in form, update the
1203 //lineitems with the financial type selected in form
1204 if ($isQuickConfig && $submittedFinancialType) {
1205 $li['financial_type_id'] = $submittedFinancialType;
1206 }
1207 }
1208 }
1209
1210 $params['contact_id'] = $this->_contactID;
1211
1212 $fields = array(
1213 'status_id',
1214 'source',
1215 'is_override',
1216 'campaign_id',
1217 );
1218
1219 foreach ($fields as $f) {
1220 $params[$f] = CRM_Utils_Array::value($f, $formValues);
1221 }
1222
1223 // fix for CRM-3724
1224 // when is_override false ignore is_admin statuses during membership
1225 // status calculation. similarly we did fix for import in CRM-3570.
1226 if (empty($params['is_override'])) {
1227 $params['exclude_is_admin'] = TRUE;
1228 }
1229
1230 // process date params to mysql date format.
1231 $dateTypes = array(
1232 'join_date' => 'joinDate',
1233 'start_date' => 'startDate',
1234 'end_date' => 'endDate',
1235 );
1236 foreach ($dateTypes as $dateField => $dateVariable) {
1237 $$dateVariable = CRM_Utils_Date::processDate($formValues[$dateField]);
1238 }
1239
1240 $memTypeNumTerms = empty($termsByType) ? CRM_Utils_Array::value('num_terms', $formValues) : NULL;
1241
1242 $calcDates = array();
1243 foreach ($this->_memTypeSelected as $memType) {
1244 if (empty($memTypeNumTerms)) {
1245 $memTypeNumTerms = CRM_Utils_Array::value($memType, $termsByType, 1);
1246 }
1247 $calcDates[$memType] = CRM_Member_BAO_MembershipType::getDatesForMembershipType($memType,
1248 $joinDate, $startDate, $endDate, $memTypeNumTerms
1249 );
1250 }
1251
1252 foreach ($calcDates as $memType => $calcDate) {
1253 foreach (array_keys($dateTypes) as $d) {
1254 //first give priority to form values then calDates.
1255 $date = CRM_Utils_Array::value($d, $formValues);
1256 if (!$date) {
1257 $date = CRM_Utils_Array::value($d, $calcDate);
1258 }
1259
1260 $membershipTypeValues[$memType][$d] = CRM_Utils_Date::processDate($date);
1261 }
1262 }
1263
1264 // max related memberships - take from form or inherit from membership type
1265 foreach ($this->_memTypeSelected as $memType) {
1266 if (array_key_exists('max_related', $formValues)) {
1267 $membershipTypeValues[$memType]['max_related'] = CRM_Utils_Array::value('max_related', $formValues);
1268 }
1269 $membershipTypeValues[$memType]['custom'] = CRM_Core_BAO_CustomField::postProcess($formValues,
1270 $this->_id,
1271 'Membership'
1272 );
1273 $membershipTypes[$memType] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType',
1274 $memType
1275 );
1276 }
1277
1278 $membershipType = implode(', ', $membershipTypes);
1279
1280 // Retrieve the name and email of the current user - this will be the FROM for the receipt email
1281 list($userName) = CRM_Contact_BAO_Contact_Location::getEmailDetails($ids['userId']);
1282
1283 //CRM-13981, allow different person as a soft-contributor of chosen type
1284 if ($this->_contributorContactID != $this->_contactID) {
1285 $params['contribution_contact_id'] = $this->_contributorContactID;
1286 if (!empty($formValues['soft_credit_type_id'])) {
1287 $softParams['soft_credit_type_id'] = $formValues['soft_credit_type_id'];
1288 $softParams['contact_id'] = $this->_contactID;
1289 }
1290 }
1291 if (!empty($formValues['record_contribution'])) {
1292 $recordContribution = array(
1293 'total_amount',
1294 'financial_type_id',
1295 'payment_instrument_id',
1296 'trxn_id',
1297 'contribution_status_id',
1298 'check_number',
1299 'campaign_id',
1300 'receive_date',
1301 );
1302
1303 foreach ($recordContribution as $f) {
1304 $params[$f] = CRM_Utils_Array::value($f, $formValues);
1305 }
1306
1307 if (!$this->_onlinePendingContributionId) {
1308 if (empty($formValues['source'])) {
1309 $params['contribution_source'] = ts('%1 Membership: Offline signup (by %2)', array(
1310 1 => $membershipType,
1311 2 => $userName,
1312 ));
1313 }
1314 else {
1315 $params['contribution_source'] = $formValues['source'];
1316 }
1317 }
1318
1319 if (empty($params['is_override']) &&
1320 CRM_Utils_Array::value('contribution_status_id', $params) == array_search('Pending', CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'))
1321 ) {
1322 $params['status_id'] = array_search('Pending', $allMemberStatus);
1323 $params['skipStatusCal'] = TRUE;
1324 $params['is_pay_later'] = 1;
1325 $this->assign('is_pay_later', 1);
1326 }
1327
1328 if (!empty($formValues['send_receipt'])) {
1329 $params['receipt_date'] = CRM_Utils_Array::value('receive_date', $formValues);
1330 }
1331
1332 //insert financial type name in receipt.
1333 $formValues['contributionType_name'] = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialType',
1334 $formValues['financial_type_id']
1335 );
1336 }
1337
1338 // process line items, until no previous line items.
1339 if (!empty($lineItem)) {
1340 $params['lineItems'] = $lineItem;
1341 $params['processPriceSet'] = TRUE;
1342 }
1343 $createdMemberships = array();
1344 if ($this->_mode) {
1345 $params['total_amount'] = CRM_Utils_Array::value('total_amount', $formValues, 0);
1346
1347 if (!$isQuickConfig) {
1348 $params['financial_type_id'] = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet',
1349 $this->_priceSetId,
1350 'financial_type_id'
1351 );
1352 }
1353 else {
1354 $params['financial_type_id'] = CRM_Utils_Array::value('financial_type_id', $formValues);
1355 }
1356
1357 // @todo - test removing this line. The beginPostProcess Function should have done it for us.
1358 $this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getPayment($formValues['payment_processor_id'],
1359 $this->_mode
1360 );
1361
1362 //get the payment processor id as per mode. Try removing in favour of beginPostProcess.
1363 $params['payment_processor_id'] = $formValues['payment_processor_id'] = $this->_paymentProcessor['id'];
1364 $params['register_date'] = date('YmdHis');
1365
1366 // add all the additional payment params we need
1367 // @todo the country & state values should be set by the call to $this->assignBillingAddress.
1368 $formValues["state_province-{$this->_bltID}"] = $formValues["billing_state_province-{$this->_bltID}"]
1369 = CRM_Core_PseudoConstant::stateProvinceAbbreviation($formValues["billing_state_province_id-{$this->_bltID}"]);
1370 $formValues["country-{$this->_bltID}"] = $formValues["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant::countryIsoCode($formValues["billing_country_id-{$this->_bltID}"]);
1371
1372 $formValues['amount'] = $params['total_amount'];
1373 // @todo this is a candidate for beginPostProcessFunction.
1374 $formValues['currencyID'] = $config->defaultCurrency;
1375 $formValues['description'] = ts("Contribution submitted by a staff person using member's credit card for signup");
1376 $formValues['invoiceID'] = md5(uniqid(rand(), TRUE));
1377 $formValues['financial_type_id'] = $params['financial_type_id'];
1378
1379 // at this point we've created a contact and stored its address etc
1380 // all the payment processors expect the name and address to be in the
1381 // so we copy stuff over to first_name etc.
1382 $paymentParams = $formValues;
1383 $paymentParams['contactID'] = $this->_contributorContactID;
1384 //CRM-10377 if payment is by an alternate contact then we need to set that person
1385 // as the contact in the payment params
1386 if ($this->_contributorContactID != $this->_contactID) {
1387 if (!empty($formValues['soft_credit_type_id'])) {
1388 $softParams['contact_id'] = $params['contact_id'];
1389 $softParams['soft_credit_type_id'] = $formValues['soft_credit_type_id'];
1390 }
1391 }
1392 if (!empty($formValues['send_receipt'])) {
1393 $paymentParams['email'] = $this->_contributorEmail;
1394 }
1395
1396 // This is a candidate for shared beginPostProcess function.
1397 CRM_Core_Payment_Form::mapParams($this->_bltID, $formValues, $paymentParams, TRUE);
1398 // CRM-7137 -for recurring membership,
1399 // we do need contribution and recurring records.
1400 $result = NULL;
1401 if (!empty($paymentParams['is_recur'])) {
1402 $financialType = new CRM_Financial_DAO_FinancialType();
1403 $financialType->id = $params['financial_type_id'];
1404 $financialType->find(TRUE);
1405 $this->_params = $formValues;
1406 $contribution = CRM_Contribute_Form_Contribution_Confirm::processFormContribution($this,
1407 $paymentParams,
1408 NULL,
1409 array(
1410 'contact_id' => $this->_contributorContactID,
1411 'line_item' => $lineItem,
1412 'is_test' => $isTest,
1413 'campaign_id' => CRM_Utils_Array::value('campaign_id', $paymentParams),
1414 'contribution_page_id' => CRM_Utils_Array::value('contribution_page_id', $formValues),
1415 'source' => CRM_Utils_Array::value('source', $paymentParams, CRM_Utils_Array::value('description', $paymentParams)),
1416 'thankyou_date' => CRM_Utils_Array::value('thankyou_date', $paymentParams),
1417 'payment_instrument_id' => $this->_paymentProcessor['payment_instrument_id'],
1418 ),
1419 $financialType,
1420 FALSE,
1421 $this->_bltID
1422 );
1423
1424 //create new soft-credit record, CRM-13981
1425 if ($softParams) {
1426 $softParams['contribution_id'] = $contribution->id;
1427 $softParams['currency'] = $contribution->currency;
1428 $softParams['amount'] = $contribution->total_amount;
1429 CRM_Contribute_BAO_ContributionSoft::add($softParams);
1430 }
1431
1432 $paymentParams['contactID'] = $this->_contactID;
1433 $paymentParams['contributionID'] = $contribution->id;
1434 $paymentParams['contributionTypeID'] = $contribution->financial_type_id;
1435 $paymentParams['contributionPageID'] = $contribution->contribution_page_id;
1436 $paymentParams['contributionRecurID'] = $contribution->contribution_recur_id;
1437 $ids['contribution'] = $contribution->id;
1438 $params['contribution_recur_id'] = $paymentParams['contributionRecurID'];
1439 }
1440
1441 if ($params['total_amount'] > 0.0) {
1442 $payment = $this->_paymentProcessor['object'];
1443 try {
1444 $result = $payment->doPayment($paymentParams);
1445 $formValues = array_merge($formValues, $result);
1446 // Assign amount to template if payment was successful.
1447 $this->assign('amount', $params['total_amount']);
1448 }
1449 catch (PaymentProcessorException $e) {
1450 if (!empty($paymentParams['contributionID'])) {
1451 CRM_Contribute_BAO_Contribution::failPayment($paymentParams['contributionID'], $this->_contactID,
1452 $e->getMessage());
1453 }
1454 if (!empty($paymentParams['contributionRecurID'])) {
1455 CRM_Contribute_BAO_ContributionRecur::deleteRecurContribution($paymentParams['contributionRecurID']);
1456 }
1457
1458 CRM_Core_Error::displaySessionError($result);
1459 CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/view/membership',
1460 "reset=1&action=add&cid={$this->_contactID}&context=&mode={$this->_mode}"
1461 ));
1462
1463 }
1464 }
1465
1466 if ($formValues['payment_status_id'] != array_search('Completed', $allContributionStatus)) {
1467 $params['status_id'] = array_search('Pending', $allMemberStatus);
1468 $params['skipStatusCal'] = TRUE;
1469 // unset send-receipt option, since receipt will be sent when ipn is received.
1470 unset($formValues['send_receipt'], $formValues['send_receipt']);
1471 //as membership is pending set dates to null.
1472 $memberDates = array(
1473 'join_date' => 'joinDate',
1474 'start_date' => 'startDate',
1475 'end_date' => 'endDate',
1476 );
1477 foreach ($memberDates as $dv) {
1478 $$dv = NULL;
1479 foreach ($this->_memTypeSelected as $memType) {
1480 $membershipTypeValues[$memType][$dv] = NULL;
1481 }
1482 }
1483 }
1484 $now = date('YmdHis');
1485 $params['receive_date'] = $now;
1486 $params['invoice_id'] = $formValues['invoiceID'];
1487 $params['contribution_source'] = ts('%1 Membership Signup: Credit card or direct debit (by %2)',
1488 array(1 => $membershipType, 2 => $userName)
1489 );
1490 $params['source'] = $formValues['source'] ? $formValues['source'] : $params['contribution_source'];
1491 $params['trxn_id'] = CRM_Utils_Array::value('trxn_id', $result);
1492 $params['payment_instrument_id'] = 1;
1493 $params['is_test'] = ($this->_mode == 'live') ? 0 : 1;
1494 if (!empty($formValues['send_receipt'])) {
1495 $params['receipt_date'] = $now;
1496 }
1497 else {
1498 $params['receipt_date'] = NULL;
1499 }
1500
1501 $this->set('params', $formValues);
1502 $this->assign('trxn_id', CRM_Utils_Array::value('trxn_id', $result));
1503 $this->assign('receive_date',
1504 CRM_Utils_Date::mysqlToIso($params['receive_date'])
1505 );
1506
1507 // required for creating membership for related contacts
1508 $params['action'] = $this->_action;
1509
1510 //create membership record.
1511 $count = 0;
1512 foreach ($this->_memTypeSelected as $memType) {
1513 if ($count &&
1514 ($relateContribution = CRM_Member_BAO_Membership::getMembershipContributionId($membership->id))
1515 ) {
1516 $membershipTypeValues[$memType]['relate_contribution_id'] = $relateContribution;
1517 }
1518
1519 $membershipParams = array_merge($membershipTypeValues[$memType], $params);
1520 //CRM-15366
1521 if (!empty($softParams) && empty($paymentParams['is_recur'])) {
1522 $membershipParams['soft_credit'] = $softParams;
1523 }
1524 if (isset($result['fee_amount'])) {
1525 $membershipParams['fee_amount'] = $result['fee_amount'];
1526 }
1527 // This is required to trigger the recording of the membership contribution in the
1528 // CRM_Member_BAO_Membership::Create function.
1529 // @todo stop setting this & 'teach' the create function to respond to something
1530 // appropriate as part of our 2-step always create the pending contribution & then finally add the payment
1531 // process -
1532 // @see http://wiki.civicrm.org/confluence/pages/viewpage.action?pageId=261062657#Payments&AccountsRoadmap-Movetowardsalwaysusinga2-steppaymentprocess
1533 $membershipParams['contribution_status_id'] = CRM_Utils_Array::value('payment_status_id', $result);
1534 if (!empty($paymentParams['is_recur'])) {
1535 // The earlier process created the line items (although we want to get rid of the earlier one in favour
1536 // of a single path!
1537 unset($membershipParams['lineItems']);
1538 }
1539
1540 $membership = CRM_Member_BAO_Membership::create($membershipParams, $ids);
1541 $params['contribution'] = CRM_Utils_Array::value('contribution', $membershipParams);
1542 unset($params['lineItems']);
1543 $this->_membershipIDs[] = $membership->id;
1544 $createdMemberships[$memType] = $membership;
1545 $count++;
1546 }
1547
1548 }
1549 else {
1550 $params['action'] = $this->_action;
1551 if ($this->_onlinePendingContributionId && !empty($formValues['record_contribution'])) {
1552
1553 // update membership as well as contribution object, CRM-4395
1554 $params['contribution_id'] = $this->_onlinePendingContributionId;
1555 $params['componentId'] = $params['id'];
1556 $params['componentName'] = 'contribute';
1557 $result = CRM_Contribute_BAO_Contribution::transitionComponents($params, TRUE);
1558 if (!empty($result) && !empty($params['contribution_id'])) {
1559 $lineItem = array();
1560 $lineItems = CRM_Price_BAO_LineItem::getLineItems($params['contribution_id'], 'contribution', NULL, TRUE, TRUE);
1561 $itemId = key($lineItems);
1562 $priceSetId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', $lineItems[$itemId]['price_field_id'], 'price_set_id');
1563
1564 $lineItems[$itemId]['unit_price'] = $params['total_amount'];
1565 $lineItems[$itemId]['line_total'] = $params['total_amount'];
1566 $lineItems[$itemId]['id'] = $itemId;
1567 $lineItem[$priceSetId] = $lineItems;
1568 $contributionBAO = new CRM_Contribute_BAO_Contribution();
1569 $contributionBAO->id = $params['contribution_id'];
1570 $contributionBAO->contact_id = $params['contact_id'];
1571 $contributionBAO->find();
1572 CRM_Price_BAO_LineItem::processPriceSet($params['contribution_id'], $lineItem, $contributionBAO, 'civicrm_membership');
1573
1574 //create new soft-credit record, CRM-13981
1575 if ($softParams) {
1576 $softParams['contribution_id'] = $params['contribution_id'];
1577 while ($contributionBAO->fetch()) {
1578 $softParams['currency'] = $contributionBAO->currency;
1579 $softParams['amount'] = $contributionBAO->total_amount;
1580 }
1581 CRM_Contribute_BAO_ContributionSoft::add($softParams);
1582 }
1583 }
1584
1585 //carry updated membership object.
1586 $membership = new CRM_Member_DAO_Membership();
1587 $membership->id = $this->_id;
1588 $membership->find(TRUE);
1589
1590 $cancelled = TRUE;
1591 if ($membership->end_date) {
1592 //display end date w/ status message.
1593 $endDate = $membership->end_date;
1594
1595 if (!in_array($membership->status_id, array(
1596 // CRM-15475
1597 array_search('Cancelled', CRM_Member_PseudoConstant::membershipStatus(NULL, " name = 'Cancelled' ", 'name', FALSE, TRUE)),
1598 array_search('Expired', CRM_Member_PseudoConstant::membershipStatus()),
1599 ))
1600 ) {
1601 $cancelled = FALSE;
1602 }
1603 }
1604 // suppress form values in template.
1605 $this->assign('cancelled', $cancelled);
1606
1607 $createdMemberships[] = $membership;
1608 }
1609 else {
1610 $count = 0;
1611 foreach ($this->_memTypeSelected as $memType) {
1612 if ($count && !empty($formValues['record_contribution']) &&
1613 ($relateContribution = CRM_Member_BAO_Membership::getMembershipContributionId($membership->id))
1614 ) {
1615 $membershipTypeValues[$memType]['relate_contribution_id'] = $relateContribution;
1616 }
1617
1618 $membershipParams = array_merge($params, $membershipTypeValues[$memType]);
1619 if (!empty($formValues['int_amount'])) {
1620 $init_amount = array();
1621 foreach ($formValues as $key => $value) {
1622 if (strstr($key, 'txt-price')) {
1623 $init_amount[$key] = $value;
1624 }
1625 }
1626 $membershipParams['init_amount'] = $init_amount;
1627 }
1628
1629 if (!empty($softParams)) {
1630 $membershipParams['soft_credit'] = $softParams;
1631 }
1632
1633 $membership = CRM_Member_BAO_Membership::create($membershipParams, $ids);
1634 $params['contribution'] = CRM_Utils_Array::value('contribution', $membershipParams);
1635 unset($params['lineItems']);
1636
1637 $this->_membershipIDs[] = $membership->id;
1638 $createdMemberships[$memType] = $membership;
1639 $count++;
1640 }
1641 }
1642 }
1643
1644 if (!empty($lineItem[$this->_priceSetId])) {
1645 $invoiceSettings = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME, 'contribution_invoice_settings');
1646 $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings);
1647 $taxAmount = FALSE;
1648 $totalTaxAmount = 0;
1649 foreach ($lineItem[$this->_priceSetId] as & $priceFieldOp) {
1650 if (!empty($priceFieldOp['membership_type_id'])) {
1651 $priceFieldOp['start_date'] = $membershipTypeValues[$priceFieldOp['membership_type_id']]['start_date'] ? CRM_Utils_Date::customFormat($membershipTypeValues[$priceFieldOp['membership_type_id']]['start_date'], '%B %E%f, %Y') : '-';
1652 $priceFieldOp['end_date'] = $membershipTypeValues[$priceFieldOp['membership_type_id']]['end_date'] ? CRM_Utils_Date::customFormat($membershipTypeValues[$priceFieldOp['membership_type_id']]['end_date'], '%B %E%f, %Y') : '-';
1653 }
1654 else {
1655 $priceFieldOp['start_date'] = $priceFieldOp['end_date'] = 'N/A';
1656 }
1657 if ($invoicing && isset($priceFieldOp['tax_amount'])) {
1658 $taxAmount = TRUE;
1659 $totalTaxAmount += $priceFieldOp['tax_amount'];
1660 }
1661 }
1662 if ($invoicing) {
1663 $dataArray = array();
1664 foreach ($lineItem[$this->_priceSetId] as $key => $value) {
1665 if (isset($value['tax_amount']) && isset($value['tax_rate'])) {
1666 if (isset($dataArray[$value['tax_rate']])) {
1667 $dataArray[$value['tax_rate']] = $dataArray[$value['tax_rate']] + CRM_Utils_Array::value('tax_amount', $value);
1668 }
1669 else {
1670 $dataArray[$value['tax_rate']] = CRM_Utils_Array::value('tax_amount', $value);
1671 }
1672 }
1673 }
1674 if ($taxAmount) {
1675 $this->assign('totalTaxAmount', $totalTaxAmount);
1676 $this->assign('taxTerm', CRM_Utils_Array::value('tax_term', $invoiceSettings));
1677 }
1678 $this->assign('dataArray', $dataArray);
1679 }
1680 }
1681 $this->assign('lineItem', !empty($lineItem) && !$isQuickConfig ? $lineItem : FALSE);
1682
1683 $receiptSend = FALSE;
1684 $contributionId = CRM_Member_BAO_Membership::getMembershipContributionId($membership->id);
1685 $membershipIds = $this->_membershipIDs;
1686 if ($contributionId && !empty($membershipIds)) {
1687 $contributionDetails = CRM_Contribute_BAO_Contribution::getContributionDetails(
1688 CRM_Export_Form_Select::MEMBER_EXPORT, $this->_membershipIDs);
1689 if ($contributionDetails[$membership->id]['contribution_status'] == 'Completed') {
1690 $receiptSend = TRUE;
1691 }
1692 }
1693
1694 if (!empty($formValues['send_receipt']) && $receiptSend) {
1695 $formValues['contact_id'] = $this->_contactID;
1696 $formValues['contribution_id'] = $contributionId;
1697 // We really don't need a distinct receipt_text_signup vs receipt_text_renewal as they are
1698 // handled in the receipt. But by setting one we avoid breaking templates for now
1699 // although at some point we should switch in the templates.
1700 $formValues['receipt_text_signup'] = $formValues['receipt_text'];
1701 // send email receipt
1702 $this->assignBillingName();
1703 $mailSend = self::emailReceipt($this, $formValues, $membership);
1704 }
1705
1706 // finally set membership id if already not set
1707 if (!$this->_id) {
1708 $this->_id = $membership->id;
1709 }
1710
1711 $isRecur = CRM_Utils_Array::value('is_recur', $params);
1712 $this->setStatusMessage($membership, $endDate, $receiptSend, $membershipTypes, $createdMemberships, $isRecur, $calcDates, $mailSend);
1713 return $createdMemberships;
1714 }
1715
1716 /**
1717 * Set context in session.
1718 */
1719 protected function setUserContext() {
1720 $buttonName = $this->controller->getButtonName();
1721 $session = CRM_Core_Session::singleton();
1722
1723 if ($this->_context == 'standalone') {
1724 if ($buttonName == $this->getButtonName('upload', 'new')) {
1725 $session->replaceUserContext(CRM_Utils_System::url('civicrm/member/add',
1726 'reset=1&action=add&context=standalone'
1727 ));
1728 }
1729 else {
1730 $session->replaceUserContext(CRM_Utils_System::url('civicrm/contact/view',
1731 "reset=1&cid={$this->_contactID}&selectedChild=member"
1732 ));
1733 }
1734 }
1735 elseif ($buttonName == $this->getButtonName('upload', 'new')) {
1736 $session->replaceUserContext(CRM_Utils_System::url('civicrm/contact/view/membership',
1737 "reset=1&action=add&context=membership&cid={$this->_contactID}"
1738 ));
1739 }
1740 }
1741
1742 /**
1743 * Get status message for updating membership.
1744 *
1745 * @param CRM_Member_BAO_Membership $membership
1746 * @param string $endDate
1747 * @param bool $receiptSend
1748 *
1749 * @return string
1750 */
1751 protected function getStatusMessageForUpdate($membership, $endDate, $receiptSend) {
1752 // End date can be modified by hooks, so if end date is set then use it.
1753 $endDate = ($membership->end_date) ? $membership->end_date : $endDate;
1754
1755 $statusMsg = ts('Membership for %1 has been updated.', array(1 => $this->_memberDisplayName));
1756 if ($endDate && $endDate !== 'null') {
1757 $endDate = CRM_Utils_Date::customFormat($endDate);
1758 $statusMsg .= ' ' . ts('The membership End Date is %1.', array(1 => $endDate));
1759 }
1760
1761 if (!empty($formValues['send_receipt']) && $receiptSend) {
1762 $statusMsg .= ' ' . ts('A confirmation and receipt has been sent to %1.', array(1 => $this->_contributorEmail));
1763 }
1764 return $statusMsg;
1765 }
1766
1767 /**
1768 * Get status message for create action.
1769 *
1770 * @param string $endDate
1771 * @param bool $receiptSend
1772 * @param array $membershipTypes
1773 * @param array $createdMemberships
1774 * @param bool $isRecur
1775 * @param array $calcDates
1776 * @param bool $mailSent
1777 *
1778 * @return array|string
1779 */
1780 protected function getStatusMessageForCreate($endDate, $receiptSend, $membershipTypes, $createdMemberships,
1781 $isRecur, $calcDates, $mailSent) {
1782 // FIX ME: fix status messages
1783
1784 $statusMsg = array();
1785 foreach ($membershipTypes as $memType => $membershipType) {
1786 $statusMsg[$memType] = ts('%1 membership for %2 has been added.', array(
1787 1 => $membershipType,
1788 2 => $this->_memberDisplayName,
1789 ));
1790
1791 $membership = $createdMemberships[$memType];
1792 $memEndDate = ($membership->end_date) ? $membership->end_date : $endDate;
1793
1794 //get the end date from calculated dates.
1795 if (!$memEndDate && !$isRecur) {
1796 $memEndDate = CRM_Utils_Array::value('end_date', $calcDates[$memType]);
1797 }
1798
1799 if ($memEndDate && $memEndDate !== 'null') {
1800 $memEndDate = CRM_Utils_Date::customFormat($memEndDate);
1801 $statusMsg[$memType] .= ' ' . ts('The new membership End Date is %1.', array(1 => $memEndDate));
1802 }
1803 }
1804 $statusMsg = implode('<br/>', $statusMsg);
1805 if ($receiptSend && !empty($mailSent)) {
1806 $statusMsg .= ' ' . ts('A membership confirmation and receipt has been sent to %1.', array(1 => $this->_contributorEmail));
1807 }
1808 return $statusMsg;
1809 }
1810
1811 /**
1812 * @param $membership
1813 * @param $endDate
1814 * @param $receiptSend
1815 * @param $membershipTypes
1816 * @param $createdMemberships
1817 * @param $isRecur
1818 * @param $calcDates
1819 * @param $mailSend
1820 */
1821 protected function setStatusMessage($membership, $endDate, $receiptSend, $membershipTypes, $createdMemberships, $isRecur, $calcDates, $mailSend) {
1822 $statusMsg = '';
1823 if (($this->_action & CRM_Core_Action::UPDATE)) {
1824 $statusMsg = $this->getStatusMessageForUpdate($membership, $endDate, $receiptSend);
1825 }
1826 elseif (($this->_action & CRM_Core_Action::ADD)) {
1827 $statusMsg = $this->getStatusMessageForCreate($endDate, $receiptSend, $membershipTypes, $createdMemberships,
1828 $isRecur, $calcDates, $mailSend);
1829 }
1830
1831 CRM_Core_Session::setStatus($statusMsg, ts('Complete'), 'success');
1832 //CRM-15187
1833 // display message when membership type is changed
1834 if (($this->_action & CRM_Core_Action::UPDATE) && $this->_id && !in_array($this->_memType, $this->_memTypeSelected)) {
1835 $lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_id, 'membership');
1836 $maxID = max(array_keys($lineItem));
1837 $lineItem = $lineItem[$maxID];
1838 $membershipTypeDetails = $this->allMembershipTypeDetails[$membership->membership_type_id];
1839 if ($membershipTypeDetails['financial_type_id'] != $lineItem['financial_type_id']) {
1840 CRM_Core_Session::setStatus(
1841 ts('The financial types associated with the old and new membership types are different. You may want to edit the contribution associated with this membership to adjust its financial type.'),
1842 ts('Warning')
1843 );
1844 }
1845 if ($membershipTypeDetails['minimum_fee'] != $lineItem['line_total']) {
1846 CRM_Core_Session::setStatus(
1847 ts('The cost of the old and new membership types are different. You may want to edit the contribution associated with this membership to adjust its amount.'),
1848 ts('Warning')
1849 );
1850 }
1851 }
1852 }
1853
1854}