242 lines
7.7 KiB
TypeScript
242 lines
7.7 KiB
TypeScript
import axios from 'axios';
|
|
import { XMLParser } from 'fast-xml-parser';
|
|
import fs from 'fs';
|
|
|
|
import { toArray } from '@kit/shared/utils';
|
|
|
|
import {
|
|
createAnalysis,
|
|
createNoDataReceivedEntry,
|
|
createNoNewDataReceivedEntry,
|
|
createSyncFailEntry,
|
|
createSyncSuccessEntry,
|
|
getAnalyses,
|
|
} from '~/lib/services/analyses.service';
|
|
import {
|
|
AnalysisElement,
|
|
createAnalysisElement,
|
|
getAnalysisElements,
|
|
} from '~/lib/services/analysis-element.service';
|
|
import {
|
|
createAnalysisGroup,
|
|
getAnalysisGroups,
|
|
} from '~/lib/services/analysis-group.service';
|
|
import { createCodes } from '~/lib/services/codes.service';
|
|
import { IMedipostPublicMessageDataParsed } from '~/lib/services/medipost/medipost.types';
|
|
import { getLatestPublicMessageListItem } from '~/lib/services/medipost/medipostPublicMessage.service';
|
|
import { getLastCheckedDate } from '~/lib/services/sync-entries.service';
|
|
import type { ICode } from '~/lib/types/code';
|
|
|
|
const WRITE_XML_TO_FILE = false as boolean;
|
|
|
|
export default async function syncAnalysisGroups() {
|
|
const baseUrl = process.env.MEDIPOST_URL;
|
|
const user = process.env.MEDIPOST_USER;
|
|
const password = process.env.MEDIPOST_PASSWORD;
|
|
const sender = process.env.MEDIPOST_MESSAGE_SENDER;
|
|
|
|
if (!baseUrl || !user || !password || !sender) {
|
|
throw new Error('Could not access all necessary environment variables');
|
|
}
|
|
|
|
try {
|
|
console.info('Getting latest public message id');
|
|
// const lastCheckedDate = await getLastCheckedDate(); never used?
|
|
|
|
const latestMessage = await getLatestPublicMessageListItem();
|
|
if (!latestMessage) {
|
|
console.info('No new data received');
|
|
await createNoNewDataReceivedEntry();
|
|
return;
|
|
}
|
|
console.info('Getting public message with id: ', latestMessage.messageId);
|
|
|
|
const { data: publicMessageData } = await axios.get(baseUrl, {
|
|
params: {
|
|
Action: 'GetPublicMessage',
|
|
User: user,
|
|
Password: password,
|
|
MessageId: latestMessage.messageId,
|
|
},
|
|
headers: {
|
|
Accept: 'application/xml',
|
|
},
|
|
});
|
|
|
|
if (WRITE_XML_TO_FILE) {
|
|
fs.writeFileSync('public-messages-list-response.xml', publicMessageData);
|
|
}
|
|
|
|
const parser = new XMLParser({ ignoreAttributes: false });
|
|
const parsed: IMedipostPublicMessageDataParsed =
|
|
parser.parse(publicMessageData);
|
|
|
|
if (parsed.ANSWER?.CODE && parsed.ANSWER?.CODE !== 0) {
|
|
throw new Error(
|
|
`Failed to get public message (id: ${latestMessage.messageId})`,
|
|
);
|
|
}
|
|
|
|
const existingAnalysisGroups = await getAnalysisGroups();
|
|
|
|
// SAVE PUBLIC MESSAGE DATA
|
|
|
|
const providers = toArray(parsed?.Saadetis?.Teenused.Teostaja);
|
|
const analysisGroups = providers.flatMap((provider) =>
|
|
toArray(provider.UuringuGrupp),
|
|
);
|
|
|
|
if (!parsed || !analysisGroups.length) {
|
|
console.info('No analysis groups data received');
|
|
await createNoDataReceivedEntry();
|
|
return;
|
|
}
|
|
|
|
const codes: ICode[] = [];
|
|
for (const analysisGroup of analysisGroups) {
|
|
const existingAnalysisGroup = existingAnalysisGroups?.find(
|
|
({ original_id }) => original_id === analysisGroup.UuringuGruppId,
|
|
);
|
|
let groupExistingAnalysisElements: AnalysisElement[] = [];
|
|
let analysisGroupId: number;
|
|
if (existingAnalysisGroup) {
|
|
console.info(
|
|
`Analysis group '${analysisGroup.UuringuGruppNimi}' already exists, only creating new analysis elements`,
|
|
);
|
|
groupExistingAnalysisElements = await getAnalysisElements({
|
|
analysisGroupId: existingAnalysisGroup.id,
|
|
});
|
|
analysisGroupId = existingAnalysisGroup.id;
|
|
} else {
|
|
analysisGroupId = await createAnalysisGroup({
|
|
id: analysisGroup.UuringuGruppId,
|
|
name: analysisGroup.UuringuGruppNimi,
|
|
order: analysisGroup.UuringuGruppJarjekord,
|
|
});
|
|
|
|
const analysisGroupCodes = toArray(analysisGroup.Kood);
|
|
codes.push(
|
|
...analysisGroupCodes.map((kood) => ({
|
|
hk_code: kood.HkKood,
|
|
hk_code_multiplier: kood.HkKoodiKordaja,
|
|
coefficient: kood.Koefitsient,
|
|
price: kood.Hind,
|
|
analysis_group_id: analysisGroupId,
|
|
analysis_element_id: null,
|
|
analysis_id: null,
|
|
})),
|
|
);
|
|
}
|
|
|
|
const analysisGroupItems = toArray(analysisGroup.Uuring);
|
|
|
|
for (const item of analysisGroupItems) {
|
|
const analysisElement = item.UuringuElement!;
|
|
const isExistingAnalysisElement = groupExistingAnalysisElements.find(
|
|
({ analysis_id_original }) =>
|
|
analysis_id_original === analysisElement.UuringId,
|
|
);
|
|
if (isExistingAnalysisElement) {
|
|
console.info(
|
|
`Analysis element '${analysisElement.UuringNimi}' already exists`,
|
|
);
|
|
continue;
|
|
}
|
|
|
|
const insertedAnalysisElementId = await createAnalysisElement({
|
|
analysisElement: analysisElement!,
|
|
analysisGroupId,
|
|
materialGroups: toArray(item.MaterjalideGrupp),
|
|
});
|
|
|
|
if (Array.isArray(analysisElement.UuringuElement)) {
|
|
for (const nestedAnalysisElement of analysisElement.UuringuElement) {
|
|
await createAnalysisElement({
|
|
analysisElement: nestedAnalysisElement,
|
|
analysisGroupId,
|
|
materialGroups: toArray(item.MaterjalideGrupp),
|
|
});
|
|
}
|
|
}
|
|
|
|
if (analysisElement.Kood) {
|
|
const analysisElementCodes = toArray(analysisElement.Kood);
|
|
codes.push(
|
|
...analysisElementCodes.map((kood) => ({
|
|
hk_code: kood.HkKood,
|
|
hk_code_multiplier: kood.HkKoodiKordaja,
|
|
coefficient: kood.Koefitsient,
|
|
price: kood.Hind,
|
|
analysis_group_id: null,
|
|
analysis_element_id: insertedAnalysisElementId,
|
|
analysis_id: null,
|
|
})),
|
|
);
|
|
}
|
|
|
|
const analyses = analysisElement.UuringuElement;
|
|
if (analyses?.length) {
|
|
const existingAnalyses = await getAnalyses({
|
|
originalIds: analyses.map(({ UuringId }) => UuringId),
|
|
});
|
|
|
|
for (const analysis of analyses) {
|
|
const isExistingAnalysis = existingAnalyses.find(
|
|
({ analysis_id_original }) =>
|
|
analysis_id_original === analysis.UuringId,
|
|
);
|
|
if (isExistingAnalysis) {
|
|
console.info(`Analysis '${analysis.UuringNimi}' already exists`);
|
|
continue;
|
|
}
|
|
|
|
const insertedAnalysisId = await createAnalysis(
|
|
analysis,
|
|
analysisGroupId,
|
|
);
|
|
|
|
if (analysis.Kood) {
|
|
const analysisCodes = toArray(analysis.Kood);
|
|
|
|
codes.push(
|
|
...analysisCodes.map((kood) => ({
|
|
hk_code: kood.HkKood,
|
|
hk_code_multiplier: kood.HkKoodiKordaja,
|
|
coefficient: kood.Koefitsient,
|
|
price: kood.Hind,
|
|
analysis_group_id: null,
|
|
analysis_element_id: null,
|
|
analysis_id: insertedAnalysisId,
|
|
})),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
console.info('Inserting codes');
|
|
await createCodes(codes);
|
|
|
|
console.info('Inserting sync entry');
|
|
await createSyncSuccessEntry();
|
|
} catch (e) {
|
|
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
await createSyncFailEntry(
|
|
JSON.stringify(
|
|
{
|
|
message: errorMessage,
|
|
stack: e instanceof Error ? e.stack : undefined,
|
|
name: e instanceof Error ? e.name : 'Unknown',
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
);
|
|
console.error('Sync failed:', e);
|
|
throw new Error(
|
|
`Failed to sync public message data, error: ${errorMessage}`,
|
|
);
|
|
}
|
|
}
|