Call static function statically
[civicrm-core.git] / ang / exportui / exportui.js
1 (function(angular, $, _) {
2 angular.module('exportui', CRM.angRequires('exportui'));
3
4 angular.module('exportui', CRM.angular.modules)
5
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
9 relations = [];
10
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;
18 });
19 }, {});
20 $scope.data = {
21 preview: CRM.vars.exportUi.preview_data,
22 contact_type: '',
23 columns: []
24 };
25 $scope.perms = {
26 admin: CRM.checkPerm('administer CiviCRM')
27 };
28 // For the "add new field" dropdown
29 $scope.new = {col: ''};
30 var contactTypes = _.transform($scope.contact_types, function(result, type) {
31 result.push(type.id);
32 _.each(type.children || [], function(subType) {
33 result.push(subType.id);
34 });
35 });
36 var cids = _.filter(_.map(CRM.vars.exportUi.preview_data, 'id'));
37
38 // Get fields for performing the export or saving the field mapping
39 function getSelectedColumns() {
40 var map = [];
41 _.each($scope.data.columns, function(col, no) {
42 // Make a copy of col without the extra angular props
43 var item = JSON.parse(angular.toJson(col));
44 delete item.select;
45 delete item.mapping_id;
46 item.contact_type = $scope.data.contact_type || 'Contact';
47 item.column_number = no;
48 map.push(item);
49 });
50 return map;
51 }
52
53 // Load a saved field mapping
54 function loadFieldMap(map) {
55 $scope.data.columns = [];
56 var mapContactTypes = [];
57 _.each(map, function(col) {
58 if (_.contains(contactTypes, col.contact_type)) {
59 mapContactTypes.push(col.contact_type);
60 }
61 if (col.relationship_type_id && col.relationship_direction) {
62 col.select = '' + col.relationship_type_id + '_' + col.relationship_direction;
63 } else {
64 col.select = col.name;
65 }
66 $scope.data.columns.push(col);
67 });
68 // If all the fields are for the same contact type, set it form-wide
69 if (!$scope.data.contact_type && _.unique(mapContactTypes).length === 1) {
70 $scope.data.contact_type = mapContactTypes[0];
71 }
72 }
73
74 // Return fields relevant to a contact type
75 // Filter out non-contact fields (for relationship selectors)
76 function filterFields(contactType, onlyContact) {
77 return _.transform(CRM.vars.exportUi.fields, function(result, cat) {
78 if (!cat.is_contact && onlyContact) {
79 return;
80 }
81 var fields = _.filter(cat.children, function(field) {
82 return !field.contact_type || !contactType || _.contains(field.contact_type, contactType);
83 });
84 if (fields.length) {
85 result.push({
86 id: cat.id,
87 text: cat.text,
88 children: fields
89 });
90 }
91 });
92 }
93
94 $scope.getFields = function() {
95 return {results: filterFields($scope.data.contact_type)};
96 };
97
98 $scope.getRelatedFields = function(contact_type) {
99 return function() {
100 return {results: filterFields(contact_type, true)};
101 };
102 };
103
104 $scope.showPreview = function(row, field) {
105 var key = field.name;
106 if (field.relationship_type_id && field.relationship_direction) {
107 fetchRelations(field);
108 key = '' + field.relationship_type_id + '_' + field.relationship_direction + '_' + key;
109 }
110 if (field.location_type_id) {
111 key += '_' + field.location_type_id + (field.phone_type_id ? '_' + field.phone_type_id : '');
112 }
113 return field.name ? row[key] : '';
114 };
115
116 function fetchRelations(field) {
117 if (cids.length && !relations[field.relationship_type_id + field.relationship_direction]) {
118 relations[field.relationship_type_id + field.relationship_direction] = true;
119 var a = field.relationship_direction[0],
120 b = field.relationship_direction[2],
121 params = {
122 relationship_type_id: field.relationship_type_id,
123 filters: {is_current: 1},
124 "api.Contact.getsingle": {id: '$value.contact_id_' + b}
125 };
126 params['contact_' + a] = {'IN': cids};
127 (function (field, params) {
128 crmApi('Relationship', 'get', params).then(function (data) {
129 _.each(data.values, function (rel) {
130 var row = cids.indexOf(rel['contact_id_' + a]);
131 if (row > -1) {
132 _.each(rel["api.Contact.getsingle"], function (item, key) {
133 $scope.data.preview[row][field.relationship_type_id + '_' + field.relationship_direction + '_' + key] = item;
134 });
135 }
136 });
137 });
138 })(field, params);
139 }
140 }
141
142 $scope.saveMappingDialog = function() {
143 var options = CRM.utils.adjustDialogDefaults({
144 width: '40%',
145 height: 300,
146 autoOpen: false,
147 title: ts('Save Fields')
148 });
149 var mappingNames = _.transform(CRM.vars.exportUi.mapping_names, function(result, n, key) {
150 result[key] = n.toLowerCase();
151 });
152 var model = {
153 ts: ts,
154 saving: false,
155 overwrite: CRM.vars.exportUi.mapping_id ? '1' : '0',
156 mapping_id: CRM.vars.exportUi.mapping_id,
157 mapping_type_id: CRM.vars.exportUi.mapping_type_id,
158 mapping_names: CRM.vars.exportUi.mapping_names,
159 new_name: CRM.vars.exportUi.mapping_id ? CRM.vars.exportUi.mapping_names[CRM.vars.exportUi.mapping_id] : '',
160 description: CRM.vars.exportUi.mapping_description,
161 nameIsUnique: function() {
162 return !_.contains(mappingNames, this.new_name.toLowerCase()) || (this.overwrite === '1' && this.new_name.toLowerCase() === this.mapping_names[this.mapping_id].toLowerCase());
163 },
164 saveMapping: function() {
165 this.saving = true;
166 var mapping = {
167 id: this.overwrite === '1' ? this.mapping_id : null,
168 mapping_type_id: this.mapping_type_id,
169 name: this.new_name,
170 description: this.description,
171 sequential: 1
172 },
173 mappingFields = getSelectedColumns();
174 if (!mapping.id) {
175 _.each(mappingFields, function(field) {
176 delete field.id;
177 });
178 }
179 mapping['api.MappingField.replace'] = {values: mappingFields};
180 crmApi('Mapping', 'create', mapping).then(function(result) {
181 CRM.vars.exportUi.mapping_id = result.id;
182 CRM.vars.exportUi.mapping_description = mapping.description;
183 CRM.vars.exportUi.mapping_names[result.id] = mapping.name;
184 // Call loadFieldMap to update field ids in $scope.data.columns
185 loadFieldMap(result.values[0]['api.MappingField.replace'].values);
186 dialogService.close('exportSaveMapping');
187 });
188 }
189 };
190 dialogService.open('exportSaveMapping', '~/exportui/exportSaveMapping.html', model, options);
191 };
192
193 // Load saved mapping
194 if ($('input[name=export_field_map]').val()) {
195 loadFieldMap(JSON.parse($('input[name=export_field_map]').val()));
196 }
197
198 // Add new col
199 $scope.$watch('new.col', function(val) {
200 var field = val;
201 $timeout(function() {
202 if (field) {
203 $scope.data.columns.push({
204 select: field,
205 name: '',
206 location_type_id: null,
207 phone_type_id: null,
208 website_type_id: null,
209 im_provider_id: null,
210 relationship_type_id: null,
211 relationship_direction: null
212 });
213 $scope.new.col = '';
214 }
215 });
216 });
217
218 // When adding/removing columns
219 $scope.$watch('data.columns', function(values) {
220 _.each(values, function(col, index) {
221 // Remove empty values
222 if (!col.select) {
223 $scope.data.columns.splice(index, 1);
224 } else {
225 // Format item
226 var selection = $scope.fields[col.select];
227 if (selection.relationship_type_id) {
228 col.relationship_type_id = selection.relationship_type_id;
229 col.relationship_direction = col.select.slice(col.select.indexOf('_')+1);
230 } else {
231 col.name = col.select;
232 col.relationship_direction = col.relationship_type_id = null;
233 }
234 var field = col.name ? $scope.fields[col.name] : {};
235 col.location_type_id = field.has_location ? col.location_type_id || '' : null;
236 _.each($scope.option_list, function(options, list) {
237 col[list] = (col.location_type_id || !field.has_location) && field.option_list === list ? col[list] || options[0].id : null;
238 });
239 }
240 });
241 // Store data in a quickform hidden field
242 var selectedColumns = getSelectedColumns();
243 $('input[name=export_field_map]').val(JSON.stringify(selectedColumns));
244
245 // Hide submit button when no fields selected
246 $('.crm-button_qf_Map_next').toggle(!!selectedColumns.length);
247 }, true);
248 });
249
250 })(angular, CRM.$, CRM._);