192 lines
6.6 KiB
TypeScript
192 lines
6.6 KiB
TypeScript
'use server';
|
||
|
||
import {
|
||
getClientInstitution,
|
||
getClientPerson,
|
||
getOrderEnteredPerson,
|
||
getPais,
|
||
getPatient,
|
||
getProviderInstitution,
|
||
} from '@/lib/templates/medipost-order';
|
||
import {
|
||
MedipostAction,
|
||
} from '@/lib/types/medipost';
|
||
import axios from 'axios';
|
||
import { uniqBy } from 'lodash';
|
||
|
||
import { Tables } from '@kit/supabase/database';
|
||
import { formatDate } from 'date-fns';
|
||
import { getAnalyses } from './analyses.service';
|
||
import { getAnalysisElementsAdmin } from './analysis-element.service';
|
||
import { validateMedipostResponse } from './medipost.service';
|
||
|
||
const BASE_URL = process.env.MEDIPOST_URL!;
|
||
const USER = process.env.MEDIPOST_USER!;
|
||
const PASSWORD = process.env.MEDIPOST_PASSWORD!;
|
||
const RECIPIENT = process.env.MEDIPOST_RECIPIENT!;
|
||
|
||
export async function sendPrivateMessageTestResponse({
|
||
messageXml,
|
||
}: {
|
||
messageXml: string;
|
||
}) {
|
||
const body = new FormData();
|
||
body.append('Action', MedipostAction.SendPrivateMessage);
|
||
body.append('User', USER);
|
||
body.append('Password', PASSWORD);
|
||
body.append('Receiver', RECIPIENT);
|
||
body.append('MessageType', 'Vastus');
|
||
body.append(
|
||
'Message',
|
||
new Blob([messageXml], {
|
||
type: 'text/xml; charset=UTF-8',
|
||
}),
|
||
);
|
||
|
||
const { data } = await axios.post(BASE_URL, body);
|
||
await validateMedipostResponse(data);
|
||
}
|
||
|
||
function getRandomInt(min: number, max: number) {
|
||
min = Math.ceil(min);
|
||
max = Math.floor(max);
|
||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||
}
|
||
|
||
export async function composeOrderTestResponseXML({
|
||
person,
|
||
orderedAnalysisElementsIds,
|
||
orderedAnalysesIds,
|
||
orderId,
|
||
orderCreatedAt,
|
||
}: {
|
||
person: {
|
||
idCode: string;
|
||
firstName: string;
|
||
lastName: string;
|
||
phone: string;
|
||
};
|
||
orderedAnalysisElementsIds: number[];
|
||
orderedAnalysesIds: number[];
|
||
orderId: string;
|
||
orderCreatedAt: Date;
|
||
}) {
|
||
const analysisElements = await getAnalysisElementsAdmin({ ids: orderedAnalysisElementsIds });
|
||
const analyses = await getAnalyses({ ids: orderedAnalysesIds });
|
||
|
||
const analysisGroups: Tables<{ schema: 'medreport' }, 'analysis_groups'>[] =
|
||
uniqBy(
|
||
(
|
||
analysisElements?.flatMap(({ analysis_groups }) => analysis_groups) ??
|
||
[]
|
||
).concat(
|
||
analyses?.flatMap(
|
||
({ analysis_elements }) => analysis_elements.analysis_groups,
|
||
) ?? [],
|
||
),
|
||
'id',
|
||
);
|
||
|
||
// Tellimuse olek:
|
||
// 1 – Järjekorras, 2 – Ootel, 3 - Töös, 4 – Lõpetatud,
|
||
// 5 – Tagasi lükatud, 6 – Tühistatud.
|
||
const orderStatus = 4;
|
||
const orderNumber = orderId;
|
||
|
||
const allAnalysisElementsForGroups = analysisElements?.filter((element) => {
|
||
return analysisGroups.some((group) => group.id === element.analysis_groups.id);
|
||
});
|
||
const addedIds = new Set<number>();
|
||
|
||
return `<?xml version="1.0" encoding="UTF-8"?>
|
||
<Saadetis xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="TellimusLOINC.xsd">
|
||
${getPais(USER, RECIPIENT, orderId, "AL")}
|
||
<Vastus>
|
||
<ValisTellimuseId>${orderId}</ValisTellimuseId>
|
||
${getClientInstitution({ index: 1 })}
|
||
${getProviderInstitution({ index: 1 })}
|
||
${getClientPerson()}
|
||
${getOrderEnteredPerson()}
|
||
<TellijaMarkused>Siia tuleb tellija poolne märkus</TellijaMarkused>
|
||
|
||
${getPatient(person)}
|
||
|
||
<Proov>
|
||
<ProovinouIdOID>1.3.6.1.4.1.28284.1.625.2.17</ProovinouIdOID>
|
||
<ProovinouId>16522314</ProovinouId>
|
||
<MaterjaliTyypOID>1.3.6.1.4.1.28284.6.2.1.244.8</MaterjaliTyypOID>
|
||
<MaterjaliTyyp>119297000</MaterjaliTyyp>
|
||
<MaterjaliNimi>Veri</MaterjaliNimi>
|
||
<Ribakood>16522314</Ribakood>
|
||
<Jarjenumber>1</Jarjenumber>
|
||
<VotmisAeg>2022-08-19 08:53:00</VotmisAeg>
|
||
<SaabumisAeg>2022-08-23 15:10:00</SaabumisAeg>
|
||
</Proov>
|
||
|
||
<TellimuseNumber>${orderNumber}</TellimuseNumber>
|
||
|
||
<TellimuseOlek>${orderStatus}</TellimuseOlek>
|
||
${allAnalysisElementsForGroups.map((analysisElement) => {
|
||
const group = analysisGroups.find((group) => group.id === analysisElement.analysis_groups.id);
|
||
if (!group) {
|
||
throw new Error(`Failed to find group for analysis element ${analysisElement.id}`);
|
||
}
|
||
|
||
let relatedAnalysisElement = analysisElements?.find(
|
||
(element) => element.analysis_groups.id === group.id && !addedIds.has(element.id),
|
||
);
|
||
const relatedAnalyses = analyses?.filter((analysis) => {
|
||
return analysis.analysis_elements.analysis_groups.id === group.id && !addedIds.has(analysis.analysis_elements.id);
|
||
});
|
||
|
||
if (!relatedAnalysisElement) {
|
||
relatedAnalysisElement = relatedAnalyses?.find(
|
||
(relatedAnalysis) =>
|
||
relatedAnalysis.analysis_elements.analysis_groups.id ===
|
||
group.id,
|
||
)?.analysis_elements;
|
||
}
|
||
|
||
if (!relatedAnalysisElement || !relatedAnalysisElement.material_groups) {
|
||
throw new Error(
|
||
`Failed to find related analysis element for group ${group.name} (id: ${group.id})`,
|
||
);
|
||
}
|
||
|
||
const lower = getRandomInt(0, 100);
|
||
const upper = getRandomInt(lower + 1, 500);
|
||
const result = getRandomInt(lower - Math.floor(lower * 0.1), upper + Math.floor(upper * 0.1));
|
||
addedIds.add(relatedAnalysisElement.id);
|
||
return (`
|
||
<UuringuGrupp>
|
||
<UuringuGruppId>${group.original_id}</UuringuGruppId>
|
||
<UuringuGruppNimi>${group.name}</UuringuGruppNimi>
|
||
<Uuring>
|
||
<UuringuElement>
|
||
<UuringIdOID>${relatedAnalysisElement.analysis_id_oid}</UuringIdOID>
|
||
<UuringId>${relatedAnalysisElement.analysis_id_original}</UuringId>
|
||
<TLyhend>${relatedAnalysisElement.tehik_short_loinc}</TLyhend>
|
||
<KNimetus>${relatedAnalysisElement.tehik_loinc_name}</KNimetus>
|
||
<UuringNimi>${relatedAnalysisElement.analysis_name_lab ?? relatedAnalysisElement.tehik_loinc_name}</UuringNimi>
|
||
<TellijaUuringId>${relatedAnalysisElement.id}</TellijaUuringId>
|
||
<TeostajaUuringId>${relatedAnalysisElement.id}</TeostajaUuringId>
|
||
<UuringOlek>4</UuringOlek>
|
||
<Mootyhik>%</Mootyhik>
|
||
<UuringuVastus>
|
||
<VastuseVaartus>${result}</VastuseVaartus>
|
||
<VastuseAeg>${formatDate(new Date(), 'yyyy-MM-dd HH:mm:ss')}</VastuseAeg>
|
||
<NormYlem kaasaarvatud=\"EI\">${upper}</NormYlem>
|
||
<NormAlum kaasaarvatud=\"EI\">${lower}</NormAlum>
|
||
<NormiStaatus>${result < lower ? 1 : (result > upper ? 1 : 0)}</NormiStaatus>
|
||
<ProoviJarjenumber>1</ProoviJarjenumber>
|
||
</UuringuVastus>
|
||
</UuringuElement>
|
||
<UuringuTaitjaAsutuseJnr>2</UuringuTaitjaAsutuseJnr>
|
||
</Uuring>
|
||
</UuringuGrupp>
|
||
`);
|
||
}).join('')}
|
||
</Vastus>
|
||
</Saadetis>`;
|
||
}
|