Merge pull request #13987 from seamuslee001/new_coder_pcp_pledge_profile_queue_report
[civicrm-core.git] / CRM / Member / Import / Parser / Membership.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
6a488035
TO
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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 *
30 * @package CRM
6b83d5bd 31 * @copyright CiviCRM LLC (c) 2004-2019
6a488035
TO
32 * $Id$
33 *
34 */
35
36
37require_once 'api/api.php';
38
39/**
40 * class to parse membership csv files
41 */
42class CRM_Member_Import_Parser_Membership extends CRM_Member_Import_Parser {
43
44 protected $_mapperKeys;
45
46 private $_contactIdIndex;
47 private $_totalAmountIndex;
48 private $_membershipTypeIndex;
49 private $_membershipStatusIndex;
50
51 /**
ceb10dc7 52 * Array of successfully imported membership id's
6a488035
TO
53 *
54 * @array
55 */
56 protected $_newMemberships;
57
58 /**
fe482240 59 * Class constructor.
c2b5a0af
EM
60 *
61 * @param $mapperKeys
62 * @param null $mapperLocType
63 * @param null $mapperPhoneType
6a488035 64 */
00be9182 65 public function __construct(&$mapperKeys, $mapperLocType = NULL, $mapperPhoneType = NULL) {
6a488035
TO
66 parent::__construct();
67 $this->_mapperKeys = &$mapperKeys;
68 }
69
70 /**
100fef9d 71 * The initializer code, called before the processing
6a488035
TO
72 *
73 * @return void
6a488035 74 */
00be9182 75 public function init() {
6a488035
TO
76 $fields = CRM_Member_BAO_Membership::importableFields($this->_contactType, FALSE);
77
78 foreach ($fields as $name => $field) {
79 $field['type'] = CRM_Utils_Array::value('type', $field, CRM_Utils_Type::T_INT);
80 $field['dataPattern'] = CRM_Utils_Array::value('dataPattern', $field, '//');
81 $field['headerPattern'] = CRM_Utils_Array::value('headerPattern', $field, '//');
82 $this->addField($name, $field['title'], $field['type'], $field['headerPattern'], $field['dataPattern']);
83 }
84
be2fb01f 85 $this->_newMemberships = [];
6a488035
TO
86
87 $this->setActiveFields($this->_mapperKeys);
88
89 // FIXME: we should do this in one place together with Form/MapField.php
90 $this->_contactIdIndex = -1;
91 $this->_membershipTypeIndex = -1;
92 $this->_membershipStatusIndex = -1;
93
94 $index = 0;
95 foreach ($this->_mapperKeys as $key) {
96 switch ($key) {
97 case 'membership_contact_id':
98 $this->_contactIdIndex = $index;
99 break;
100
101 case 'membership_type_id':
102 $this->_membershipTypeIndex = $index;
103 break;
104
105 case 'status_id':
106 $this->_membershipStatusIndex = $index;
107 break;
108 }
109 $index++;
110 }
111 }
112
113 /**
fe482240 114 * Handle the values in mapField mode.
6a488035 115 *
b2363ea8
TO
116 * @param array $values
117 * The array of values belonging to this line.
6a488035 118 *
d5cc0fc2 119 * @return bool
6a488035 120 */
00be9182 121 public function mapField(&$values) {
a05662ef 122 return CRM_Import_Parser::VALID;
6a488035
TO
123 }
124
125 /**
fe482240 126 * Handle the values in preview mode.
6a488035 127 *
b2363ea8
TO
128 * @param array $values
129 * The array of values belonging to this line.
6a488035 130 *
d5cc0fc2 131 * @return bool
a6c01b45 132 * the result of this processing
6a488035 133 */
00be9182 134 public function preview(&$values) {
6a488035
TO
135 return $this->summary($values);
136 }
137
138 /**
fe482240 139 * Handle the values in summary mode.
6a488035 140 *
b2363ea8
TO
141 * @param array $values
142 * The array of values belonging to this line.
6a488035 143 *
d5cc0fc2 144 * @return bool
a6c01b45 145 * the result of this processing
6a488035 146 */
00be9182 147 public function summary(&$values) {
6a488035
TO
148 $erroneousField = NULL;
149 $response = $this->setActiveFieldValues($values, $erroneousField);
150
151 $errorRequired = FALSE;
152
153 if ($this->_membershipTypeIndex < 0) {
154 $errorRequired = TRUE;
155 }
156 else {
157 $errorRequired = !CRM_Utils_Array::value($this->_membershipTypeIndex, $values);
158 }
159
160 if ($errorRequired) {
161 array_unshift($values, ts('Missing required fields'));
a05662ef 162 return CRM_Import_Parser::ERROR;
6a488035
TO
163 }
164
04f72de8 165 $params = $this->getActiveFieldParams();
6a488035
TO
166 $errorMessage = NULL;
167
168 //To check whether start date or join date is provided
8cc574cf 169 if (empty($params['membership_start_date']) && empty($params['join_date'])) {
6a488035 170 $errorMessage = 'Membership Start Date is required to create a memberships.';
719a6fec 171 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Start Date', $errorMessage);
6a488035 172 }
6a488035
TO
173
174 //for date-Formats
175 $session = CRM_Core_Session::singleton();
176 $dateType = $session->get('dateTypes');
177 foreach ($params as $key => $val) {
178
179 if ($val) {
180 switch ($key) {
181 case 'join_date':
182 if (CRM_Utils_Date::convertToDefaultDate($params, $dateType, $key)) {
183 if (!CRM_Utils_Rule::date($params[$key])) {
719a6fec 184 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Member Since', $errorMessage);
6a488035
TO
185 }
186 }
187 else {
719a6fec 188 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Member Since', $errorMessage);
6a488035
TO
189 }
190 break;
191
192 case 'membership_start_date':
193 if (CRM_Utils_Date::convertToDefaultDate($params, $dateType, $key)) {
194 if (!CRM_Utils_Rule::date($params[$key])) {
719a6fec 195 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Start Date', $errorMessage);
6a488035
TO
196 }
197 }
198 else {
719a6fec 199 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Start Date', $errorMessage);
6a488035
TO
200 }
201 break;
202
203 case 'membership_end_date':
204 if (CRM_Utils_Date::convertToDefaultDate($params, $dateType, $key)) {
205 if (!CRM_Utils_Rule::date($params[$key])) {
719a6fec 206 CRM_Contact_Import_Parser_Contact::addToErrorMsg('End date', $errorMessage);
6a488035
TO
207 }
208 }
209 else {
719a6fec 210 CRM_Contact_Import_Parser_Contact::addToErrorMsg('End date', $errorMessage);
6a488035
TO
211 }
212 break;
e136f704
O
213
214 case 'status_override_end_date':
215 if (CRM_Utils_Date::convertToDefaultDate($params, $dateType, $key)) {
216 if (!CRM_Utils_Rule::date($params[$key])) {
217 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Status Override End Date', $errorMessage);
218 }
219 }
220 else {
221 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Status Override End Date', $errorMessage);
222 }
223 break;
6a488035
TO
224
225 case 'membership_type_id':
226 $membershipTypes = CRM_Member_PseudoConstant::membershipType();
227 if (!CRM_Utils_Array::crmInArray($val, $membershipTypes) &&
228 !array_key_exists($val, $membershipTypes)
229 ) {
719a6fec 230 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Membership Type', $errorMessage);
6a488035
TO
231 }
232 break;
233
234 case 'status_id':
235 if (!CRM_Utils_Array::crmInArray($val, CRM_Member_PseudoConstant::membershipStatus())) {
719a6fec 236 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Membership Status', $errorMessage);
6a488035
TO
237 }
238 break;
239
240 case 'email':
241 if (!CRM_Utils_Rule::email($val)) {
719a6fec 242 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Email Address', $errorMessage);
6a488035
TO
243 }
244 }
245 }
246 }
247 //date-Format part ends
248
249 $params['contact_type'] = 'Membership';
250
251 //checking error in custom data
719a6fec 252 CRM_Contact_Import_Parser_Contact::isErrorInCustomData($params, $errorMessage);
6a488035
TO
253
254 if ($errorMessage) {
255 $tempMsg = "Invalid value for field(s) : $errorMessage";
256 array_unshift($values, $tempMsg);
257 $errorMessage = NULL;
a05662ef 258 return CRM_Import_Parser::ERROR;
6a488035
TO
259 }
260
a05662ef 261 return CRM_Import_Parser::VALID;
6a488035
TO
262 }
263
264 /**
fe482240 265 * Handle the values in import mode.
6a488035 266 *
b2363ea8
TO
267 * @param int $onDuplicate
268 * The code for what action to take on duplicates.
269 * @param array $values
270 * The array of values belonging to this line.
6a488035 271 *
d5cc0fc2 272 * @return bool
a6c01b45 273 * the result of this processing
6a488035 274 */
00be9182 275 public function import($onDuplicate, &$values) {
92e4c2a5 276 try {
4f7b71ab 277 // first make sure this is a valid line
278 $response = $this->summary($values);
279 if ($response != CRM_Import_Parser::VALID) {
280 return $response;
281 }
6a488035 282
04f72de8 283 $params = $this->getActiveFieldParams();
6a488035 284
4f7b71ab 285 //assign join date equal to start date if join date is not provided
8cc574cf 286 if (empty($params['join_date']) && !empty($params['membership_start_date'])) {
4f7b71ab 287 $params['join_date'] = $params['membership_start_date'];
288 }
6a488035 289
353ffa53
TO
290 $session = CRM_Core_Session::singleton();
291 $dateType = $session->get('dateTypes');
be2fb01f 292 $formatted = [];
5981d156
JP
293 $customDataType = !empty($params['contact_type']) ? $params['contact_type'] : 'Membership';
294 $customFields = CRM_Core_BAO_CustomField::getFields($customDataType);
4f7b71ab 295
296 // don't add to recent items, CRM-4399
297 $formatted['skipRecentView'] = TRUE;
be2fb01f 298 $dateLabels = [
4f7b71ab 299 'join_date' => ts('Member Since'),
300 'membership_start_date' => ts('Start Date'),
301 'membership_end_date' => ts('End Date'),
be2fb01f 302 ];
4f7b71ab 303 foreach ($params as $key => $val) {
304 if ($val) {
305 switch ($key) {
306 case 'join_date':
307 case 'membership_start_date':
308 case 'membership_end_date':
309 if (CRM_Utils_Date::convertToDefaultDate($params, $dateType, $key)) {
310 if (!CRM_Utils_Rule::date($params[$key])) {
311 CRM_Contact_Import_Parser_Contact::addToErrorMsg($dateLabels[$key], $errorMessage);
312 }
313 }
314 else {
87bbc876 315 CRM_Contact_Import_Parser_Contact::addToErrorMsg($dateLabels[$key], $errorMessage);
6a488035 316 }
4f7b71ab 317 break;
6a488035 318
4f7b71ab 319 case 'membership_type_id':
320 if (!is_numeric($val)) {
321 unset($params['membership_type_id']);
322 $params['membership_type'] = $val;
323 }
324 break;
6a488035 325
4f7b71ab 326 case 'status_id':
327 if (!is_numeric($val)) {
328 unset($params['status_id']);
329 $params['membership_status'] = $val;
330 }
331 break;
6a488035 332
4f7b71ab 333 case 'is_override':
334 $params[$key] = CRM_Utils_String::strtobool($val);
335 break;
336 }
337 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
481a74f4 338 if ($customFields[$customFieldID]['data_type'] == 'Date') {
4f7b71ab 339 CRM_Contact_Import_Parser_Contact::formatCustomDate($params, $formatted, $dateType, $key);
340 unset($params[$key]);
0db6c3e1 341 }
481a74f4 342 elseif ($customFields[$customFieldID]['data_type'] == 'Boolean') {
4f7b71ab 343 $params[$key] = CRM_Utils_String::strtoboolstr($val);
344 }
6a488035
TO
345 }
346 }
347 }
4f7b71ab 348 //date-Format part ends
6a488035 349
4f7b71ab 350 static $indieFields = NULL;
351 if ($indieFields == NULL) {
352 $tempIndieFields = CRM_Member_DAO_Membership::import();
353 $indieFields = $tempIndieFields;
6a488035
TO
354 }
355
be2fb01f 356 $formatValues = [];
4f7b71ab 357 foreach ($params as $key => $field) {
358 if ($field == NULL || $field === '') {
359 continue;
360 }
6a488035 361
4f7b71ab 362 $formatValues[$key] = $field;
6a488035
TO
363 }
364
4f7b71ab 365 //format params to meet api v2 requirements.
366 //@todo find a way to test removing this formatting
367 $formatError = $this->membership_format_params($formatValues, $formatted, TRUE);
6a488035 368
4f7b71ab 369 if ($onDuplicate != CRM_Import_Parser::DUPLICATE_UPDATE) {
6a488035 370 $formatted['custom'] = CRM_Core_BAO_CustomField::postProcess($formatted,
4f7b71ab 371 NULL,
6a488035
TO
372 'Membership'
373 );
4f7b71ab 374 }
375 else {
376 //fix for CRM-2219 Update Membership
377 // onDuplicate == CRM_Import_Parser::DUPLICATE_UPDATE
8cc574cf 378 if (!empty($formatted['is_override']) && empty($formatted['status_id'])) {
4f7b71ab 379 array_unshift($values, 'Required parameter missing: Status');
380 return CRM_Import_Parser::ERROR;
381 }
6a488035 382
1a9d4317 383 if (!empty($formatValues['membership_id'])) {
353ffa53 384 $dao = new CRM_Member_BAO_Membership();
4f7b71ab 385 $dao->id = $formatValues['membership_id'];
be2fb01f 386 $dates = ['join_date', 'start_date', 'end_date'];
4f7b71ab 387 foreach ($dates as $v) {
82cc6775 388 if (empty($formatted[$v])) {
4f7b71ab 389 $formatted[$v] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $formatValues['membership_id'], $v);
390 }
391 }
392
393 $formatted['custom'] = CRM_Core_BAO_CustomField::postProcess($formatted,
4f7b71ab 394 $formatValues['membership_id'],
395 'Membership'
396 );
397 if ($dao->find(TRUE)) {
be2fb01f 398 $ids = [
4f7b71ab 399 'membership' => $formatValues['membership_id'],
400 'userId' => $session->get('userID'),
be2fb01f 401 ];
d75f2f47 402
82cc6775
PN
403 if (empty($params['line_item']) && !empty($formatted['membership_type_id'])) {
404 CRM_Price_BAO_LineItem::getLineItemArray($formatted, NULL, 'membership', $formatted['membership_type_id']);
405 }
d75f2f47 406
4f7b71ab 407 $newMembership = CRM_Member_BAO_Membership::create($formatted, $ids, TRUE);
408 if (civicrm_error($newMembership)) {
409 array_unshift($values, $newMembership['is_error'] . ' for Membership ID ' . $formatValues['membership_id'] . '. Row was skipped.');
410 return CRM_Import_Parser::ERROR;
411 }
412 else {
413 $this->_newMemberships[] = $newMembership->id;
414 return CRM_Import_Parser::VALID;
415 }
6a488035
TO
416 }
417 else {
4f7b71ab 418 array_unshift($values, 'Matching Membership record not found for Membership ID ' . $formatValues['membership_id'] . '. Row was skipped.');
419 return CRM_Import_Parser::ERROR;
6a488035
TO
420 }
421 }
6a488035 422 }
6a488035 423
4f7b71ab 424 //Format dates
425 $startDate = CRM_Utils_Date::customFormat(CRM_Utils_Array::value('start_date', $formatted), '%Y-%m-%d');
353ffa53
TO
426 $endDate = CRM_Utils_Date::customFormat(CRM_Utils_Array::value('end_date', $formatted), '%Y-%m-%d');
427 $joinDate = CRM_Utils_Date::customFormat(CRM_Utils_Array::value('join_date', $formatted), '%Y-%m-%d');
6a488035 428
4f7b71ab 429 if ($this->_contactIdIndex < 0) {
56316747 430 $error = $this->checkContactDuplicate($formatValues);
6a488035 431
4f7b71ab 432 if (CRM_Core_Error::isAPIError($error, CRM_Core_ERROR::DUPLICATE_CONTACT)) {
433 $matchedIDs = explode(',', $error['error_message']['params'][0]);
434 if (count($matchedIDs) > 1) {
435 array_unshift($values, 'Multiple matching contact records detected for this row. The membership was not imported');
436 return CRM_Import_Parser::ERROR;
437 }
438 else {
439 $cid = $matchedIDs[0];
440 $formatted['contact_id'] = $cid;
441
442 //fix for CRM-1924
443 $calcDates = CRM_Member_BAO_MembershipType::getDatesForMembershipType($formatted['membership_type_id'],
444 $joinDate,
445 $startDate,
446 $endDate
447 );
448 self::formattedDates($calcDates, $formatted);
449
450 //fix for CRM-3570, exclude the statuses those having is_admin = 1
451 //now user can import is_admin if is override is true.
452 $excludeIsAdmin = FALSE;
a7488080 453 if (empty($formatted['is_override'])) {
4f7b71ab 454 $formatted['exclude_is_admin'] = $excludeIsAdmin = TRUE;
455 }
456 $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($startDate,
457 $endDate,
458 $joinDate,
459 'today',
5f11bbcc
EM
460 $excludeIsAdmin,
461 $formatted['membership_type_id'],
462 $formatted
4f7b71ab 463 );
464
a7488080 465 if (empty($formatted['status_id'])) {
4f7b71ab 466 $formatted['status_id'] = $calcStatus['id'];
467 }
a7488080 468 elseif (empty($formatted['is_override'])) {
4f7b71ab 469 if (empty($calcStatus)) {
470 array_unshift($values, 'Status in import row (' . $formatValues['status_id'] . ') does not match calculated status based on your configured Membership Status Rules. Record was not imported.');
471 return CRM_Import_Parser::ERROR;
472 }
473 elseif ($formatted['status_id'] != $calcStatus['id']) {
474 //Status Hold" is either NOT mapped or is FALSE
475 array_unshift($values, 'Status in import row (' . $formatValues['status_id'] . ') does not match calculated status based on your configured Membership Status Rules (' . $calcStatus['name'] . '). Record was not imported.');
476 return CRM_Import_Parser::ERROR;
477 }
478 }
479
480 $newMembership = civicrm_api3('membership', 'create', $formatted);
481
482 $this->_newMemberships[] = $newMembership['id'];
483 return CRM_Import_Parser::VALID;
484 }
6a488035
TO
485 }
486 else {
4f7b71ab 487 // Using new Dedupe rule.
be2fb01f 488 $ruleParams = [
4f7b71ab 489 'contact_type' => $this->_contactType,
353ffa53 490 'used' => 'Unsupervised',
be2fb01f 491 ];
4f7b71ab 492 $fieldsArray = CRM_Dedupe_BAO_Rule::dedupeRuleFields($ruleParams);
493 $disp = '';
494
495 foreach ($fieldsArray as $value) {
496 if (array_key_exists(trim($value), $params)) {
497 $paramValue = $params[trim($value)];
498 if (is_array($paramValue)) {
499 $disp .= $params[trim($value)][0][trim($value)] . " ";
500 }
501 else {
502 $disp .= $params[trim($value)] . " ";
503 }
504 }
6a488035 505 }
6a488035 506
a7488080 507 if (!empty($params['external_identifier'])) {
4f7b71ab 508 if ($disp) {
509 $disp .= "AND {$params['external_identifier']}";
6a488035 510 }
4f7b71ab 511 else {
512 $disp = $params['external_identifier'];
6a488035
TO
513 }
514 }
515
4f7b71ab 516 array_unshift($values, 'No matching Contact found for (' . $disp . ')');
517 return CRM_Import_Parser::ERROR;
6a488035
TO
518 }
519 }
520 else {
a7488080 521 if (!empty($formatValues['external_identifier'])) {
4f7b71ab 522 $checkCid = new CRM_Contact_DAO_Contact();
523 $checkCid->external_identifier = $formatValues['external_identifier'];
524 $checkCid->find(TRUE);
525 if ($checkCid->id != $formatted['contact_id']) {
d79be26c 526 array_unshift($values, 'Mismatch of External ID:' . $formatValues['external_identifier'] . ' and Contact Id:' . $formatted['contact_id']);
4f7b71ab 527 return CRM_Import_Parser::ERROR;
6a488035
TO
528 }
529 }
530
4f7b71ab 531 //to calculate dates
532 $calcDates = CRM_Member_BAO_MembershipType::getDatesForMembershipType($formatted['membership_type_id'],
533 $joinDate,
534 $startDate,
535 $endDate
536 );
537 self::formattedDates($calcDates, $formatted);
538 //end of date calculation part
539
540 //fix for CRM-3570, exclude the statuses those having is_admin = 1
541 //now user can import is_admin if is override is true.
542 $excludeIsAdmin = FALSE;
a7488080 543 if (empty($formatted['is_override'])) {
4f7b71ab 544 $formatted['exclude_is_admin'] = $excludeIsAdmin = TRUE;
545 }
546 $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($startDate,
547 $endDate,
548 $joinDate,
549 'today',
5f11bbcc
EM
550 $excludeIsAdmin,
551 $formatted['membership_type_id'],
552 $formatted
4f7b71ab 553 );
a7488080 554 if (empty($formatted['status_id'])) {
4f7b71ab 555 $formatted['status_id'] = CRM_Utils_Array::value('id', $calcStatus);
556 }
a7488080 557 elseif (empty($formatted['is_override'])) {
4f7b71ab 558 if (empty($calcStatus)) {
559 array_unshift($values, 'Status in import row (' . CRM_Utils_Array::value('status_id', $formatValues) . ') does not match calculated status based on your configured Membership Status Rules. Record was not imported.');
560 return CRM_Import_Parser::ERROR;
6a488035 561 }
4f7b71ab 562 elseif ($formatted['status_id'] != $calcStatus['id']) {
563 //Status Hold" is either NOT mapped or is FALSE
564 array_unshift($values, 'Status in import row (' . CRM_Utils_Array::value('status_id', $formatValues) . ') does not match calculated status based on your configured Membership Status Rules (' . $calcStatus['name'] . '). Record was not imported.');
565 return CRM_Import_Parser::ERROR;
6a488035
TO
566 }
567 }
568
4f7b71ab 569 $newMembership = civicrm_api3('membership', 'create', $formatted);
6a488035 570
4f7b71ab 571 $this->_newMemberships[] = $newMembership['id'];
572 return CRM_Import_Parser::VALID;
6a488035 573 }
f719e41c 574 }
575 catch (Exception $e) {
576 array_unshift($values, $e->getMessage());
577 return CRM_Import_Parser::ERROR;
578 }
6a488035
TO
579 }
580
581 /**
ceb10dc7 582 * Get the array of successfully imported membership id's
6a488035
TO
583 *
584 * @return array
6a488035 585 */
00be9182 586 public function &getImportedMemberships() {
6a488035
TO
587 return $this->_newMemberships;
588 }
589
590 /**
100fef9d 591 * The initializer code, called before the processing
6a488035
TO
592 *
593 * @return void
6a488035 594 */
b09fe5ed
TO
595 public function fini() {
596 }
6a488035
TO
597
598 /**
599 * to calculate join, start and end dates
600 *
b2363ea8
TO
601 * @param array $calcDates
602 * Array of dates returned by getDatesForMembershipType().
6a488035 603 *
2a6da8d7 604 * @param $formatted
6a488035 605 *
6a488035 606 */
00be9182 607 public function formattedDates($calcDates, &$formatted) {
be2fb01f 608 $dates = [
6a488035
TO
609 'join_date',
610 'start_date',
611 'end_date',
be2fb01f 612 ];
6a488035
TO
613
614 foreach ($dates as $d) {
615 if (isset($formatted[$d]) &&
616 !CRM_Utils_System::isNull($formatted[$d])
617 ) {
618 $formatted[$d] = CRM_Utils_Date::isoToMysql($formatted[$d]);
619 }
620 elseif (isset($calcDates[$d])) {
621 $formatted[$d] = CRM_Utils_Date::isoToMysql($calcDates[$d]);
622 }
623 }
624 }
77b97be7 625
3c15495c 626 /**
627 * @deprecated - this function formats params according to v2 standards but
628 * need to be sure about the impact of not calling it so retaining on the import class
629 * take the input parameter list as specified in the data model and
630 * convert it into the same format that we use in QF and BAO object
631 *
b2363ea8
TO
632 * @param array $params
633 * Associative array of property name/value.
3c15495c 634 * pairs to insert in new contact.
b2363ea8
TO
635 * @param array $values
636 * The reformatted properties that we can use internally.
3c15495c 637 *
77b97be7 638 * @param array|bool $create Is the formatted Values array going to
3c15495c 639 * be used for CRM_Member_BAO_Membership:create()
640 *
77b97be7 641 * @throws Exception
3c15495c 642 * @return array|error
3c15495c 643 */
00be9182 644 public function membership_format_params($params, &$values, $create = FALSE) {
3c15495c 645 require_once 'api/v3/utils.php';
646 $fields = CRM_Member_DAO_Membership::fields();
647 _civicrm_api3_store_values($fields, $params, $values);
648
481a74f4 649 $customFields = CRM_Core_BAO_CustomField::getFields('Membership');
3c15495c 650
651 foreach ($params as $key => $value) {
652 // ignore empty values or empty arrays etc
653 if (CRM_Utils_System::isNull($value)) {
654 continue;
655 }
656
657 //Handling Custom Data
658 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
659 $values[$key] = $value;
660 $type = $customFields[$customFieldID]['html_type'];
6cc845ad 661 if ($type == 'CheckBox' || $type == 'Multi-Select') {
481a74f4 662 $mulValues = explode(',', $value);
b09fe5ed 663 $customOption = CRM_Core_BAO_CustomOption::getCustomOption($customFieldID, TRUE);
be2fb01f 664 $values[$key] = [];
481a74f4 665 foreach ($mulValues as $v1) {
22e263ad 666 foreach ($customOption as $customValueID => $customLabel) {
3c15495c 667 $customValue = $customLabel['value'];
481a74f4 668 if ((strtolower($customLabel['label']) == strtolower(trim($v1))) ||
353ffa53
TO
669 (strtolower($customValue) == strtolower(trim($v1)))
670 ) {
481a74f4 671 if ($type == 'CheckBox') {
3c15495c 672 $values[$key][$customValue] = 1;
0db6c3e1
TO
673 }
674 else {
3c15495c 675 $values[$key][] = $customValue;
676 }
677 }
678 }
679 }
680 }
681 }
682
683 switch ($key) {
684 case 'membership_contact_id':
685 if (!CRM_Utils_Rule::integer($value)) {
f719e41c 686 throw new Exception("contact_id not valid: $value");
3c15495c 687 }
353ffa53 688 $dao = new CRM_Core_DAO();
be2fb01f 689 $qParams = [];
353ffa53 690 $svq = $dao->singleValueQuery("SELECT id FROM civicrm_contact WHERE id = $value",
3c15495c 691 $qParams
692 );
693 if (!$svq) {
f719e41c 694 throw new Exception("Invalid Contact ID: There is no contact record with contact_id = $value.");
3c15495c 695 }
696 $values['contact_id'] = $values['membership_contact_id'];
697 unset($values['membership_contact_id']);
698 break;
699
700 case 'membership_type_id':
701 if (!CRM_Utils_Array::value($value, CRM_Member_PseudoConstant::membershipType())) {
f719e41c 702 throw new Exception('Invalid Membership Type Id');
3c15495c 703 }
704 $values[$key] = $value;
705 break;
706
707 case 'membership_type':
708 $membershipTypeId = CRM_Utils_Array::key(ucfirst($value),
353ffa53 709 CRM_Member_PseudoConstant::membershipType()
3c15495c 710 );
711 if ($membershipTypeId) {
a7488080 712 if (!empty($values['membership_type_id']) &&
3c15495c 713 $membershipTypeId != $values['membership_type_id']
714 ) {
f719e41c 715 throw new Exception('Mismatched membership Type and Membership Type Id');
3c15495c 716 }
717 }
718 else {
f719e41c 719 throw new Exception('Invalid Membership Type');
3c15495c 720 }
721 $values['membership_type_id'] = $membershipTypeId;
722 break;
723
724 case 'status_id':
725 if (!CRM_Utils_Array::value($value, CRM_Member_PseudoConstant::membershipStatus())) {
f719e41c 726 throw new Exception('Invalid Membership Status Id');
3c15495c 727 }
728 $values[$key] = $value;
729 break;
730
731 case 'membership_status':
732 $membershipStatusId = CRM_Utils_Array::key(ucfirst($value),
353ffa53 733 CRM_Member_PseudoConstant::membershipStatus()
3c15495c 734 );
735 if ($membershipStatusId) {
a7488080 736 if (!empty($values['status_id']) &&
3c15495c 737 $membershipStatusId != $values['status_id']
738 ) {
f719e41c 739 throw new Exception('Mismatched membership Status and Membership Status Id');
3c15495c 740 }
741 }
742 else {
f719e41c 743 throw new Exception('Invalid Membership Status');
3c15495c 744 }
745 $values['status_id'] = $membershipStatusId;
746 break;
747
748 default:
749 break;
750 }
751 }
752
753 _civicrm_api3_custom_format_params($params, $values, 'Membership');
754
3c15495c 755 if ($create) {
756 // CRM_Member_BAO_Membership::create() handles membership_start_date,
757 // membership_end_date and membership_source. So, if $values contains
758 // membership_start_date, membership_end_date or membership_source,
759 // convert it to start_date, end_date or source
be2fb01f 760 $changes = [
3c15495c 761 'membership_start_date' => 'start_date',
762 'membership_end_date' => 'end_date',
763 'membership_source' => 'source',
be2fb01f 764 ];
3c15495c 765
766 foreach ($changes as $orgVal => $changeVal) {
767 if (isset($values[$orgVal])) {
768 $values[$changeVal] = $values[$orgVal];
769 unset($values[$orgVal]);
770 }
771 }
772 }
773
774 return NULL;
775 }
96025800 776
6a488035 777}