001/*-
002 * #%L
003 * Smile CDR - CDR
004 * %%
005 * Copyright (C) 2016 - 2024 Smile CDR, Inc.
006 * %%
007 * All rights reserved.
008 * #L%
009 */
010package ca.cdr.api.pub.hl7v2.common.abstraction;
011
012import ca.uhn.hl7v2.HL7Exception;
013import ca.uhn.hl7v2.model.AbstractMessage;
014import ca.uhn.hl7v2.model.Group;
015import ca.uhn.hl7v2.model.v25.group.ADT_A01_INSURANCE;
016import ca.uhn.hl7v2.model.v25.group.ADT_A01_PROCEDURE;
017import ca.uhn.hl7v2.model.v25.group.ADT_A03_INSURANCE;
018import ca.uhn.hl7v2.model.v25.group.ADT_A03_PROCEDURE;
019import ca.uhn.hl7v2.model.v25.group.ADT_A05_INSURANCE;
020import ca.uhn.hl7v2.model.v25.group.ADT_A05_PROCEDURE;
021import ca.uhn.hl7v2.model.v25.group.ADT_A06_INSURANCE;
022import ca.uhn.hl7v2.model.v25.group.ADT_A06_PROCEDURE;
023import ca.uhn.hl7v2.model.v25.group.BAR_P12_PROCEDURE;
024import ca.uhn.hl7v2.model.v25.group.DFT_P03_INSURANCE;
025import ca.uhn.hl7v2.model.v25.group.OMG_O19_INSURANCE;
026import ca.uhn.hl7v2.model.v25.group.OMG_O19_ORDER;
027import ca.uhn.hl7v2.model.v25.group.ORM_O01_INSURANCE;
028import ca.uhn.hl7v2.model.v25.group.ORM_O01_ORDER;
029import ca.uhn.hl7v2.model.v25.message.ADT_A01;
030import ca.uhn.hl7v2.model.v25.message.ADT_A02;
031import ca.uhn.hl7v2.model.v25.message.ADT_A03;
032import ca.uhn.hl7v2.model.v25.message.ADT_A05;
033import ca.uhn.hl7v2.model.v25.message.ADT_A06;
034import ca.uhn.hl7v2.model.v25.message.ADT_A09;
035import ca.uhn.hl7v2.model.v25.message.ADT_A12;
036import ca.uhn.hl7v2.model.v25.message.ADT_A15;
037import ca.uhn.hl7v2.model.v25.message.ADT_A17;
038import ca.uhn.hl7v2.model.v25.message.ADT_A21;
039import ca.uhn.hl7v2.model.v25.message.ADT_A24;
040import ca.uhn.hl7v2.model.v25.message.ADT_A30;
041import ca.uhn.hl7v2.model.v25.message.ADT_A38;
042import ca.uhn.hl7v2.model.v25.message.ADT_A39;
043import ca.uhn.hl7v2.model.v25.message.BAR_P12;
044import ca.uhn.hl7v2.model.v25.message.DFT_P03;
045import ca.uhn.hl7v2.model.v25.message.OMG_O19;
046import ca.uhn.hl7v2.model.v25.message.ORM_O01;
047import ca.uhn.hl7v2.model.v25.message.ORU_R01;
048import ca.uhn.hl7v2.model.v25.message.RAS_O17;
049import ca.uhn.hl7v2.model.v25.message.RDE_O11;
050import ca.uhn.hl7v2.model.v25.message.VXU_V04;
051import ca.uhn.hl7v2.model.v25.segment.DG1;
052import ca.uhn.hl7v2.model.v25.segment.IN1;
053import ca.uhn.hl7v2.model.v25.segment.IN2;
054import ca.uhn.hl7v2.model.v25.segment.PR1;
055import ca.uhn.hl7v2.model.v25.segment.PV1;
056import ca.uhn.hl7v2.model.v25.segment.PV2;
057
058import java.util.ArrayList;
059import java.util.List;
060import java.util.function.Function;
061import java.util.stream.Collectors;
062
063/**
064 * Wraps the relevant portion of an HL7 V2 message to an {@link IVisitMessage}
065 */
066public class VisitMessageFactory {
067
068        public IVisitMessage asVisitMessage(AbstractMessage theMsg) throws HL7Exception {
069                if (theMsg instanceof ADT_A01) {
070                        return asVisitMessage((ADT_A01) theMsg);
071                } else if (theMsg instanceof ADT_A02) {
072                        return asVisitMessage((ADT_A02) theMsg);
073                } else if (theMsg instanceof ADT_A03) {
074                        return asVisitMessage((ADT_A03) theMsg);
075                } else if (theMsg instanceof ADT_A05) {
076                        return asVisitMessage((ADT_A05) theMsg);
077                } else if (theMsg instanceof ADT_A06) {
078                        return asVisitMessage((ADT_A06) theMsg);
079                } else if (theMsg instanceof ADT_A09) {
080                        return asVisitMessage((ADT_A09) theMsg);
081                } else if (theMsg instanceof ADT_A12) {
082                        return asVisitMessage((ADT_A12) theMsg);
083                } else if (theMsg instanceof ADT_A15) {
084                        return asVisitMessage((ADT_A15) theMsg);
085                } else if (theMsg instanceof ADT_A17) {
086                        return asVisitMessage((ADT_A17) theMsg);
087                } else if (theMsg instanceof ADT_A21) {
088                        return asVisitMessage((ADT_A21) theMsg);
089                } else if (theMsg instanceof ADT_A24) {
090                        return asVisitMessage((ADT_A24) theMsg);
091                } else if (theMsg instanceof ADT_A30) {
092                        return asVisitMessage((ADT_A30) theMsg);
093                } else if (theMsg instanceof ADT_A38) {
094                        return asVisitMessage((ADT_A38) theMsg);
095                } else if (theMsg instanceof ADT_A39) {
096                        return asVisitMessage((ADT_A39) theMsg);
097                } else if (theMsg instanceof DFT_P03) {
098                        return asVisitMessage((DFT_P03) theMsg);
099                } else if (theMsg instanceof OMG_O19) {
100                        return asVisitMessage((OMG_O19) theMsg);
101                } else if (theMsg instanceof ORM_O01) {
102                        return asVisitMessage((ORM_O01) theMsg);
103                } else if (theMsg instanceof ORU_R01) {
104                        return asVisitMessage((ORU_R01) theMsg);
105                } else if (theMsg instanceof RAS_O17) {
106                        return asVisitMessage((RAS_O17) theMsg);
107                } else if (theMsg instanceof RDE_O11) {
108                        return asVisitMessage((RDE_O11) theMsg);
109                } else if (theMsg instanceof VXU_V04) {
110                        return asVisitMessage((VXU_V04) theMsg);
111                } else if (theMsg instanceof BAR_P12) {
112                        return asVisitMessage((BAR_P12) theMsg);
113                } else {
114                        return null;
115                }
116        }
117
118        private VisitMessage getDefaultVisitMessageAndSetPV1PV2(PV1 thePv1, PV2 thePv2) {
119                return new VisitMessage()
120                                .setPV1(thePv1)
121                                .setPV2(thePv2)
122                                .setDG1(null, null)
123                                .setROL(null, null)
124                                .setGT1(null)
125                                .setOBX(null);
126        }
127
128        private <T> List<IVisitMessage.IVisitMessageInsurance> getInsurances(
129                        List<T> theInsurances, Function<T, IN1> theIn1Function, Function<T, IN2> theIn2Function) {
130                return theInsurances.stream()
131                                .map(t -> new VisitMessageInsurance<>(t, theIn1Function, theIn2Function))
132                                .collect(Collectors.toList());
133        }
134
135        private <T> List<IVisitMessage.IVisitMessageProcedure> getProcedures(
136                        List<T> theProcedures, Function<T, PR1> thePr1Function) {
137                return theProcedures.stream()
138                                .map(t -> new VisitMessageProcedure((Group) t, thePr1Function))
139                                .collect(Collectors.toList());
140        }
141
142        private IVisitMessage asVisitMessage(ADT_A39 theMsg) {
143                return getDefaultVisitMessageAndSetPV1PV2(theMsg.getPATIENT().getPV1(), null);
144        }
145
146        private IVisitMessage asVisitMessage(ADT_A15 theMsg) {
147                return getDefaultVisitMessageAndSetPV1PV2(theMsg.getPV1(), theMsg.getPV2());
148        }
149
150        private IVisitMessage asVisitMessage(DFT_P03 theMsg) throws HL7Exception {
151                VisitMessage visitMessage = getDefaultVisitMessageAndSetPV1PV2(theMsg.getPV1(), theMsg.getPV2())
152                                .setDG1(theMsg.getDG1All(), () -> theMsg.insertDG1(theMsg.getDG1Reps()))
153                                .setGT1(theMsg.getGT1All());
154
155                List<IVisitMessage.IVisitMessageInsurance> insurances =
156                                getInsurances(theMsg.getINSURANCEAll(), DFT_P03_INSURANCE::getIN1, DFT_P03_INSURANCE::getIN2);
157                visitMessage.setInsurances(
158                                insurances,
159                                () -> new VisitMessageInsurance<>(
160                                                theMsg.insertINSURANCE(theMsg.getINSURANCEReps()),
161                                                DFT_P03_INSURANCE::getIN1,
162                                                DFT_P03_INSURANCE::getIN2));
163                return visitMessage;
164        }
165
166        private IVisitMessage asVisitMessage(ORU_R01 theMsg) {
167                return getDefaultVisitMessageAndSetPV1PV2(
168                                theMsg.getPATIENT_RESULT().getPATIENT().getVISIT().getPV1(),
169                                theMsg.getPATIENT_RESULT().getPATIENT().getVISIT().getPV2());
170        }
171
172        private IVisitMessage asVisitMessage(RAS_O17 theMsg) {
173                return getDefaultVisitMessageAndSetPV1PV2(
174                                theMsg.getPATIENT().getPATIENT_VISIT().getPV1(),
175                                theMsg.getPATIENT().getPATIENT_VISIT().getPV2());
176        }
177
178        private IVisitMessage asVisitMessage(RDE_O11 theMsg) {
179                return getDefaultVisitMessageAndSetPV1PV2(
180                                theMsg.getPATIENT().getPATIENT_VISIT().getPV1(),
181                                theMsg.getPATIENT().getPATIENT_VISIT().getPV2());
182        }
183
184        private IVisitMessage asVisitMessage(ADT_A01 theMsg) throws HL7Exception {
185                VisitMessage visitMessage = getDefaultVisitMessageAndSetPV1PV2(theMsg.getPV1(), theMsg.getPV2())
186                                .setDG1(theMsg.getDG1All(), () -> theMsg.insertDG1(theMsg.getDG1Reps()))
187                                .setROL(theMsg.getROL2All(), () -> theMsg.insertROL2(theMsg.getROL2Reps()))
188                                .setAL1(theMsg.getAL1All(), () -> theMsg.insertAL1(theMsg.getAL1Reps()))
189                                .setGT1(theMsg.getGT1All())
190                                .setOBX(theMsg.getOBXAll());
191
192                List<IVisitMessage.IVisitMessageProcedure> procedures =
193                                getProcedures(theMsg.getPROCEDUREAll(), ADT_A01_PROCEDURE::getPR1);
194                visitMessage.setProcedures(
195                                procedures,
196                                () -> new VisitMessageProcedure<>(
197                                                theMsg.insertPROCEDURE(theMsg.getPROCEDUREReps()), ADT_A01_PROCEDURE::getPR1));
198
199                List<IVisitMessage.IVisitMessageInsurance> insurances =
200                                getInsurances(theMsg.getINSURANCEAll(), ADT_A01_INSURANCE::getIN1, ADT_A01_INSURANCE::getIN2);
201                visitMessage.setInsurances(
202                                insurances,
203                                () -> new VisitMessageInsurance<>(
204                                                theMsg.insertINSURANCE(theMsg.getINSURANCEReps()),
205                                                ADT_A01_INSURANCE::getIN1,
206                                                ADT_A01_INSURANCE::getIN2));
207
208                return visitMessage;
209        }
210
211        private IVisitMessage asVisitMessage(ADT_A02 theMsg) throws HL7Exception {
212                return getDefaultVisitMessageAndSetPV1PV2(theMsg.getPV1(), theMsg.getPV2())
213                                .setROL(theMsg.getROL2All(), () -> theMsg.insertROL2(theMsg.getROL2Reps()))
214                                .setOBX(theMsg.getOBXAll());
215        }
216
217        private IVisitMessage asVisitMessage(ADT_A03 theMsg) throws HL7Exception {
218                VisitMessage visitMessage = getDefaultVisitMessageAndSetPV1PV2(theMsg.getPV1(), theMsg.getPV2())
219                                .setDG1(theMsg.getDG1All(), () -> theMsg.insertDG1(theMsg.getDG1Reps()))
220                                .setROL(theMsg.getROL2All(), () -> theMsg.insertROL2(theMsg.getROL2Reps()))
221                                .setAL1(theMsg.getAL1All(), () -> theMsg.insertAL1(theMsg.getAL1Reps()))
222                                .setGT1(theMsg.getGT1All())
223                                .setOBX(theMsg.getOBXAll());
224
225                List<IVisitMessage.IVisitMessageProcedure> procedures =
226                                getProcedures(theMsg.getPROCEDUREAll(), ADT_A03_PROCEDURE::getPR1);
227                visitMessage.setProcedures(
228                                procedures,
229                                () -> new VisitMessageProcedure<>(
230                                                theMsg.insertPROCEDURE(theMsg.getPROCEDUREReps()), ADT_A03_PROCEDURE::getPR1));
231
232                List<IVisitMessage.IVisitMessageInsurance> insurances =
233                                getInsurances(theMsg.getINSURANCEAll(), ADT_A03_INSURANCE::getIN1, ADT_A03_INSURANCE::getIN2);
234                visitMessage.setInsurances(
235                                insurances,
236                                () -> new VisitMessageInsurance<>(
237                                                theMsg.insertINSURANCE(theMsg.getINSURANCEReps()),
238                                                ADT_A03_INSURANCE::getIN1,
239                                                ADT_A03_INSURANCE::getIN2));
240
241                return visitMessage;
242        }
243
244        private IVisitMessage asVisitMessage(ADT_A05 theMsg) throws HL7Exception {
245                VisitMessage visitMessage = getDefaultVisitMessageAndSetPV1PV2(theMsg.getPV1(), theMsg.getPV2())
246                                .setDG1(theMsg.getDG1All(), () -> theMsg.insertDG1(theMsg.getDG1Reps()))
247                                .setROL(theMsg.getROL2All(), () -> theMsg.insertROL2(theMsg.getROL2Reps()))
248                                .setAL1(theMsg.getAL1All(), () -> theMsg.insertAL1(theMsg.getAL1Reps()))
249                                .setGT1(theMsg.getGT1All())
250                                .setOBX(theMsg.getOBXAll());
251
252                List<IVisitMessage.IVisitMessageProcedure> procedures =
253                                getProcedures(theMsg.getPROCEDUREAll(), ADT_A05_PROCEDURE::getPR1);
254                visitMessage.setProcedures(
255                                procedures,
256                                () -> new VisitMessageProcedure<>(
257                                                theMsg.insertPROCEDURE(theMsg.getPROCEDUREReps()), ADT_A05_PROCEDURE::getPR1));
258
259                List<IVisitMessage.IVisitMessageInsurance> insurances =
260                                getInsurances(theMsg.getINSURANCEAll(), ADT_A05_INSURANCE::getIN1, ADT_A05_INSURANCE::getIN2);
261                visitMessage.setInsurances(
262                                insurances,
263                                () -> new VisitMessageInsurance<>(
264                                                theMsg.insertINSURANCE(theMsg.getINSURANCEReps()),
265                                                ADT_A05_INSURANCE::getIN1,
266                                                ADT_A05_INSURANCE::getIN2));
267
268                return visitMessage;
269        }
270
271        private IVisitMessage asVisitMessage(ADT_A06 theMsg) throws HL7Exception {
272                VisitMessage visitMessage = getDefaultVisitMessageAndSetPV1PV2(theMsg.getPV1(), theMsg.getPV2())
273                                .setDG1(theMsg.getDG1All(), () -> theMsg.insertDG1(theMsg.getDG1Reps()))
274                                .setROL(theMsg.getROL2All(), () -> theMsg.insertROL2(theMsg.getROL2Reps()))
275                                .setAL1(theMsg.getAL1All(), () -> theMsg.insertAL1(theMsg.getAL1Reps()))
276                                .setGT1(theMsg.getGT1All())
277                                .setOBX(theMsg.getOBXAll());
278
279                List<IVisitMessage.IVisitMessageProcedure> procedures =
280                                getProcedures(theMsg.getPROCEDUREAll(), ADT_A06_PROCEDURE::getPR1);
281                visitMessage.setProcedures(
282                                procedures,
283                                () -> new VisitMessageProcedure<>(
284                                                theMsg.insertPROCEDURE(theMsg.getPROCEDUREReps()), ADT_A06_PROCEDURE::getPR1));
285
286                List<IVisitMessage.IVisitMessageInsurance> insurances =
287                                getInsurances(theMsg.getINSURANCEAll(), ADT_A06_INSURANCE::getIN1, ADT_A06_INSURANCE::getIN2);
288                visitMessage.setInsurances(
289                                insurances,
290                                () -> new VisitMessageInsurance<>(
291                                                theMsg.insertINSURANCE(theMsg.getINSURANCEReps()),
292                                                ADT_A06_INSURANCE::getIN1,
293                                                ADT_A06_INSURANCE::getIN2));
294                return visitMessage;
295        }
296
297        private IVisitMessage asVisitMessage(ADT_A09 theMsg) throws HL7Exception {
298                return getDefaultVisitMessageAndSetPV1PV2(theMsg.getPV1(), theMsg.getPV2())
299                                .setDG1(theMsg.getDG1All(), () -> theMsg.insertDG1(theMsg.getDG1Reps()))
300                                .setOBX(theMsg.getOBXAll());
301        }
302
303        private IVisitMessage asVisitMessage(ADT_A12 theMsg) throws HL7Exception {
304                return getDefaultVisitMessageAndSetPV1PV2(theMsg.getPV1(), theMsg.getPV2())
305                                .setOBX(theMsg.getOBXAll());
306        }
307
308        private IVisitMessage asVisitMessage(ADT_A17 theMsg) throws HL7Exception {
309                return getDefaultVisitMessageAndSetPV1PV2(theMsg.getPV1(), theMsg.getPV2())
310                                .setOBX(theMsg.getOBXAll());
311        }
312
313        private IVisitMessage asVisitMessage(ADT_A21 theMsg) throws HL7Exception {
314                return getDefaultVisitMessageAndSetPV1PV2(theMsg.getPV1(), theMsg.getPV2())
315                                .setOBX(theMsg.getOBXAll());
316        }
317
318        private IVisitMessage asVisitMessage(ADT_A38 theMsg) throws HL7Exception {
319                return getDefaultVisitMessageAndSetPV1PV2(theMsg.getPV1(), theMsg.getPV2())
320                                .setDG1(theMsg.getDG1All(), () -> theMsg.insertDG1(theMsg.getDG1Reps()))
321                                .setOBX(theMsg.getOBXAll());
322        }
323
324        @SuppressWarnings("unused")
325        private IVisitMessage asVisitMessage(ADT_A30 theMsg) {
326                return getDefaultVisitMessageAndSetPV1PV2(null, null);
327        }
328
329        private IVisitMessage asVisitMessage(ADT_A24 theMsg) {
330                return getDefaultVisitMessageAndSetPV1PV2(theMsg.getPV1(), null);
331        }
332
333        private IVisitMessage asVisitMessage(VXU_V04 theMsg) {
334                return getDefaultVisitMessageAndSetPV1PV2(theMsg.getPATIENT().getPV1(), null);
335        }
336
337        private IVisitMessage asVisitMessage(ORM_O01 theMsg) throws HL7Exception {
338                List<DG1> dg1List = new ArrayList<>();
339                for (ORM_O01_ORDER nextOrder : theMsg.getORDERAll()) {
340                        dg1List.addAll(nextOrder.getORDER_DETAIL().getDG1All());
341                }
342
343                VisitMessage visitMessage = getDefaultVisitMessageAndSetPV1PV2(
344                                                theMsg.getPATIENT().getPATIENT_VISIT().getPV1(),
345                                                theMsg.getPATIENT().getPATIENT_VISIT().getPV2())
346                                .setDG1(dg1List, null);
347
348                List<IVisitMessage.IVisitMessageInsurance> insurances = getInsurances(
349                                theMsg.getPATIENT().getINSURANCEAll(), ORM_O01_INSURANCE::getIN1, ORM_O01_INSURANCE::getIN2);
350                visitMessage.setInsurances(
351                                insurances,
352                                () -> new VisitMessageInsurance<>(
353                                                theMsg.getPATIENT().insertINSURANCE(theMsg.getPATIENT().getINSURANCEReps()),
354                                                ORM_O01_INSURANCE::getIN1,
355                                                ORM_O01_INSURANCE::getIN2));
356
357                return visitMessage;
358        }
359
360        private IVisitMessage asVisitMessage(OMG_O19 theMsg) throws HL7Exception {
361                List<DG1> dg1List = new ArrayList<>();
362                for (OMG_O19_ORDER nextOrder : theMsg.getORDERAll()) {
363                        dg1List.addAll(nextOrder.getDG1All());
364                }
365
366                VisitMessage visitMessage = getDefaultVisitMessageAndSetPV1PV2(
367                                                theMsg.getPATIENT().getPATIENT_VISIT().getPV1(),
368                                                theMsg.getPATIENT().getPATIENT_VISIT().getPV2())
369                                .setDG1(dg1List, null);
370
371                List<IVisitMessage.IVisitMessageInsurance> insurances = getInsurances(
372                                theMsg.getPATIENT().getINSURANCEAll(), OMG_O19_INSURANCE::getIN1, OMG_O19_INSURANCE::getIN2);
373                visitMessage.setInsurances(
374                                insurances,
375                                () -> new VisitMessageInsurance<>(
376                                                theMsg.getPATIENT().insertINSURANCE(theMsg.getPATIENT().getINSURANCEReps()),
377                                                OMG_O19_INSURANCE::getIN1,
378                                                OMG_O19_INSURANCE::getIN2));
379
380                return visitMessage;
381        }
382
383        private IVisitMessage asVisitMessage(BAR_P12 theMsg) throws HL7Exception {
384                VisitMessage visitMessage = getDefaultVisitMessageAndSetPV1PV2(theMsg.getPV1(), null)
385                                .setDG1(theMsg.getDG1All(), () -> theMsg.insertDG1(theMsg.getDG1Reps()));
386
387                List<IVisitMessage.IVisitMessageProcedure> procedures =
388                                getProcedures(theMsg.getPROCEDUREAll(), BAR_P12_PROCEDURE::getPR1);
389                visitMessage.setProcedures(
390                                procedures,
391                                () -> new VisitMessageProcedure<>(
392                                                theMsg.insertPROCEDURE(theMsg.getPROCEDUREReps()), BAR_P12_PROCEDURE::getPR1));
393
394                return visitMessage;
395        }
396}