16
16
package de .symeda .sormas .backend .externalmessage .labmessage ;
17
17
18
18
import java .text .Collator ;
19
- import java .util .Comparator ;
20
- import java .util .Date ;
21
- import java .util .List ;
22
- import java .util .Objects ;
23
- import java .util .Set ;
19
+ import java .util .*;
24
20
import java .util .concurrent .CompletableFuture ;
25
21
import java .util .concurrent .CompletionStage ;
26
22
import java .util .concurrent .ExecutionException ;
37
33
import org .slf4j .Logger ;
38
34
import org .slf4j .LoggerFactory ;
39
35
36
+ import de .symeda .sormas .api .CountryHelper ;
40
37
import de .symeda .sormas .api .Disease ;
41
38
import de .symeda .sormas .api .caze .CaseDataDto ;
42
39
import de .symeda .sormas .api .caze .CaseSelectionDto ;
64
61
import de .symeda .sormas .api .utils .dataprocessing .HandlerCallback ;
65
62
import de .symeda .sormas .api .utils .dataprocessing .PickOrCreateEntryResult ;
66
63
import de .symeda .sormas .api .utils .dataprocessing .ProcessingResult ;
64
+ import de .symeda .sormas .api .utils .luxembourg .LuxembourgNationalHealthIdValidator ;
67
65
import de .symeda .sormas .backend .caze .CaseFacadeEjb .CaseFacadeEjbLocal ;
68
66
import de .symeda .sormas .backend .caze .CaseService ;
67
+ import de .symeda .sormas .backend .common .ConfigFacadeEjb .ConfigFacadeEjbLocal ;
69
68
import de .symeda .sormas .backend .disease .DiseaseConfigurationFacadeEjb .DiseaseConfigurationFacadeEjbLocal ;
70
69
import de .symeda .sormas .backend .person .PersonFacadeEjb .PersonFacadeEjbLocal ;
71
70
import de .symeda .sormas .backend .sample .PathogenTestFacadeEjb .PathogenTestFacadeEjbLocal ;
@@ -82,6 +81,8 @@ public class AutomaticLabMessageProcessor {
82
81
@ PersistenceContext (unitName = ModelConstants .PERSISTENCE_UNIT_NAME )
83
82
private EntityManager em ;
84
83
84
+ @ EJB
85
+ private ConfigFacadeEjbLocal configFacade ;
85
86
@ EJB
86
87
private UserFacadeEjbLocal userFacade ;
87
88
@ EJB
@@ -138,8 +139,74 @@ protected CompletionStage<Boolean> handleRelatedForwardedMessages() {
138
139
throw new UnsupportedOperationException ("Related forwarded messages not supported yet" );
139
140
}
140
141
141
- @ Override
142
- protected void handlePickOrCreatePerson (PersonDto person , HandlerCallback <EntitySelection <PersonDto >> callback ) {
142
+ /**
143
+ * Handles person picking/creation with localized logic.
144
+ * In case of Luxembourg, this method checks for a valid national health ID
145
+ * and attempts to find an exact matching person.
146
+ * Other country specific handling could be added to this method in the future.
147
+ *
148
+ * @param person
149
+ * The {@link PersonDto} to process.
150
+ * @param callback
151
+ * The {@link HandlerCallback} to deliver the result of the
152
+ * operation.
153
+ * @return {@code true} if the person was handled by this method (either found
154
+ * or created),
155
+ * {@code false} otherwise.
156
+ */
157
+ protected boolean localizedHandlePickOrCreatePerson (PersonDto person , HandlerCallback <EntitySelection <PersonDto >> callback ) {
158
+
159
+ if (configFacade .isConfiguredCountry (CountryHelper .COUNTRY_CODE_LUXEMBOURG )) {
160
+ String nationalHealthId = person .getNationalHealthId ();
161
+ if (StringUtils .isBlank (nationalHealthId )) {
162
+ logger .debug ("[MESSAGE PROCESSING] Incoming person's national health ID is blank. Canceling processing." );
163
+ callback .cancel ();
164
+ return true ;
165
+ }
166
+
167
+ if (!LuxembourgNationalHealthIdValidator .isValid (nationalHealthId , null , null , null )) {
168
+ logger .debug ("[MESSAGE PROCESSING] Incoming person's national health ID is not valid. Canceling processing." );
169
+ callback .cancel ();
170
+ return true ;
171
+ }
172
+
173
+ final List <PersonDto > matchingPersons = personFacade .getByNationalHealthId (nationalHealthId );
174
+
175
+ // Multiple persons matched
176
+ if (matchingPersons .size () > 1 ) {
177
+ logger
178
+ .debug ("[MESSAGE PROCESSING] Multiple persons with the same national health id found in the database. Canceling processing." );
179
+ callback .cancel ();
180
+ return true ;
181
+ }
182
+
183
+ // No persons matched
184
+ if (matchingPersons .isEmpty ()) {
185
+ callback .done (new EntitySelection <>(personFacade .save (person ), true ));
186
+ return true ;
187
+ }
188
+
189
+ // Exactly one person matched
190
+ callback .done (new EntitySelection <>(matchingPersons .get (0 ), false ));
191
+ return true ;
192
+ }
193
+
194
+ return false ;
195
+ }
196
+
197
+ /**
198
+ * Handles person picking/creation with default logic. This method checks for a
199
+ * national health ID. If present, it searches for matching persons. If no ID is
200
+ * found, it checks for similar persons based on name.
201
+ *
202
+ * @param person
203
+ * The {@link PersonDto} to process.
204
+ * @param callback
205
+ * The {@link HandlerCallback} to deliver the result of the
206
+ * operation.
207
+ */
208
+ protected void defaultHandlePickOrCreatePerson (PersonDto person , HandlerCallback <EntitySelection <PersonDto >> callback ) {
209
+
143
210
String nationalHealthId = person .getNationalHealthId ();
144
211
if (StringUtils .isNotBlank (nationalHealthId )) {
145
212
List <PersonDto > matchingPersons = personFacade .getByNationalHealthId (nationalHealthId );
@@ -163,6 +230,29 @@ protected void handlePickOrCreatePerson(PersonDto person, HandlerCallback<Entity
163
230
}
164
231
}
165
232
233
+ /**
234
+ * Handles the process of picking an existing person or creating a new one.
235
+ * This method first attempts to use localized handling. If that fails, it
236
+ * defaults to the general handling logic.
237
+ *
238
+ * @param person
239
+ * The {@link PersonDto} to process.
240
+ * @param callback
241
+ * The {@link HandlerCallback} to deliver the result of the
242
+ * operation.
243
+ */
244
+ @ Override
245
+ protected void handlePickOrCreatePerson (PersonDto person , HandlerCallback <EntitySelection <PersonDto >> callback ) {
246
+
247
+ // try to see if any localized handling is processing it
248
+ if (localizedHandlePickOrCreatePerson (person , callback )) {
249
+ return ;
250
+ }
251
+
252
+ // no localized handling was do so go with default
253
+ defaultHandlePickOrCreatePerson (person , callback );
254
+ }
255
+
166
256
@ Override
167
257
protected void handlePickOrCreateEntry (
168
258
List <CaseSelectionDto > similarCases ,
0 commit comments