1 (function(angular
, $, _
) {
2 angular
.module('exportui', CRM
.angRequires('exportui'));
4 angular
.module('exportui', CRM
.angular
.modules
)
6 .controller('ExportUiCtrl', function($scope
, $timeout
, crmApi
, dialogService
) {
7 var ts
= $scope
.ts
= CRM
.ts('exportui'),
8 // Which relationships we've already looked up for the preview
11 $scope
.option_list
= CRM
.vars
.exportUi
.option_list
;
12 $scope
.contact_types
= CRM
.vars
.exportUi
.contact_types
;
13 $scope
.location_type_id
= [{id
: '', text
: ts('Primary')}].concat(CRM
.vars
.exportUi
.location_type_id
);
14 // Map of all fields keyed by name
15 $scope
.fields
= _
.transform(CRM
.vars
.exportUi
.fields
, function(result
, category
) {
16 _
.each(category
.children
, function(field
) {
17 result
[field
.id
] = field
;
21 preview
: CRM
.vars
.exportUi
.preview_data
,
25 // For the "add new field" dropdown
26 $scope
.new = {col
: ''};
27 var contactTypes
= _
.transform($scope
.contact_types
, function(result
, type
) {
29 _
.each(type
.children
|| [], function(subType
) {
30 result
.push(subType
.id
);
33 var cids
= _
.filter(_
.map(CRM
.vars
.exportUi
.preview_data
, 'id'));
35 // Get fields for performing the export or saving the field mapping
36 function getSelectedColumns() {
38 _
.each($scope
.data
.columns
, function(col
, no
) {
39 // Make a copy of col without the extra angular props
40 var item
= JSON
.parse(angular
.toJson(col
));
42 delete item
.mapping_id
;
43 item
.contact_type
= $scope
.data
.contact_type
|| 'Contact';
44 item
.column_number
= no
;
50 // Load a saved field mapping
51 function loadFieldMap(map
) {
52 $scope
.data
.columns
= [];
53 var mapContactTypes
= [];
54 _
.each(map
, function(col
) {
55 if (_
.contains(contactTypes
, col
.contact_type
)) {
56 mapContactTypes
.push(col
.contact_type
);
58 if (col
.relationship_type_id
&& col
.relationship_direction
) {
59 col
.select
= '' + col
.relationship_type_id
+ '_' + col
.relationship_direction
;
61 col
.select
= col
.name
;
63 $scope
.data
.columns
.push(col
);
65 // If all the fields are for the same contact type, set it form-wide
66 if (!$scope
.data
.contact_type
&& _
.unique(mapContactTypes
).length
=== 1) {
67 $scope
.data
.contact_type
= mapContactTypes
[0];
71 // Return fields relevant to a contact type
72 // Filter out non-contact fields (for relationship selectors)
73 function filterFields(contactType
, onlyContact
) {
74 return _
.transform(CRM
.vars
.exportUi
.fields
, function(result
, cat
) {
75 if (!cat
.is_contact
&& onlyContact
) {
78 var fields
= _
.filter(cat
.children
, function(field
) {
79 return !field
.contact_type
|| !contactType
|| _
.contains(field
.contact_type
, contactType
);
91 $scope
.getFields = function() {
92 return {results
: filterFields($scope
.data
.contact_type
)};
95 $scope
.getRelatedFields = function(contact_type
) {
97 return {results
: filterFields(contact_type
, true)};
101 $scope
.showPreview = function(row
, field
) {
102 var key
= field
.name
;
103 if (field
.relationship_type_id
&& field
.relationship_direction
) {
104 fetchRelations(field
);
105 key
= '' + field
.relationship_type_id
+ '_' + field
.relationship_direction
+ '_' + key
;
107 if (field
.location_type_id
) {
108 key
+= '_' + field
.location_type_id
+ (field
.phone_type_id
? '_' + field
.phone_type_id
: '');
110 return field
.name
? row
[key
] : '';
113 function fetchRelations(field
) {
114 if (cids
.length
&& !relations
[field
.relationship_type_id
+ field
.relationship_direction
]) {
115 relations
[field
.relationship_type_id
+ field
.relationship_direction
] = true;
116 var a
= field
.relationship_direction
[0],
117 b
= field
.relationship_direction
[2],
119 relationship_type_id
: field
.relationship_type_id
,
120 filters
: {is_current
: 1},
121 "api.Contact.getsingle": {id
: '$value.contact_id_' + b
}
123 params
['contact_' + a
] = {'IN': cids
};
124 (function (field
, params
) {
125 crmApi('Relationship', 'get', params
).then(function (data
) {
126 _
.each(data
.values
, function (rel
) {
127 var row
= cids
.indexOf(rel
['contact_id_' + a
]);
129 _
.each(rel
["api.Contact.getsingle"], function (item
, key
) {
130 $scope
.data
.preview
[row
][field
.relationship_type_id
+ '_' + field
.relationship_direction
+ '_' + key
] = item
;
139 $scope
.saveMappingDialog = function() {
140 var options
= CRM
.utils
.adjustDialogDefaults({
144 title
: ts('Save Fields')
146 var mappingNames
= _
.transform(CRM
.vars
.exportUi
.mapping_names
, function(result
, n
, key
) {
147 result
[key
] = n
.toLowerCase();
152 overwrite
: CRM
.vars
.exportUi
.mapping_id
? '1' : '0',
153 mapping_id
: CRM
.vars
.exportUi
.mapping_id
,
154 mapping_type_id
: CRM
.vars
.exportUi
.mapping_type_id
,
155 mapping_names
: CRM
.vars
.exportUi
.mapping_names
,
156 new_name
: CRM
.vars
.exportUi
.mapping_id
? CRM
.vars
.exportUi
.mapping_names
[CRM
.vars
.exportUi
.mapping_id
] : '',
157 description
: CRM
.vars
.exportUi
.mapping_description
,
158 nameIsUnique: function() {
159 return !_
.contains(mappingNames
, this.new_name
.toLowerCase()) || (this.overwrite
=== '1' && this.new_name
.toLowerCase() === this.mapping_names
[this.mapping_id
].toLowerCase());
161 saveMapping: function() {
164 id
: this.overwrite
=== '1' ? this.mapping_id
: null,
165 mapping_type_id
: this.mapping_type_id
,
167 description
: this.description
,
170 mappingFields
= getSelectedColumns();
172 _
.each(mappingFields
, function(field
) {
176 mapping
['api.MappingField.replace'] = {values
: mappingFields
};
177 crmApi('Mapping', 'create', mapping
).then(function(result
) {
178 CRM
.vars
.exportUi
.mapping_id
= result
.id
;
179 CRM
.vars
.exportUi
.mapping_description
= mapping
.description
;
180 CRM
.vars
.exportUi
.mapping_names
[result
.id
] = mapping
.name
;
181 // Call loadFieldMap to update field ids in $scope.data.columns
182 loadFieldMap(result
.values
[0]['api.MappingField.replace'].values
);
183 dialogService
.close('exportSaveMapping');
187 dialogService
.open('exportSaveMapping', '~/exportui/exportSaveMapping.html', model
, options
);
190 // Load saved mapping
191 if ($('input[name=export_field_map]').val()) {
192 loadFieldMap(JSON
.parse($('input[name=export_field_map]').val()));
196 $scope
.$watch('new.col', function(val
) {
198 $timeout(function() {
200 $scope
.data
.columns
.push({
203 location_type_id
: null,
205 website_type_id
: null,
206 im_provider_id
: null,
207 relationship_type_id
: null,
208 relationship_direction
: null
215 // When adding/removing columns
216 $scope
.$watch('data.columns', function(values
) {
217 _
.each(values
, function(col
, index
) {
218 // Remove empty values
220 $scope
.data
.columns
.splice(index
, 1);
223 var selection
= $scope
.fields
[col
.select
];
224 if (selection
.relationship_type_id
) {
225 col
.relationship_type_id
= selection
.relationship_type_id
;
226 col
.relationship_direction
= col
.select
.slice(col
.select
.indexOf('_')+1);
228 col
.name
= col
.select
;
229 col
.relationship_direction
= col
.relationship_type_id
= null;
231 var field
= col
.name
? $scope
.fields
[col
.name
] : {};
232 col
.location_type_id
= field
.has_location
? col
.location_type_id
|| '' : null;
233 _
.each($scope
.option_list
, function(options
, list
) {
234 col
[list
] = (col
.location_type_id
|| !field
.has_location
) && field
.option_list
=== list
? col
[list
] || options
[0].id
: null;
238 // Store data in a quickform hidden field
239 var selectedColumns
= getSelectedColumns();
240 $('input[name=export_field_map]').val(JSON
.stringify(selectedColumns
));
242 // Hide submit button when no fields selected
243 $('.crm-button_qf_Map_next').toggle(!!selectedColumns
.length
);
247 })(angular
, CRM
.$, CRM
._
);