Merge pull request #4082 from monishdeb/CRM-14784
[civicrm-core.git] / CRM / Activity / Import / Parser / Activity.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
06b69b18 4 | CiviCRM version 4.5 |
6a488035 5 +--------------------------------------------------------------------+
06b69b18 6 | Copyright CiviCRM LLC (c) 2004-2014 |
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 +--------------------------------------------------------------------+
26*/
27
28/**
29 *
30 * @package CRM
06b69b18 31 * @copyright CiviCRM LLC (c) 2004-2014
6a488035
TO
32 * $Id$
33 *
34 */
35
36require_once 'api/api.php';
37
38/**
39 * class to parse activity csv files
40 */
41class CRM_Activity_Import_Parser_Activity extends CRM_Activity_Import_Parser {
42
43 protected $_mapperKeys;
44
45 private $_contactIdIndex;
46 private $_activityTypeIndex;
47 private $_activityLabelIndex;
48 private $_activityDateIndex;
49
50 /**
ceb10dc7 51 * Array of successfully imported activity id's
6a488035
TO
52 *
53 * @array
54 */
55 protected $_newActivity;
56
57 /**
58 * class constructor
59 */
60 function __construct(&$mapperKeys, $mapperLocType = NULL, $mapperPhoneType = NULL) {
61 parent::__construct();
62 $this->_mapperKeys = &$mapperKeys;
63 }
64
65 /**
66 * the initializer code, called before the processing
67 *
68 * @return void
69 * @access public
70 */
71 function init() {
cc6f3942 72 $activityContact = CRM_Activity_BAO_ActivityContact::import();
73 $activityTarget['target_contact_id'] = $activityContact['contact_id'];
6a488035 74 $fields = array_merge(CRM_Activity_BAO_Activity::importableFields(),
cc6f3942 75 $activityTarget
6a488035
TO
76 );
77
cc6f3942 78 $fields = array_merge($fields, array(
4039effc
JP
79 'source_contact_id' => array(
80 'title' => ts('Source Contact'),
81 'headerPattern' => '/Source.Contact?/i',
82 ),
cc6f3942 83 'activity_label' => array(
84 'title' => ts('Activity Type Label'),
85 'headerPattern' => '/(activity.)?type label?/i',
86 )
87 ));
6a488035
TO
88
89 foreach ($fields as $name => $field) {
90 $field['type'] = CRM_Utils_Array::value('type', $field, CRM_Utils_Type::T_INT);
91 $field['dataPattern'] = CRM_Utils_Array::value('dataPattern', $field, '//');
92 $field['headerPattern'] = CRM_Utils_Array::value('headerPattern', $field, '//');
93 $this->addField($name, $field['title'], $field['type'], $field['headerPattern'], $field['dataPattern']);
94 }
95
96 $this->_newActivity = array();
97
98 $this->setActiveFields($this->_mapperKeys);
99
100 // FIXME: we should do this in one place together with Form/MapField.php
101 $this->_contactIdIndex = -1;
102 $this->_activityTypeIndex = -1;
103 $this->_activityLabelIndex = -1;
104 $this->_activityDateIndex = -1;
105
106 $index = 0;
107 foreach ($this->_mapperKeys as $key) {
108 switch ($key) {
109 case 'target_contact_id':
110 case 'external_identifier':
111 $this->_contactIdIndex = $index;
112 break;
113
114 case 'activity_label':
115 $this->_activityLabelIndex = $index;
116 break;
117
118 case 'activity_type_id':
119 $this->_activityTypeIndex = $index;
120 break;
121
122 case 'activity_date_time':
123 $this->_activityDateIndex = $index;
124 break;
125 }
126 $index++;
127 }
128 }
129
130 /**
131 * handle the values in mapField mode
132 *
133 * @param array $values the array of values belonging to this line
134 *
135 * @return boolean
136 * @access public
137 */
138 function mapField(&$values) {
a05662ef 139 return CRM_Import_Parser::VALID;
6a488035
TO
140 }
141
142 /**
143 * handle the values in preview mode
144 *
145 * @param array $values the array of values belonging to this line
146 *
147 * @return boolean the result of this processing
148 * @access public
149 */
150 function preview(&$values) {
151 return $this->summary($values);
152 }
153
154 /**
155 * handle the values in summary mode
156 *
157 * @param array $values the array of values belonging to this line
158 *
159 * @return boolean the result of this processing
160 * @access public
161 */
162 function summary(&$values) {
163 $erroneousField = NULL;
164 $response = $this->setActiveFieldValues($values, $erroneousField);
165 $index = -1;
166 $errorRequired = FALSE;
167
168 if ($this->_activityTypeIndex > -1 && $this->_activityLabelIndex > -1) {
169 array_unshift($values, ts('Please select either Activity Type ID OR Activity Type Label.'));
a05662ef 170 return CRM_Import_Parser::ERROR;
6a488035
TO
171 }
172 elseif ($this->_activityLabelIndex > -1) {
173 $index = $this->_activityLabelIndex;
174 }
175 elseif ($this->_activityTypeIndex > -1) {
176 $index = $this->_activityTypeIndex;
177 }
178
179 if ($index < 0 or $this->_activityDateIndex < 0) {
180 $errorRequired = TRUE;
181 }
182 else {
183 $errorRequired = !CRM_Utils_Array::value($index, $values) || !CRM_Utils_Array::value($this->_activityDateIndex, $values);
184 }
185
186 if ($errorRequired) {
187 array_unshift($values, ts('Missing required fields'));
a05662ef 188 return CRM_Import_Parser::ERROR;
6a488035
TO
189 }
190
191 $params = &$this->getActiveFieldParams();
192
193 $errorMessage = NULL;
194
195 //for date-Formats
196 $session = CRM_Core_Session::singleton();
197 $dateType = $session->get('dateTypes');
198 if (!isset($params['source_contact_id'])) {
199 $params['source_contact_id'] = $session->get('userID');
200 }
201 foreach ($params as $key => $val) {
202 if ($key == 'activity_date_time') {
203 if ($val) {
204 $dateValue = CRM_Utils_Date::formatDate($val, $dateType);
205 if ($dateValue) {
206 $params[$key] = $dateValue;
207 }
208 else {
719a6fec 209 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Activity date', $errorMessage);
6a488035
TO
210 }
211 }
212 }
213 elseif ($key == 'activity_engagement_level' && $val &&
214 !CRM_Utils_Rule::positiveInteger($val)
215 ) {
719a6fec 216 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Activity Engagement Index', $errorMessage);
6a488035
TO
217 }
218 }
219 //date-Format part ends
220
221 //checking error in custom data
222 $params['contact_type'] = isset($this->_contactType) ? $this->_contactType : 'Activity';
223
719a6fec 224 CRM_Contact_Import_Parser_Contact::isErrorInCustomData($params, $errorMessage);
6a488035
TO
225
226 if ($errorMessage) {
227 $tempMsg = "Invalid value for field(s) : $errorMessage";
228 array_unshift($values, $tempMsg);
229 $errorMessage = NULL;
a05662ef 230 return CRM_Import_Parser::ERROR;
6a488035
TO
231 }
232
a05662ef 233 return CRM_Import_Parser::VALID;
6a488035
TO
234 }
235
236 /**
237 * handle the values in import mode
238 *
239 * @param int $onDuplicate the code for what action to take on duplicates
240 * @param array $values the array of values belonging to this line
241 *
242 * @return boolean the result of this processing
243 * @access public
244 */
245 function import($onDuplicate, &$values) {
246 // first make sure this is a valid line
247 $response = $this->summary($values);
248
a05662ef 249 if ($response != CRM_Import_Parser::VALID) {
6a488035
TO
250 return $response;
251 }
252 $params = &$this->getActiveFieldParams();
253 $activityLabel = array_search('activity_label', $this->_mapperKeys);
254 if ($activityLabel) {
255 $params = array_merge($params, array('activity_label' => $values[$activityLabel]));
256 }
257 //for date-Formats
258 $session = CRM_Core_Session::singleton();
259 $dateType = $session->get('dateTypes');
260 if (!isset($params['source_contact_id'])) {
261 $params['source_contact_id'] = $session->get('userID');
262 }
263 $formatted = array();
264 $customFields = CRM_Core_BAO_CustomField::getFields(CRM_Utils_Array::value('contact_type', $params));
265
266 foreach ($params as $key => $val) {
267 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
2272a067
BS
268 if ($key == 'activity_date_time' && $val) {
269 $params[$key] = CRM_Utils_Date::formatDate($val, $dateType);
270 }
271 elseif ($customFields[$customFieldID]['data_type'] == 'Date') {
719a6fec 272 CRM_Contact_Import_Parser_Contact::formatCustomDate($params, $params, $dateType, $key);
6a488035
TO
273 }
274 elseif ($customFields[$customFieldID]['data_type'] == 'Boolean') {
275 $params[$key] = CRM_Utils_String::strtoboolstr($val);
276 }
277 }
278 elseif ($key == 'activity_subject') {
279 $params['subject'] = $val;
280 }
281 }
282 //date-Format part ends
283 require_once 'CRM/Utils/DeprecatedUtils.php';
284 $formatError = _civicrm_api3_deprecated_activity_formatted_param($params, $params, TRUE);
285
286 if ($formatError) {
287 array_unshift($values, $formatError['error_message']);
a05662ef 288 return CRM_Import_Parser::ERROR;
6a488035
TO
289 }
290
291 $params['custom'] = CRM_Core_BAO_CustomField::postProcess($params,
292 CRM_Core_DAO::$_nullObject,
293 NULL,
294 'Activity'
295 );
296
297 if ($this->_contactIdIndex < 0) {
298
299 //retrieve contact id using contact dedupe rule.
300 //since we are support only individual's activity import.
301 $params['contact_type'] = 'Individual';
302 $params['version'] = 3;
303 $error = _civicrm_api3_deprecated_duplicate_formatted_contact($params);
304
305 if (CRM_Core_Error::isAPIError($error, CRM_Core_ERROR::DUPLICATE_CONTACT)) {
306 $matchedIDs = explode(',', $error['error_message']['params'][0]);
307 if (count($matchedIDs) > 1) {
308 array_unshift($values, 'Multiple matching contact records detected for this row. The activity was not imported');
a05662ef 309 return CRM_Import_Parser::ERROR;
6a488035
TO
310 }
311 else {
312 $cid = $matchedIDs[0];
313 $params['target_contact_id'] = $cid;
314 $params['version'] = 3;
315 $newActivity = civicrm_api('activity', 'create', $params);
a7488080 316 if (!empty($newActivity['is_error'])) {
6a488035 317 array_unshift($values, $newActivity['error_message']);
a05662ef 318 return CRM_Import_Parser::ERROR;
6a488035
TO
319 }
320
321 $this->_newActivity[] = $newActivity['id'];
a05662ef 322 return CRM_Import_Parser::VALID;
6a488035
TO
323 }
324 }
325 else {
326 // Using new Dedupe rule.
327 $ruleParams = array(
328 'contact_type' => 'Individual',
329 'used' => 'Unsupervised',
330 );
331 $fieldsArray = CRM_Dedupe_BAO_Rule::dedupeRuleFields($ruleParams);
332
333 $disp = NULL;
334 foreach ($fieldsArray as $value) {
335 if (array_key_exists(trim($value), $params)) {
336 $paramValue = $params[trim($value)];
337 if (is_array($paramValue)) {
338 $disp .= $params[trim($value)][0][trim($value)] . " ";
339 }
340 else {
341 $disp .= $params[trim($value)] . " ";
342 }
343 }
344 }
345
a7488080 346 if (!empty($params['external_identifier'])) {
6a488035
TO
347 if ($disp) {
348 $disp .= "AND {$params['external_identifier']}";
349 }
350 else {
351 $disp = $params['external_identifier'];
352 }
353 }
354
355 array_unshift($values, 'No matching Contact found for (' . $disp . ')');
a05662ef 356 return CRM_Import_Parser::ERROR;
6a488035
TO
357 }
358 }
359 else {
a7488080 360 if (!empty($params['external_identifier'])) {
6a488035
TO
361 $targetContactId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
362 $params['external_identifier'], 'id', 'external_identifier'
363 );
364
a7488080 365 if (!empty($params['target_contact_id']) &&
6a488035
TO
366 $params['target_contact_id'] != $targetContactId
367 ) {
368 array_unshift($values, 'Mismatch of External identifier :' . $params['external_identifier'] . ' and Contact Id:' . $params['target_contact_id']);
a05662ef 369 return CRM_Import_Parser::ERROR;
6a488035
TO
370 }
371 elseif ($targetContactId) {
372 $params['target_contact_id'] = $targetContactId;
373 }
374 else {
375 array_unshift($values, 'No Matching Contact for External identifier :' . $params['external_identifier']);
a05662ef 376 return CRM_Import_Parser::ERROR;
6a488035
TO
377 }
378 }
379
380 $params['version'] = 3;
381 $newActivity = civicrm_api('activity', 'create', $params);
a7488080 382 if (!empty($newActivity['is_error'])) {
6a488035 383 array_unshift($values, $newActivity['error_message']);
a05662ef 384 return CRM_Import_Parser::ERROR;
6a488035
TO
385 }
386
387 $this->_newActivity[] = $newActivity['id'];
a05662ef 388 return CRM_Import_Parser::VALID;
6a488035
TO
389 }
390 }
391
392 /**
393 * the initializer code, called before the processing
394 *
395 * @return void
396 * @access public
397 */
398 function fini() {}
399
400}
401