1 /** 2 * @author Brian Carlsen 3 * @version 1.0.0 4 * 5 * Serves as a wrapper to the MINDBODY Client Service, providing 6 * some additional functionality. 7 * 8 * All Client Service methods are available returning 9 * 1) An extracted result using the instance method with the same name 10 * 2) The raw array response using the instance method with the same name post-fixed with 'Response'. 11 * The array consists of: 12 * i) The object represtentation of the SOAP response 13 * ii) The raw XML SOAP response 14 * iii) The raw header info of the SOAP response 15 */ 16 17 var Promise = require( 'bluebird' ); 18 19 var mboService = require( './mbo_Service' ); 20 21 //--------------- ClientService Class --------------------- 22 23 /** 24 * Represents the MINDOBDY Client Service. 25 * 26 * @constructor 27 * @param {string} username Username of the MINDBODY client interacting with the service. 28 * @param {string} password Password of the MINDBODY client interacting with the service. 29 * @return {mbo_ClientService} Returns the Client Service. 30 */ 31 function mbo_ClientService( username, password ) { 32 mboService.call( this, 'ClientService', username, password ); 33 } 34 mbo_ClientService.prototype = Object.create( mboService.prototype ); 35 mbo_ClientService.prototype.constructor = mbo_ClientService; 36 37 //------------- Methods ---------------------- 38 39 /** 40 * Retrieves the number of clients. 41 * @param {string} [search] Search string to filter results. 42 * @return {Promise} An A+ Promise passed the total number of clients, 43 * matching the search string if given. 44 */ 45 mbo_ClientService.prototype.getClientCount = function( search ) { 46 var args = { 47 SearchText: search || '', 48 PageSize: 1, 49 XMLDetail: 'Bare' 50 }; 51 52 return this.GetClientsResponse( args ) 53 .spread( function( result, raw, header ) { 54 return result.GetClientsResult.ResultCount; 55 } ) 56 .catch( function( err ) { 57 throw err; 58 } ); 59 }; 60 61 /** 62 * Retrieves all clients, filtered by search text if given. 63 * @param {string} [search] Search string to filter results. 64 * @return {Promise} An A+ Promise passed an array of the found clients. 65 */ 66 mbo_ClientService.prototype.getAllClients = function( search, params ) { 67 var self = this; 68 69 return self.getClientCount() 70 .then( function( clientCount ) { 71 var args = params || {}; 72 args.SearchText = search || ''; 73 74 var pageSize = args.PageSize || self.requestDefaults.PageSize, 75 pages = Math.ceil( clientCount / pageSize ), 76 completed = 0 77 clientRequests = []; 78 79 for ( var p = 0; p < pages; ++p ) { // Send all requests 80 args.CurrentPageIndex = p; 81 clientRequests.push( self.GetClients( args ) ); 82 } 83 84 return clientRequests; 85 } ) 86 .then( function( clientRequests ) { 87 return Promise.all( clientRequests ) // Wait for all requests to complete 88 .then( function( clientRequests ) { 89 var clients = []; 90 91 for ( var i in clientRequests ) { 92 clients = clients.concat( clientRequests[ i ] ); 93 } 94 95 return clients; 96 } ) 97 } ) 98 .catch( function( err ) { 99 throw err; 100 } ); 101 }; 102 103 /** 104 * Retireves the clients matching the given IDs 105 * @param {number|number[]} ids An single or array of client IDs to retrieve. 106 * @return {Promise} An A+ Promise passed an array of clients. 107 */ 108 mbo_ClientService.prototype.getClientsById = function( ids, params ) { 109 var args = params || {}; 110 args.ClientIDs = { 111 string: ids 112 }; 113 114 // If more than 1000 clients, must break query into multiple pages 115 var clientRequests = [], 116 pages = Math.ceil( ids.length / 1000 ); 117 118 for ( var p = 0; p < pages; ++p ) { 119 args.CurrentPageIndex = p; 120 clientRequests.push( this.GetClients( args ) ); 121 } 122 123 return Promise.all( clientRequests ) 124 .then( function( clientRequests ) { 125 var clients = []; 126 127 for ( var i in clientRequests ) { 128 clients = clients.concat( clientRequests[ i ] ); 129 } 130 131 return clients; 132 } ) 133 .catch( function( err ) { 134 throw err; 135 } ); 136 }; 137 138 /** 139 * Retrieves a single client by ID 140 * @param {number} id Teh ID of the requested client 141 * @return {Promise} An A+ Promise passed an object representing the client. 142 */ 143 mbo_ClientService.prototype.getClientById = function( id ) { 144 return this.getClientsById( id ) 145 .then( function( clients ) { 146 if ( clients.length === 1 ) { 147 if ( clients[ 0 ].ID ) { 148 return clients[ 0 ]; 149 } 150 else { 151 return false; 152 } 153 } 154 else { 155 throw new Error( 'More than one client found with same Id.' ); 156 } 157 } ) 158 .catch( function( err ) { 159 throw err; 160 } ); 161 }; 162 163 /** 164 * Gets the values of Client Indexes for a client. 165 * @param {number|string} id The client's Id 166 * @return {Promise} Returns an A+ Promise resolved to an array of objects representing 167 * the client's assigned Client Index values. 168 * Each object has the form { index: { id, name }, value: { id, name } }. 169 * Client Indexes which do not have an assigned value are excluded. 170 */ 171 mbo_ClientService.prototype.getClientIndexValues = function( id ) { 172 var params = { 173 ClientIDs: { string: id }, 174 Fields: { string: [ 'Clients.ClientIndexes' ] } 175 }; 176 177 return this.GetClients( params ) 178 .then( function( client ) { 179 var indexValues = [], 180 indexes = client[ 0 ].ClientIndexes.ClientIndex; 181 182 if ( indexes ) { 183 indexes.forEach( function( index ) { 184 var value = index.Values.ClientIndexValue[ 0 ], 185 indexValue = { 186 index: { 187 id: index.ID, 188 name: index.Name 189 }, 190 value: { 191 id: value.ID, 192 name: value.Name 193 } 194 }; 195 196 indexValues.push( indexValue ); 197 } ); 198 } 199 200 return indexValues; 201 } ) 202 .catch( function( err ) { 203 throw err; 204 } ); 205 }; 206 207 /** 208 * Retrieves Account Balances for Clients 209 * @param {array} ids An array of Client Ids 210 * @return {Promise} An A+ Promise resolved to an object keyed by client Id and values of thier 211 * Account Balance 212 */ 213 mbo_ClientService.prototype.getClientAccountBalancesById = function( ids ) { 214 var self = this, 215 pages = Math.ceil( ids.length / self.requestDefaults.PageSize ), 216 completed = 0 217 balanceRequests = []; 218 219 for ( var p = 0; p < pages; ++p ) { // Send all requests 220 var idStart = p * self.requestDefaults.PageSize, 221 idEnd = ( p + 1 ) * self.requestDefaults.PageSize 222 pageIds = ids.slice( idStart, idEnd ); 223 224 var args = { 225 XMLDetail: 'Bare', 226 CurrentPageIndex: p, 227 ClientIDs: { string: pageIds } 228 }; 229 230 balanceRequests.push( self.GetClientAccountBalances( args ) ); 231 } 232 233 return Promise.all( balanceRequests ) // Wait for all requests to complete 234 .then( function( balanceRequests ) { 235 var balances = {}; 236 237 balanceRequests.forEach( function( balanceRequest ) { 238 balanceRequest.forEach( function( balance ) { 239 balances[ balance.ID ] = parseFloat( balance.AccountBalance ); 240 } ); 241 } ); 242 243 return balances; 244 } ) 245 .catch( function( err ) { 246 throw err; 247 } ); 248 }; 249 250 module.exports = mbo_ClientService;