· 6 years ago · Feb 04, 2020, 09:20 PM
1import axios, { AxiosPromise, AxiosRequestConfig, AxiosResponse } from 'axios';
2import {
3 BestMatchResponse,
4 Mpin,
5 Person,
6 PlaceName,
7 Provider,
8 ProviderId,
9 ProviderLocationId,
10 ProviderType,
11 ProviderWithoutLocation
12} from './models/provider';
13import { LeapfrogScores } from './models/leapfrog';
14import { paramsSerializer } from '../../cs.constants';
15import { planDisplaysMedicalGroupDirectories } from '../../helpers/partner/PlanConfiguration';
16import {
17 MedicalGroupHospitalAffiliations,
18 MedicalGroupPhysicianProfileEntry,
19 MedicalGroupSpecialtyLookup
20} from './models/MedicalGroup';
21import { PhysicianDirectoryEntry } from './models/physicianDirectory';
22import { LocationId, MedicareProviderNumber, SpecialtyId } from './models/location';
23import { PlanCoverageType } from '../partner/models';
24import {
25 coverages,
26 getLocation,
27 networkIds,
28 partner,
29 partnerWithoutFallback,
30 searchDelsys
31} from '../../helpers/userInfo/UserInfo';
32import {
33 CS_FEATURE_DISABLE_FRONTEND_PROVIDER_LOCATION_SORT,
34 CS_FEATURE_ENABLE_MEDICAL_GROUP_SEARCH_RADIUS,
35 CS_FEATURE_ENABLE_PROVIDER_DETAILS_LIMITED_LOCATIONS
36} from '../../mesos/featureFlags';
37import {
38 BestMatchBodyParams,
39 BestMatchRequestParameters,
40 LocalizedContentItem,
41 MultiCoverageLastIndexResult
42} from './models/search';
43import { flatten, isUndefined, mapObject } from 'underscore';
44import { PersonResult } from './models/connectWebSearch';
45import { CareteamProvider } from '../careteam/models';
46
47import { providerAxiosCache } from './decoupled';
48import { ContentJson } from '../../helpers/Content';
49// import { getCurrentPcp } from '../../helpers/PcpDataService/pcpDataService';
50
51export function getProviderDetails(
52 coverageType: PlanCoverageType,
53 providerType: ProviderType,
54 providerId: ProviderId,
55 queryByPartnerId?: boolean,
56 searchRadius?: number,
57 limitLocations?: number
58): AxiosPromise<Provider> {
59 const config: AxiosRequestConfig = {
60 params: {
61 coverageType
62 }
63 };
64 //this.isPcp = PcpHelpers.isLocationUsersCurrentOrPendingPcpLocation(getCurrentPcp(), this.location);
65 this.isPcp = true;
66 if (queryByPartnerId) {
67 config.params.network = searchDelsys(coverageType);
68 config.paramsSerializer = paramsSerializer;
69 return providerAxiosCache.get<Provider>(
70 `/rest/provider/v1/${partner()}/providers/${encodeURIComponent(providerId)}`,
71 config
72 );
73 }
74 if (!isUndefined(limitLocations) && CS_FEATURE_DISABLE_FRONTEND_PROVIDER_LOCATION_SORT()) {
75 config.params.limitLocations = limitLocations;
76 }
77 if (CS_FEATURE_ENABLE_PROVIDER_DETAILS_LIMITED_LOCATIONS()) {
78 return getLocation().then(locationResp => {
79 if (!this.isPcp) {
80 config.params.lon = locationResp.data.coords[0];
81 config.params.lat = locationResp.data.coords[1];
82 if (searchRadius) {
83 config.params.searchRadius = searchRadius;
84 }
85 }
86
87 config.paramsSerializer = paramsSerializer;
88
89 return providerAxiosCache
90 .get<Provider>(
91 `/rest/provider/v2/partners/${partner()}/providerTypes/${providerType}/providers/${providerId}`,
92 config
93 )
94 .then(resp => {
95 if (resp.data && resp.data.locations && resp.data.locations.length === 0) {
96 // Do not filter locations by search radius if we end up filtering all locations.
97 delete config.params.lon;
98 delete config.params.lat;
99 delete config.params.searchRadius;
100 return providerAxiosCache.get<Provider>(
101 `/rest/provider/v2/partners/${partner()}/providerTypes/${providerType}/providers/${providerId}`,
102 config
103 );
104 } else {
105 return resp;
106 }
107 });
108 });
109 } else {
110 return providerAxiosCache.get<Provider>(
111 `/rest/provider/v2/partners/${partner()}/providerTypes/${providerType}/providers/${providerId}`,
112 config
113 );
114 }
115}
116
117export function getMultipleProviderDetails(providerIds: ProviderId[]): Promise<Partial<AxiosResponse<Provider[]>>> {
118 const config: AxiosRequestConfig = {
119 params: {
120 uniqueId: providerIds,
121 coverageType: coverages()
122 },
123 paramsSerializer
124 };
125 // quietly prevent empty arrays from being sent to bulk lookup api or else will complain
126 if (providerIds.length > 0) {
127 return providerAxiosCache.get<Provider[]>(
128 `/rest/provider/v2/partners/${partner()}/providerTypes/person/providers`,
129 config
130 );
131 }
132 return Promise.resolve({ data: [] });
133}
134
135export function getPcpDoctypeUrl(): AxiosPromise<string> {
136 return axios.get('/rest/provider/v1/postbackDoctype');
137}
138
139export function getProvidersWithoutLocation(groupId: ProviderId): AxiosPromise<ProviderWithoutLocation[]> {
140 const config: AxiosRequestConfig = {
141 params: {
142 partnerId: partner()
143 }
144 };
145 return axios.get(`/rest/provider/v3/providerWithoutLocation/groups/${groupId}`, config);
146}
147
148export function getDetailedAffiliationsByProviderAndLocationId(
149 providerId: ProviderId,
150 locationId: LocationId
151): AxiosPromise<MedicalGroupHospitalAffiliations[]> {
152 return axios.get(
153 `/rest/provider/v2/partners/${partner()}/providerTypes/person/providers/${providerId}/locations/${locationId}/affiliations`
154 );
155}
156
157export function getProviderByMpin(mpin: Mpin): AxiosPromise<Person> {
158 const config: AxiosRequestConfig = {
159 params: {
160 mpin,
161 partnerId: partner()
162 }
163 };
164 return axios.get('/rest/provider/v1/providers', config);
165}
166
167export function getPhysicianDirectoryListings(
168 facilityId: ProviderId,
169 coverageType: PlanCoverageType
170): AxiosPromise<PhysicianDirectoryEntry[]> {
171 const config = {
172 params: {
173 network: searchDelsys(coverageType)
174 },
175 paramsSerializer
176 };
177 return axios.get(`/rest/provider/v1/physicianDirectory/${facilityId}`, config);
178}
179
180export function getHospitalSafetyRatings(
181 medicareProviderNumber: MedicareProviderNumber
182): AxiosPromise<LeapfrogScores> | Promise<{}> {
183 if (!medicareProviderNumber) {
184 return Promise.resolve({});
185 }
186 return axios
187 .get(`/rest/provider/v1/hospitalQuality/${medicareProviderNumber}`)
188 .then(resp => resp.data)
189 .catch(() => ({}));
190}
191
192export function medicalGroupPhysicianSpecialties(
193 id: string,
194 coverageType: PlanCoverageType
195): Promise<Partial<AxiosResponse<MedicalGroupSpecialtyLookup | undefined>>> {
196 const config = {
197 params: {
198 coverageType,
199 networks: searchDelsys(coverageType),
200 partnerId: partner()
201 },
202 paramsSerializer
203 };
204 if (!planDisplaysMedicalGroupDirectories()) {
205 return Promise.resolve({ data: undefined });
206 }
207 return axios
208 .get(`/rest/provider/v2/medicalGroup/${id}/providerSpecialties`, config)
209 .catch(() => ({ data: undefined }));
210}
211
212export function getAllGroupsInNetwork(
213 coverageType: PlanCoverageType
214): AxiosPromise<{ id: ProviderId; name: PlaceName }[]> {
215 const config = {
216 params: {
217 networks: searchDelsys(coverageType)
218 },
219 paramsSerializer
220 };
221 return axios.get('/rest/provider/beta/medicalGroups', config);
222}
223
224export const providersForMedicalGroupSpecialtyId = async (
225 coverageType: PlanCoverageType,
226 medicalGroupId: ProviderId,
227 specialtyId: SpecialtyId,
228 searchRadius?: number
229): Promise<Partial<AxiosResponse<MedicalGroupPhysicianProfileEntry | undefined>>> => {
230 let config = {
231 params: {
232 delsysCode: searchDelsys(coverageType),
233 specialties: [specialtyId],
234 lat: undefined,
235 lon: undefined,
236 searchRadius: undefined
237 },
238 paramsSerializer
239 };
240 if (CS_FEATURE_ENABLE_MEDICAL_GROUP_SEARCH_RADIUS() && !isUndefined(searchRadius)) {
241 const location = await getLocation().catch(() => Promise.reject('No location found'));
242 const [lon, lat] = location.data.coords;
243
244 config = {
245 params: {
246 ...config.params,
247 lat,
248 lon,
249 searchRadius
250 },
251 paramsSerializer
252 };
253 }
254 if (!planDisplaysMedicalGroupDirectories()) {
255 return Promise.resolve({ data: undefined });
256 }
257 return axios
258 .get(`/rest/provider/v1/medicalGroup/${medicalGroupId}/profile`, config)
259 .catch(() => ({ data: undefined }));
260};
261
262export const getDatasetLastIndexTime = (): Promise<{ [key in PlanCoverageType]?: Date }> => {
263 const config: AxiosRequestConfig = {
264 params: {
265 partnerId: partnerWithoutFallback(),
266 coverageType: coverages()
267 },
268 paramsSerializer
269 };
270 if (!config.params.partnerId) {
271 return Promise.reject('partner undefined');
272 }
273 return providerAxiosCache
274 .get<MultiCoverageLastIndexResult>('/rest/provider/v2/lastIndexed', config)
275 .then(resp => mapObject(resp.data.lastIndexed, val => new Date(val)));
276};
277
278export const getRecommendedPcp = async (coverageType: PlanCoverageType): Promise<AxiosResponse<PersonResult>> => {
279 const partnerId = partnerWithoutFallback();
280 const location = await getLocation().catch(() => Promise.reject('No location found'));
281 const coords = location.data.coords;
282 const long = coords[0];
283 const lat = coords[1];
284
285 let params = {
286 center: lat && long ? [long, lat].toString() : undefined
287 };
288
289 if (Array.isArray(coverageType)) {
290 coverageType.forEach(coverage => {
291 params[`networks.${coverage}`] = searchDelsys(coverage, false);
292 });
293 } else {
294 params[`networks.${coverageType}`] = searchDelsys(PlanCoverageType[coverageType], false);
295 }
296
297 const config: AxiosRequestConfig = {
298 params,
299 paramsSerializer
300 };
301
302 return providerAxiosCache.get<PersonResult>(`/rest/provider/v1/partners/${partnerId}/recommendation/pcp`, config);
303};
304
305export const getMultipleProvidersByLocation = (
306 locations: ProviderLocationId[],
307 coverageTypes: PlanCoverageType[],
308 accountPolicyNumber?: string,
309 planVariation?: string,
310 planTierClusterKey?: string
311): AxiosPromise<Provider[]> => {
312 const networks: string[] = flatten(coverageTypes.map(coverage => networkIds(coverage)));
313 const config: AxiosRequestConfig = {
314 params: {
315 partnerId: partnerWithoutFallback(),
316 networkIds: networks,
317 coverageType: coverageTypes,
318 accountPolicyNumber: accountPolicyNumber,
319 planVariation: planVariation,
320 planTierClusterKey: planTierClusterKey
321 },
322 paramsSerializer
323 };
324 return providerAxiosCache.post<Provider[], ProviderLocationId[]>(
325 '/rest/provider/v2/providers/byLocation',
326 locations,
327 config
328 );
329};
330
331export const makeProviderLocationIds = (careteamProviders: CareteamProvider[]): ProviderLocationId[] => {
332 return careteamProviders.map(provider => {
333 return { uniqueId: provider.providerUniqueId, locationId: provider.locationId };
334 });
335};
336
337export const getBestMatches = (params: BestMatchRequestParameters): Promise<BestMatchResponse> => {
338 if (!params) {
339 return Promise.resolve({ providers: [], isFromHealthAtScale: false });
340 }
341 const queryParamsAsString = paramsSerializer(params.queryParams);
342 return providerAxiosCache
343 .post<BestMatchResponse, BestMatchBodyParams>(
344 `/rest/provider/v1/search/bestMatch?${queryParamsAsString}`,
345 params.bodyParams
346 )
347 .then(
348 axiosResponse => {
349 return axiosResponse.data;
350 },
351 () => {
352 return { providers: [], isFromHealthAtScale: false };
353 }
354 );
355};
356
357export const getTranslatedContent = (itemType: LocalizedContentItem): Promise<ContentJson> =>
358 providerAxiosCache.get<ContentJson>(`/rest/provider/v1/translatedContent/${itemType}`);