diff --git a/src/main/java/org/broadinstitute/dsm/DSMServer.java b/src/main/java/org/broadinstitute/dsm/DSMServer.java index 9d195128f..be42d25df 100644 --- a/src/main/java/org/broadinstitute/dsm/DSMServer.java +++ b/src/main/java/org/broadinstitute/dsm/DSMServer.java @@ -192,13 +192,7 @@ protected void setupCustomRouting(@NonNull Config cfg) { before("*", new LoggingFilter()); afterAfter((req, res) -> MDC.clear()); - before(API_ROOT + RoutePath.BSP_KIT_QUERY_PATH, (req, res) -> { - if (!new JWTRouteFilter(bspSecret, null).isAccessAllowed(req)) { - halt(404); - } - res.header(HttpHeaders.CONTENT_TYPE, MediaType.JSON_UTF_8.toString()); - }); - before(API_ROOT + RoutePath.CLINICAL_KIT_ENDPOINT, (req, res) -> { + before(API_ROOT + "*", (req, res) -> { if (!new JWTRouteFilter(bspSecret, null).isAccessAllowed(req)) { halt(404); } diff --git a/src/main/java/org/broadinstitute/dsm/db/OncHistoryDetail.java b/src/main/java/org/broadinstitute/dsm/db/OncHistoryDetail.java index 88a049d41..04d0855d8 100644 --- a/src/main/java/org/broadinstitute/dsm/db/OncHistoryDetail.java +++ b/src/main/java/org/broadinstitute/dsm/db/OncHistoryDetail.java @@ -26,12 +26,15 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import static org.broadinstitute.ddp.db.TransactionWrapper.inTransaction; @Data -@TableName ( +@TableName( name = DBConstants.DDP_ONC_HISTORY_DETAIL, alias = DBConstants.DDP_ONC_HISTORY_DETAIL_ALIAS, primaryKey = DBConstants.ONC_HISTORY_DETAIL_ID, @@ -42,31 +45,33 @@ public class OncHistoryDetail { private static final Logger logger = LoggerFactory.getLogger(OncHistoryDetail.class); - public static final String SQL_SELECT_ONC_HISTORY_DETAIL = "SELECT p.ddp_participant_id, oD.onc_history_detail_id, oD.request, oD.deleted, oD.fax_sent, oD.tissue_received, oD.medical_record_id, oD.date_px, oD.type_px, " + - "oD.location_px, oD.histology, oD.accession_number, oD.facility, oD.phone, oD.fax, oD.notes, oD.additional_values_json, " + - "oD.request, oD.fax_sent, oD.fax_sent_by, oD.fax_confirmed, oD.fax_sent_2, oD.fax_sent_2_by, oD.fax_confirmed_2, oD.fax_sent_3, " + - "oD.fax_sent_3_by, oD.fax_confirmed_3, oD.tissue_received, oD.tissue_problem_option, oD.gender, oD.destruction_policy, oD.unable_obtain_tissue, " + - "tissue_id, t.notes, count_received, tissue_type, tissue_site, tumor_type, h_e, pathology_report, collaborator_sample_id, block_sent, scrolls_received, sk_id, sm_id, " + - "sent_gp, first_sm_id, additional_tissue_value_json, expected_return, return_date, return_fedex_id, shl_work_number, tumor_percentage, tissue_sequence, " + - " scrolls_count, uss_count, h_e_count, blocks_count " + - "FROM ddp_onc_history_detail oD " + - "LEFT JOIN ddp_medical_record m on (oD.medical_record_id = m.medical_record_id AND NOT oD.deleted <=> 1 AND NOT m.deleted <=> 1) " + - "LEFT JOIN ddp_institution inst on (inst.institution_id = m.institution_id) " + - "LEFT JOIN ddp_participant p on (p.participant_id = inst.participant_id) " + - "LEFT JOIN ddp_instance realm on (p.ddp_instance_id = realm.ddp_instance_id) " + - "LEFT JOIN ddp_tissue t on (oD.onc_history_detail_id = t.onc_history_detail_id AND NOT t.deleted <=> 1) " + - "WHERE realm.instance_name = ? "; + public static final String SQL_SELECT_ONC_HISTORY_DETAIL = "SELECT p.ddp_participant_id, p.participant_id, oD.onc_history_detail_id, oD.request, oD.deleted, oD.fax_sent, oD.tissue_received, oD.medical_record_id, oD.date_px, oD.type_px, " + + "oD.location_px, oD.histology, oD.accession_number, oD.facility, oD.phone, oD.fax, oD.notes, oD.additional_values_json, " + + "oD.request, oD.fax_sent, oD.fax_sent_by, oD.fax_confirmed, oD.fax_sent_2, oD.fax_sent_2_by, oD.fax_confirmed_2, oD.fax_sent_3, " + + "oD.fax_sent_3_by, oD.fax_confirmed_3, oD.tissue_received, oD.tissue_problem_option, oD.gender, oD.destruction_policy, oD.unable_obtain_tissue, " + + "t.tissue_id, t.notes, count_received, tissue_type, tissue_site, tumor_type, h_e, pathology_report, collaborator_sample_id, block_sent, scrolls_received, sk_id, sm_id, " + + "sent_gp, first_sm_id, additional_tissue_value_json, expected_return, return_date, return_fedex_id, shl_work_number, tumor_percentage, tissue_sequence, " + + " scrolls_count, uss_count, h_e_count, blocks_count, sm.sm_id_value, sm.sm_id_type_id, sm.sm_id_pk, sm.deleted, sm.tissue_id, smt.sm_id_type " + + "FROM ddp_onc_history_detail oD " + + "LEFT JOIN ddp_medical_record m on (oD.medical_record_id = m.medical_record_id AND NOT oD.deleted <=> 1 AND NOT m.deleted <=> 1) " + + "LEFT JOIN ddp_institution inst on (inst.institution_id = m.institution_id) " + + "LEFT JOIN ddp_participant p on (p.participant_id = inst.participant_id) " + + "LEFT JOIN ddp_instance realm on (p.ddp_instance_id = realm.ddp_instance_id) " + + "LEFT JOIN ddp_tissue t on (oD.onc_history_detail_id = t.onc_history_detail_id AND NOT t.deleted <=> 1) " + + "LEFT JOIN sm_id sm on (sm.tissue_id = t.tissue_id AND NOT sm.deleted <=> 1 ) " + + "LEFT JOIN sm_id_type smt on (smt.sm_id_type_id = sm.sm_id_type_id ) " + + "WHERE realm.instance_name = ? "; private static final String SQL_CREATE_ONC_HISTORY = "INSERT INTO ddp_onc_history_detail SET medical_record_id = ?, request = ?, last_changed = ?, changed_by = ?"; - private static final String SQL_SELECT_ONC_HISTORY = "SELECT onc_history_detail_id, medical_record_id, date_px, type_px, location_px, histology, accession_number, facility," + - " phone, fax, notes, additional_values_json, request, fax_sent, fax_sent_by, fax_confirmed, fax_sent_2, fax_sent_2_by, fax_confirmed_2, fax_sent_3, fax_sent_3_by, fax_confirmed_3," + - " tissue_received, gender, tissue_problem_option, destruction_policy FROM ddp_onc_history_detail WHERE NOT (deleted <=> 1)"; + private static final String SQL_SELECT_ONC_HISTORY = "SELECT onc_history_detail_id, medical_record_id, date_px, type_px, location_px, histology, accession_number, facility," + + " phone, fax, notes, additional_values_json, request, fax_sent, fax_sent_by, fax_confirmed, fax_sent_2, fax_sent_2_by, fax_confirmed_2, fax_sent_3, fax_sent_3_by, fax_confirmed_3," + + " tissue_received, gender, tissue_problem_option, destruction_policy FROM ddp_onc_history_detail WHERE NOT (deleted <=> 1)"; private static final String SQL_SELECT_TISSUE_RECEIVED = "SELECT tissue_received FROM ddp_onc_history_detail WHERE onc_history_detail_id = ?"; private static final String SQL_INSERT_ONC_HISTORY_DETAIL = "INSERT INTO ddp_onc_history_detail SET medical_record_id = ?, request = ?, last_changed = ?, changed_by = ?"; - public static final String SQL_ORDER_BY = " ORDER BY p.ddp_participant_id, inst.ddp_institution_id, oD.onc_history_detail_id ASC"; - public static final String SQL_SELECT_ONC_HISTORY_LAST_CHANGED = "SELECT oD.last_changed FROM ddp_institution inst " + - "LEFT JOIN ddp_participant as p on (p.participant_id = inst.participant_id) LEFT JOIN ddp_instance as ddp on (ddp.ddp_instance_id = p.ddp_instance_id) " + - "LEFT JOIN ddp_medical_record as m on (m.institution_id = inst.institution_id AND NOT m.deleted <=> 1) LEFT JOIN ddp_onc_history_detail as oD on (m.medical_record_id = oD.medical_record_id) " + - "WHERE p.participant_id = ?"; + public static final String SQL_ORDER_BY = " ORDER BY p.ddp_participant_id, inst.ddp_institution_id, oD.onc_history_detail_id, t.tissue_id ASC"; + public static final String SQL_SELECT_ONC_HISTORY_LAST_CHANGED = "SELECT oD.last_changed FROM ddp_institution inst " + + "LEFT JOIN ddp_participant as p on (p.participant_id = inst.participant_id) LEFT JOIN ddp_instance as ddp on (ddp.ddp_instance_id = p.ddp_instance_id) " + + "LEFT JOIN ddp_medical_record as m on (m.institution_id = inst.institution_id AND NOT m.deleted <=> 1) LEFT JOIN ddp_onc_history_detail as oD on (m.medical_record_id = oD.medical_record_id) " + + "WHERE p.participant_id = ?"; public static final String STATUS_REVIEW = "review"; public static final String STATUS_SENT = "sent"; @@ -91,81 +96,81 @@ public class OncHistoryDetail { @ColumnName(DBConstants.MEDICAL_RECORD_ID) private long medicalRecordId; - @ColumnName (DBConstants.DATE_PX) + @ColumnName(DBConstants.DATE_PX) @DbDateConversion(SqlDateConverter.STRING_DAY) private String datePx; - @ColumnName (DBConstants.TYPE_PX) + @ColumnName(DBConstants.TYPE_PX) private String typePx; - @ColumnName (DBConstants.LOCATION_PX) + @ColumnName(DBConstants.LOCATION_PX) private String locationPx; - @ColumnName (DBConstants.HISTOLOGY) + @ColumnName(DBConstants.HISTOLOGY) private String histology; - @ColumnName (DBConstants.ACCESSION_NUMBER) + @ColumnName(DBConstants.ACCESSION_NUMBER) private String accessionNumber; - @ColumnName (DBConstants.FACILITY) + @ColumnName(DBConstants.FACILITY) private String facility; - @ColumnName (DBConstants.PHONE) + @ColumnName(DBConstants.PHONE) private String phone; - @ColumnName (DBConstants.FAX) + @ColumnName(DBConstants.FAX) private String fax; - @ColumnName (DBConstants.NOTES) + @ColumnName(DBConstants.NOTES) private String notes; - @ColumnName (DBConstants.REQUEST) + @ColumnName(DBConstants.REQUEST) private String request; - @ColumnName (DBConstants.FAX_SENT) + @ColumnName(DBConstants.FAX_SENT) @DbDateConversion(SqlDateConverter.STRING_DAY) private String faxSent; - @ColumnName (DBConstants.FAX_SENT_BY) + @ColumnName(DBConstants.FAX_SENT_BY) private String faxSentBy; - @ColumnName (DBConstants.FAX_CONFIRMED) + @ColumnName(DBConstants.FAX_CONFIRMED) @DbDateConversion(SqlDateConverter.STRING_DAY) private String faxConfirmed; - @ColumnName (DBConstants.FAX_SENT_2) + @ColumnName(DBConstants.FAX_SENT_2) @DbDateConversion(SqlDateConverter.STRING_DAY) private String faxSent2; - @ColumnName (DBConstants.FAX_SENT_2_BY) + @ColumnName(DBConstants.FAX_SENT_2_BY) private String faxSent2By; - @ColumnName (DBConstants.FAX_CONFIRMED_2) + @ColumnName(DBConstants.FAX_CONFIRMED_2) @DbDateConversion(SqlDateConverter.STRING_DAY) private String faxConfirmed2; - @ColumnName (DBConstants.FAX_SENT_3) + @ColumnName(DBConstants.FAX_SENT_3) @DbDateConversion(SqlDateConverter.STRING_DAY) private String faxSent3; - @ColumnName (DBConstants.FAX_SENT_3_BY) + @ColumnName(DBConstants.FAX_SENT_3_BY) private String faxSent3By; - @ColumnName (DBConstants.FAX_CONFIRMED_3) + @ColumnName(DBConstants.FAX_CONFIRMED_3) @DbDateConversion(SqlDateConverter.STRING_DAY) private String faxConfirmed3; - @ColumnName (DBConstants.TISSUE_RECEIVED) + @ColumnName(DBConstants.TISSUE_RECEIVED) @DbDateConversion(SqlDateConverter.STRING_DAY) private String tissueReceived; - @ColumnName (DBConstants.TISSUE_PROBLEM_OPTION) + @ColumnName(DBConstants.TISSUE_PROBLEM_OPTION) private String tissueProblemOption; - @ColumnName (DBConstants.GENDER) + @ColumnName(DBConstants.GENDER) private String gender; - @ColumnName (DBConstants.ADDITIONAL_VALUES_JSON) + @ColumnName(DBConstants.ADDITIONAL_VALUES_JSON) @JsonProperty("dynamicFields") @SerializedName("dynamicFields") private String additionalValuesJson; @@ -173,28 +178,31 @@ public class OncHistoryDetail { @JsonProperty("dynamicFields") public Map getDynamicFields() { try { - return ObjectMapperSingleton.instance().readValue(additionalValuesJson, new TypeReference>() {}); + return ObjectMapperSingleton.instance().readValue(additionalValuesJson, new TypeReference>() { + }); } catch (IOException | NullPointerException e) { return Map.of(); } } - @ColumnName (DBConstants.DESTRUCTION_POLICY) + @ColumnName(DBConstants.DESTRUCTION_POLICY) private String destructionPolicy; private String changedBy; - @ColumnName (DBConstants.DELETED) + @ColumnName(DBConstants.DELETED) private boolean deleted; - @ColumnName (DBConstants.UNABLE_OBTAIN_TISSUE) + @ColumnName(DBConstants.UNABLE_OBTAIN_TISSUE) private boolean unableObtainTissue; private String participantId; + private String ddpParticipantId; private List tissues; - public OncHistoryDetail() {} + public OncHistoryDetail() { + } public OncHistoryDetail(long oncHistoryDetailId, long medicalRecordId, String datePx, String typePx, String locationPx, String histology, String accessionNumber, String facility, String phone, @@ -241,7 +249,7 @@ public OncHistoryDetail(long oncHistoryDetailId, long medicalRecordId, String da String faxSent2, String faxSent2By, String faxConfirmed2, String faxSent3, String faxSent3By, String faxConfirmed3, String tissueReceived, String gender, String additionalValuesJson, List tissues, - String tissueProblemOption, String destructionPolicy, boolean unableObtainTissue) { + String tissueProblemOption, String destructionPolicy, boolean unableObtainTissue, String participantId, String ddpParticipantId) { this.oncHistoryDetailId = oncHistoryDetailId; this.medicalRecordId = medicalRecordId; this.datePx = datePx; @@ -270,6 +278,8 @@ public OncHistoryDetail(long oncHistoryDetailId, long medicalRecordId, String da this.tissueProblemOption = tissueProblemOption; this.destructionPolicy = destructionPolicy; this.unableObtainTissue = unableObtainTissue; + this.participantId = participantId; + this.ddpParticipantId = ddpParticipantId; } public static OncHistoryDetail getOncHistoryDetail(@NonNull ResultSet rs) throws SQLException { @@ -301,9 +311,10 @@ public static OncHistoryDetail getOncHistoryDetail(@NonNull ResultSet rs) throws rs.getString(DBConstants.DDP_ONC_HISTORY_DETAIL_ALIAS + DBConstants.ALIAS_DELIMITER + DBConstants.ADDITIONAL_VALUES_JSON), tissues, rs.getString(DBConstants.TISSUE_PROBLEM_OPTION), rs.getString(DBConstants.DESTRUCTION_POLICY), - rs.getBoolean(DBConstants.UNABLE_OBTAIN_TISSUE) + rs.getBoolean(DBConstants.UNABLE_OBTAIN_TISSUE), + rs.getString(DBConstants.PARTICIPANT_ID), + rs.getString(DBConstants.DDP_PARTICIPANT_ID) ); - return oncHistoryDetail; } @@ -332,45 +343,53 @@ public static Map> getOncHistoryDetailsByParticip public static Map> getOncHistoryDetails(@NonNull String realm, String queryAddition) { logger.info("Collection oncHistoryDetail information"); Map> oncHistory = new HashMap<>(); + Map tissues = new HashMap<>(); SimpleResult results = inTransaction((conn) -> { SimpleResult dbVals = new SimpleResult(); try (PreparedStatement stmt = conn.prepareStatement(DBUtil.getFinalQuery(SQL_SELECT_ONC_HISTORY_DETAIL, queryAddition) + SQL_ORDER_BY)) { stmt.setString(1, realm); try (ResultSet rs = stmt.executeQuery()) { - Map oncHistoryMap = new HashMap<>(); + Map oncHistoryMap = new HashMap<>(); while (rs.next()) { - String ddpParticipantId = rs.getString(DBConstants.DDP_PARTICIPANT_ID); - String oncHistoryDetailId = rs.getString(DBConstants.ONC_HISTORY_DETAIL_ID); - - Tissue tissue = Tissue.getTissue(rs); - - //check if oncHistoryDetails is already in map - List oncHistoryDataList = new ArrayList<>(); - if (oncHistory.containsKey(ddpParticipantId)) { - oncHistoryDataList = oncHistory.get(ddpParticipantId); + long oncHistoryDetailId = rs.getLong(DBConstants.ONC_HISTORY_DETAIL_ID); + TissueSmId tissueSmId = Tissue.getSMIds(rs); + Tissue tissue; + if (tissueSmId != null && tissues.containsKey(tissueSmId.getTissueId())) { + tissue = tissues.get(tissueSmId.getTissueId()); + } else { + tissue = Tissue.getTissue(rs); } - else { - oncHistory.put(ddpParticipantId, oncHistoryDataList); - oncHistoryMap = new HashMap<>(); + if (tissueSmId != null) { + tissue.setSmIdBasedOnType(tissueSmId, rs); } - - OncHistoryDetail oncHistoryDetail = null; - if (oncHistoryMap.containsKey(oncHistoryDetailId)) { - oncHistoryDetail = oncHistoryMap.get(oncHistoryDetailId); - if (tissue != null) - oncHistoryDetail.addTissue(tissue); + if (tissue != null) { + tissues.put(tissue.getTissueId(), tissue); } - else { - oncHistoryDetail = getOncHistoryDetail(rs); - if (tissue != null) - oncHistoryDetail.addTissue(tissue); - oncHistoryDataList.add(oncHistoryDetail); + + if (!oncHistoryMap.containsKey(oncHistoryDetailId)) { + OncHistoryDetail oncHistoryDetail = getOncHistoryDetail(rs); + oncHistoryMap.put(oncHistoryDetailId, oncHistoryDetail); } - oncHistoryMap.put(oncHistoryDetailId, oncHistoryDetail); + } + //add tissues to their onc history + for (Tissue tissue : tissues.values()) { + long tissueOncHistoryDetailId = tissue.getOncHistoryDetailId(); + OncHistoryDetail oncHistoryDetail = oncHistoryMap.get(tissueOncHistoryDetailId); + oncHistoryDetail.getTissues().add(tissue); + }// add onchistories to their particiapnt + for (OncHistoryDetail oncHistoryDetail : oncHistoryMap.values()) { + //check if oncHistoryDetails is already in map + String ddpParticipantId = oncHistoryDetail.getDdpParticipantId(); + List oncHistoryDataList = oncHistory.getOrDefault(ddpParticipantId, new ArrayList<>()); + oncHistoryDataList.add(oncHistoryDetail); + oncHistory.put(ddpParticipantId, oncHistoryDataList); + } + + } catch (Exception e) { + dbVals.resultException = e; } - } - catch (SQLException ex) { + } catch (SQLException ex) { dbVals.resultException = ex; } return dbVals; @@ -395,8 +414,7 @@ public static OncHistoryDetail getOncHistoryDetail(@NonNull String oncHistoryDet dbVals.resultValue = getOncHistoryDetail(rs); } } - } - catch (SQLException ex) { + } catch (SQLException ex) { dbVals.resultException = ex; } return dbVals; @@ -425,16 +443,13 @@ public static String createNewOncHistoryDetail(@NonNull String medicalRecordId, logger.info("Added new oncHistoryDetail for medicalRecord w/ id " + medicalRecordId); dbVals.resultValue = oncHistoryDetailId; } - } - catch (Exception e) { + } catch (Exception e) { throw new RuntimeException("Error getting id of new institution ", e); } - } - else { + } else { throw new RuntimeException("Error adding new oncHistoryDetail for medicalRecord w/ id " + medicalRecordId + " it was updating " + result + " rows"); } - } - catch (SQLException ex) { + } catch (SQLException ex) { dbVals.resultException = ex; } return dbVals; @@ -442,8 +457,7 @@ public static String createNewOncHistoryDetail(@NonNull String medicalRecordId, if (results.resultException != null) { throw new RuntimeException("Error adding new oncHistoryDetail for medicalRecord w/ id " + medicalRecordId, results.resultException); - } - else { + } else { return (String) results.resultValue; } } @@ -454,8 +468,7 @@ public static Boolean hasReceivedDate(@NonNull Patch patch) { try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_TISSUE_RECEIVED)) { if (patch.getNameValue().getName().contains(DBConstants.DDP_TISSUE_ALIAS + DBConstants.ALIAS_DELIMITER)) { stmt.setString(1, patch.getParentId()); - } - else if (patch.getNameValue().getName().contains(DBConstants.DDP_ONC_HISTORY_DETAIL_ALIAS + DBConstants.ALIAS_DELIMITER)) { + } else if (patch.getNameValue().getName().contains(DBConstants.DDP_ONC_HISTORY_DETAIL_ALIAS + DBConstants.ALIAS_DELIMITER)) { stmt.setString(1, patch.getId()); } try (ResultSet rs = stmt.executeQuery()) { @@ -463,20 +476,16 @@ else if (patch.getNameValue().getName().contains(DBConstants.DDP_ONC_HISTORY_DET String receivedDate = rs.getString(DBConstants.TISSUE_RECEIVED); if (StringUtils.isNotBlank(receivedDate)) { dbVals.resultValue = true; - } - else { + } else { dbVals.resultValue = false; } - } - else { + } else { dbVals.resultException = new RuntimeException(" The patch id was not found in the table!"); } - } - catch (SQLException ex) { + } catch (SQLException ex) { dbVals.resultException = ex; } - } - catch (SQLException ex) { + } catch (SQLException ex) { dbVals.resultException = ex; } return dbVals; diff --git a/src/main/java/org/broadinstitute/dsm/db/Tissue.java b/src/main/java/org/broadinstitute/dsm/db/Tissue.java index 8c2a804e8..c227b8127 100644 --- a/src/main/java/org/broadinstitute/dsm/db/Tissue.java +++ b/src/main/java/org/broadinstitute/dsm/db/Tissue.java @@ -21,13 +21,14 @@ import java.io.IOException; import java.sql.*; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import static org.broadinstitute.ddp.db.TransactionWrapper.inTransaction; @Data -@TableName ( +@TableName( name = DBConstants.DDP_TISSUE, alias = DBConstants.DDP_TISSUE_ALIAS, primaryKey = DBConstants.TISSUE_ID, @@ -38,17 +39,19 @@ public class Tissue { private static final Logger logger = LoggerFactory.getLogger(Tissue.class); - private static final String SQL_SELECT_TISSUE = "SELECT tissue_id, onc_history_detail_id, notes, count_received, tissue_type, tissue_site, tumor_type, h_e, " + - "pathology_report, collaborator_sample_id, block_sent, expected_return, return_date, return_fedex_id, scrolls_received, sk_id, sm_id, " + - "scrolls_count, uss_count, blocks_count, h_e_count, first_sm_id, sent_gp, last_changed, changed_by, additional_tissue_value_json, shl_work_number, " + - "tumor_percentage, tissue_sequence FROM ddp_tissue t WHERE NOT (deleted <=> 1) AND onc_history_detail_id = ?"; + private static final String SQL_SELECT_TISSUE = "SELECT tissue_id, onc_history_detail_id, notes, count_received, tissue_type, tissue_site, tumor_type, h_e, " + + "pathology_report, collaborator_sample_id, block_sent, expected_return, return_date, return_fedex_id, scrolls_received, sk_id, sm_id, " + + "scrolls_count, uss_count, blocks_count, h_e_count, first_sm_id, sent_gp, last_changed, changed_by, additional_tissue_value_json, shl_work_number, " + + "tumor_percentage, tissue_sequence, sm.sm_id_value, sm.sm_id_type_id, sm.sm_id_pk, sm.deleted, sm.tissue_id FROM ddp_tissue t " + + "LEFT JOIN sm_id sm on (sm.tissue_id = t.tissue_id AND NOT sm.deleted <=> 1 AND NOT t.deleted <=> 1) " + + "WHERE NOT (t.deleted <=> 1) AND onc_history_detail_id = ?"; private static final String SQL_INSERT_TISSUE = "INSERT INTO ddp_tissue SET onc_history_detail_id = ?, last_changed = ?, changed_by = ?"; public static final String SQL_SELECT_TISSUE_LAST_CHANGED = "SELECT t.last_changed FROM ddp_institution inst " + "LEFT JOIN ddp_participant as p on (p.participant_id = inst.participant_id) LEFT JOIN ddp_instance as ddp on (ddp.ddp_instance_id = p.ddp_instance_id) " + "LEFT JOIN ddp_medical_record as m on (m.institution_id = inst.institution_id AND NOT m.deleted <=> 1) LEFT JOIN ddp_onc_history_detail as oD on (m.medical_record_id = oD.medical_record_id) " + "LEFT JOIN ddp_tissue as t on (t.onc_history_detail_id = oD.onc_history_detail_id) WHERE p.participant_id = ?"; - @TableName ( + @TableName( name = DBConstants.DDP_TISSUE, alias = DBConstants.DDP_TISSUE_ALIAS, primaryKey = DBConstants.TISSUE_ID, @@ -59,60 +62,60 @@ public class Tissue { @ColumnName(DBConstants.ONC_HISTORY_DETAIL_ID) private long oncHistoryDetailId; - @ColumnName (DBConstants.NOTES) + @ColumnName(DBConstants.NOTES) private String notes; - @ColumnName (DBConstants.COUNT_RECEIVED) + @ColumnName(DBConstants.COUNT_RECEIVED) private long countReceived; - @ColumnName (DBConstants.TISSUE_TYPE) + @ColumnName(DBConstants.TISSUE_TYPE) private String tissueType; - @ColumnName (DBConstants.TISSUE_SITE) + @ColumnName(DBConstants.TISSUE_SITE) private String tissueSite; - @ColumnName (DBConstants.TUMOR_TYPE) + @ColumnName(DBConstants.TUMOR_TYPE) private String tumorType; - @ColumnName (DBConstants.H_E) + @ColumnName(DBConstants.H_E) private String hE; - @ColumnName (DBConstants.PATHOLOGY_REPORT) + @ColumnName(DBConstants.PATHOLOGY_REPORT) private String pathologyReport; - @ColumnName (DBConstants.COLLABORATOR_SAMPLE_ID) + @ColumnName(DBConstants.COLLABORATOR_SAMPLE_ID) private String collaboratorSampleId; - @ColumnName (DBConstants.BLOCK_SENT) + @ColumnName(DBConstants.BLOCK_SENT) @DbDateConversion(SqlDateConverter.STRING_DAY) private String blockSent; - @ColumnName (DBConstants.SHL_WORK_NUMBER) + @ColumnName(DBConstants.SHL_WORK_NUMBER) private String shlWorkNumber; - @ColumnName (DBConstants.SCROLLS_RECEIVED) + @ColumnName(DBConstants.SCROLLS_RECEIVED) @DbDateConversion(SqlDateConverter.STRING_DAY) private String scrollsReceived; - @ColumnName (DBConstants.SK_ID) + @ColumnName(DBConstants.SK_ID) private String skId; - @ColumnName (DBConstants.SM_ID) + @ColumnName(DBConstants.SM_ID) private String smId; - @ColumnName (DBConstants.SENT_GP) + @ColumnName(DBConstants.SENT_GP) @DbDateConversion(SqlDateConverter.STRING_DAY) private String sentGp; private String changedBy; - @ColumnName (DBConstants.DELETED) + @ColumnName(DBConstants.DELETED) private boolean deleted; - @ColumnName (DBConstants.FIRST_SM_ID) + @ColumnName(DBConstants.FIRST_SM_ID) private String firstSmId; - @ColumnName (DBConstants.ADDITIONAL_TISSUE_VALUES) + @ColumnName(DBConstants.ADDITIONAL_TISSUE_VALUES) @JsonProperty("dynamicFields") @SerializedName("dynamicFields") private String additionalValuesJson; @@ -120,39 +123,40 @@ public class Tissue { @JsonProperty("dynamicFields") public Map getDynamicFields() { try { - return ObjectMapperSingleton.instance().readValue(additionalValuesJson, new TypeReference>() {}); + return ObjectMapperSingleton.instance().readValue(additionalValuesJson, new TypeReference>() { + }); } catch (IOException | NullPointerException e) { return Map.of(); } } - @ColumnName (DBConstants.TISSUE_RETURN_DATE) + @ColumnName(DBConstants.TISSUE_RETURN_DATE) @DbDateConversion(SqlDateConverter.STRING_DAY) private String returnDate; - @ColumnName (DBConstants.RETURN_FEDEX_ID) + @ColumnName(DBConstants.RETURN_FEDEX_ID) private String returnFedexId; - @ColumnName (DBConstants.EXPECTED_RETURN) + @ColumnName(DBConstants.EXPECTED_RETURN) @DbDateConversion(SqlDateConverter.STRING_DAY) private String expectedReturn; - @ColumnName (DBConstants.TUMOR_PERCENTAGE) + @ColumnName(DBConstants.TUMOR_PERCENTAGE) private String tumorPercentage; - @ColumnName (DBConstants.TISSUE_SEQUENCE) + @ColumnName(DBConstants.TISSUE_SEQUENCE) private String tissueSequence; - @ColumnName (DBConstants.SCROLLS_COUNT) + @ColumnName(DBConstants.SCROLLS_COUNT) private long scrollsCount; - @ColumnName (DBConstants.USS_COUNT) + @ColumnName(DBConstants.USS_COUNT) private long ussCount; - @ColumnName (DBConstants.BLOCKS_COUNT) + @ColumnName(DBConstants.BLOCKS_COUNT) private long blocksCount; - @ColumnName (DBConstants.H_E_COUNT) + @ColumnName(DBConstants.H_E_COUNT) private long hECount; @JsonProperty("hECount") @@ -160,14 +164,21 @@ public long gethECount() { return hECount; } - public Tissue() {} + private List ussSMID; + + private List scrollSMID; + + private List heSMID; + + public Tissue() { + } public Tissue(long tissueId, long oncHistoryDetailId, String notes, long countReceived, String tissueType, String tissueSite, String tumorType, String hE, String pathologyReport, String collaboratorSampleId, String blockSent, String scrollsReceived, String skId, String smId, String sentGp, String firstSmId, String additionalValuesJson, String expectedReturn, String returnDate, String returnFedexId, String shlWorkNumber, String tumorPercentage, String tissueSequence, long scrollsCount, - long ussCount, long blocksCount, long hECount) { + long ussCount, long blocksCount, long hECount, List ussSMIDs, List scrollSMIDs, List heSMID) { this.tissueId = tissueId; this.oncHistoryDetailId = oncHistoryDetailId; this.notes = notes; @@ -195,6 +206,9 @@ public Tissue(long tissueId, long oncHistoryDetailId, String notes, long countRe this.hECount = hECount; this.blocksCount = blocksCount; this.ussCount = ussCount; + this.scrollSMID = scrollSMIDs; + this.ussSMID = ussSMIDs; + this.heSMID = heSMID; } public static Tissue getTissue(@NonNull ResultSet rs) throws SQLException { @@ -228,32 +242,72 @@ public static Tissue getTissue(@NonNull ResultSet rs) throws SQLException { rs.getLong(DBConstants.SCROLLS_COUNT), rs.getLong(DBConstants.USS_COUNT), rs.getLong(DBConstants.BLOCKS_COUNT), - rs.getLong(DBConstants.H_E_COUNT)); + rs.getLong(DBConstants.H_E_COUNT), + new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); return tissue; } - public static List getTissue(@NonNull Connection conn, @NonNull String oncHistoryDetailId) { + public static TissueSmId getSMIds(ResultSet rs) { + return TissueSmId.getSMIdsForTissueId(rs); + } - List tissue = new ArrayList<>(); + public static List getTissue(@NonNull Connection conn, @NonNull String oncHistoryDetailId) { + List tissueList = new ArrayList<>(); SimpleResult dbVals = new SimpleResult(); + Map tissues = new HashMap<>(); try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_TISSUE)) { stmt.setString(1, oncHistoryDetailId); try (ResultSet rs = stmt.executeQuery()) { while (rs.next()) { - tissue.add(getTissue(rs)); + TissueSmId tissueSmId = getSMIds(rs); + Tissue tissue; + if (tissueSmId != null && tissues.containsKey(tissueSmId.getTissueId())) { + tissue = tissues.get(tissueSmId.getTissueId()); + } else { + tissue = getTissue(rs); + } + if (tissueSmId != null) { + tissue.setSmIdBasedOnType(tissueSmId, rs); + } + tissues.put(tissue.tissueId, tissue); } } - } - catch (SQLException ex) { + } catch (SQLException ex) { dbVals.resultException = ex; } if (dbVals.resultException != null) { throw new RuntimeException("Error getting tissue for oncHistoryDetails w/ id " + oncHistoryDetailId, dbVals.resultException); } + tissueList.addAll(tissues.values()); + logger.info("Found " + tissueList.size() + " tissue for oncHistoryDetails w/ id " + oncHistoryDetailId); + return tissueList; + } - logger.info("Found " + tissue.size() + " tissue for oncHistoryDetails w/ id " + oncHistoryDetailId); - return tissue; + public void setSmIdBasedOnType(TissueSmId tissueSmId, ResultSet rs) { + if (tissueSmId == null || tissueSmId.getSmIdType() == null) { + return; + } + try { + String type = rs.getString(DBConstants.SM_ID_TYPE_TABLE_ALIAS + "." + DBConstants.SM_ID_TYPE); + switch (type.toLowerCase()) { + case "he": { + this.heSMID.add(tissueSmId); + break; + + } + case "uss": { + this.ussSMID.add(tissueSmId); + break; + } + case "scrolls": { + this.scrollSMID.add(tissueSmId); + break; + } + } + } catch (SQLException throwables) { + throwables.printStackTrace(); + } } public static String createNewTissue(@NonNull String oncHistoryId, @NonNull String user) { @@ -270,16 +324,13 @@ public static String createNewTissue(@NonNull String oncHistoryId, @NonNull Stri logger.info("Created new tissue for oncHistoryDetail w/ id " + oncHistoryId); dbVals.resultValue = rs.getString(1); } - } - catch (Exception e) { + } catch (Exception e) { throw new RuntimeException("Error getting id of new institution ", e); } - } - else { + } else { throw new RuntimeException("Error adding new tissue for oncHistoryDetail w/ id " + oncHistoryId + " it was updating " + result + " rows"); } - } - catch (SQLException ex) { + } catch (SQLException ex) { dbVals.resultException = ex; } return dbVals; diff --git a/src/main/java/org/broadinstitute/dsm/db/TissueSmId.java b/src/main/java/org/broadinstitute/dsm/db/TissueSmId.java new file mode 100644 index 000000000..8fd133465 --- /dev/null +++ b/src/main/java/org/broadinstitute/dsm/db/TissueSmId.java @@ -0,0 +1,107 @@ +package org.broadinstitute.dsm.db; + +import lombok.Data; +import lombok.NonNull; +import org.apache.commons.lang3.StringUtils; +import org.broadinstitute.dsm.db.dao.ddp.tissue.TissueSMIDDao; +import org.broadinstitute.dsm.db.structure.ColumnName; +import org.broadinstitute.dsm.db.structure.TableName; +import org.broadinstitute.dsm.exception.DuplicateException; +import org.broadinstitute.dsm.model.NameValue; +import org.broadinstitute.dsm.statics.DBConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +@Data +@TableName ( + name = DBConstants.SM_ID_TABLE, + alias = DBConstants.SM_ID_TABLE_ALIAS, + primaryKey = DBConstants.SM_ID_PK, + columnPrefix = "") +public class TissueSmId { + + @ColumnName (DBConstants.SM_ID_VALUE) + private String smIdValue; + + @ColumnName (DBConstants.SM_ID_TYPE_ID) + private String smIdType; + + @ColumnName (DBConstants.SM_ID_TISSUE_ID) + private String tissueId; + + @ColumnName (DBConstants.SM_ID_PK) + private String smIdPk; + + @ColumnName (DBConstants.DELETED) + private Boolean deleted; + + public static String HE = "he"; + public static String USS = "uss"; + public static String SCROLLS = "scrolls"; + private static final Logger logger = LoggerFactory.getLogger(TissueSmId.class); + + public TissueSmId() { + } + + public TissueSmId(String smIdPk, String smIdType, String smIdValue, String tissueId) { + this.smIdPk = smIdPk; + this.smIdType = smIdType; + this.smIdValue = smIdValue; + this.tissueId = tissueId; + } + + + public static TissueSmId getSMIdsForTissueId(ResultSet rs) { + TissueSmId tissueSmId = null; + + try { + if (rs.getString(DBConstants.SM_ID_PK) == null) { + return null; + } + tissueSmId = new TissueSmId( + rs.getString(DBConstants.SM_ID_PK), + rs.getString(DBConstants.SM_ID_TYPE_ID), + rs.getString(DBConstants.SM_ID_VALUE), + rs.getString("sm." + DBConstants.TISSUE_ID) + ); + if (tissueSmId != null) { + tissueSmId.setDeleted(rs.getBoolean("sm." + DBConstants.DELETED)); + } + } + catch (SQLException e) { + logger.error("problem getting tissue sm ids", e); + } + return tissueSmId; + } + + public static boolean isUniqueSmId(String smIdValue, String id) { + return new TissueSMIDDao().isUnique(smIdValue, id); + } + + public static boolean isUniqueSmId(String smIdValue) { + return new TissueSMIDDao().isUnique(smIdValue); + } + + public String createNewSmId(@NonNull String tissueId, String userId, @NonNull List smIdDetails) { + String smIdType = null; + String smIdValue = null; + for (NameValue nameValue : smIdDetails) { + if (nameValue.getName().equals("smIdType")) { + smIdType = String.valueOf(nameValue.getValue()); + } + else if (nameValue.getName().equals("smIdValue")) { + smIdValue = String.valueOf(nameValue.getValue()); + } + } + if(StringUtils.isNotBlank(smIdValue) && this.isUniqueSmId(smIdValue)) { + String smIdId = new TissueSMIDDao().createNewSMIDForTissue(tissueId, userId, smIdType, smIdValue); + return smIdId; + } else{ + throw new DuplicateException("Duplicate or blank value for sm id value "+smIdValue); + } + } +} diff --git a/src/main/java/org/broadinstitute/dsm/db/dao/ddp/tissue/TissueSMIDDao.java b/src/main/java/org/broadinstitute/dsm/db/dao/ddp/tissue/TissueSMIDDao.java new file mode 100644 index 000000000..1f5e3e3df --- /dev/null +++ b/src/main/java/org/broadinstitute/dsm/db/dao/ddp/tissue/TissueSMIDDao.java @@ -0,0 +1,172 @@ +package org.broadinstitute.dsm.db.dao.ddp.tissue; + +import lombok.NonNull; +import org.broadinstitute.ddp.db.SimpleResult; +import org.broadinstitute.dsm.statics.DBConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import static org.broadinstitute.ddp.db.TransactionWrapper.inTransaction; + +public class TissueSMIDDao { + private static final Logger logger = LoggerFactory.getLogger(TissueSMIDDao.class); + + public static final String SQL_GET_SM_ID_BASED_ON_TISSUE_ID = " SELECT * from sm_id sm where sm.tissue_id= ? and NOT sm.deleted <=> 1"; + public static final String SQL_TYPE_ID_FOR_TYPE = "SELECT sm_id_type_id from sm_id_type where `sm_id_type` = ?"; + public static final String SQL_INSERT_SM_ID = "INSERT INTO sm_id SET tissue_id = ?, sm_id_type_id = ?, sm_id_value=?, last_changed = ?, changed_by = ?"; + public static final String SQL_INSERT_SM_ID_WITH_VALUE = "INSERT INTO sm_id SET tissue_id = ?, sm_id_type_id = ?, last_changed = ?, changed_by = ?, sm_id_value = ?"; + public static final String SQL_SELECT_SM_ID_VALUE_WITH_ID = "SELECT sm_id_value from sm_id where sm_id_value = ? and NOT sm_id_pk = ? and Not deleted <=> 1"; + public static final String SQL_SELECT_SM_ID_VALUE = "SELECT sm_id_value from sm_id where sm_id_value = ? and Not deleted <=> 1"; + + public String getTypeForName(String type) { + SimpleResult results = inTransaction((conn) -> { + SimpleResult dbVals = new SimpleResult(); + try (PreparedStatement stmt = conn.prepareStatement(SQL_TYPE_ID_FOR_TYPE)) { + stmt.setString(1, type); + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + dbVals.resultValue = rs.getString(DBConstants.SM_ID_TYPE_ID); + } + } + } catch (SQLException ex) { + dbVals.resultException = ex; + } + return dbVals; + }); + + if (results.resultException != null) { + throw new RuntimeException("Error getting type ids for sm id " + type, results.resultException); + } + + return (String) results.resultValue; + } + + public String createNewSMIDForTissueWithValue(String tissueId, String userId, String smIdType, String smIdValue) { + String smIdtypeId = getTypeForName(smIdType); + SimpleResult results = inTransaction((conn) -> { + SimpleResult dbVals = new SimpleResult(); + try (PreparedStatement stmt = conn.prepareStatement(SQL_INSERT_SM_ID_WITH_VALUE, Statement.RETURN_GENERATED_KEYS)) { + stmt.setString(1, tissueId); + stmt.setString(2, smIdtypeId); + stmt.setLong(3, System.currentTimeMillis()); + stmt.setString(4, userId); + stmt.setString(5, smIdValue); + int result = stmt.executeUpdate(); + if (result == 1) { + try (ResultSet rs = stmt.getGeneratedKeys()) { + if (rs.next()) { + logger.info("Created new sm id for tissue w/ id " + tissueId); + dbVals.resultValue = rs.getString(1); + } + } catch (Exception e) { + throw new RuntimeException("Error getting id of new sm id ", e); + } + } else { + throw new RuntimeException("Error adding new sm id for tissue w/ id " + tissueId + " it was updating " + result + " rows"); + } + } catch (SQLException ex) { + dbVals.resultException = ex; + } + return dbVals; + }); + + + if (results.resultException != null) { + throw new RuntimeException("Error adding new sm id for tissue w/ id " + tissueId, results.resultException); + } else { + return (String) results.resultValue; + } + } + + public String createNewSMIDForTissue(String tissueId, String userId, @NonNull String smIdType, @NonNull String smIdValue) { + String smIdtypeId = getTypeForName(smIdType); + SimpleResult results = inTransaction((conn) -> { + SimpleResult dbVals = new SimpleResult(); + try (PreparedStatement stmt = conn.prepareStatement(SQL_INSERT_SM_ID, Statement.RETURN_GENERATED_KEYS)) { + stmt.setString(1, tissueId); + stmt.setString(2, smIdtypeId); + stmt.setString(3, smIdValue); + stmt.setLong(4, System.currentTimeMillis()); + stmt.setString(5, userId); + int result = stmt.executeUpdate(); + if (result == 1) { + try (ResultSet rs = stmt.getGeneratedKeys()) { + if (rs.next()) { + logger.info("Created new sm id for tissue w/ id " + tissueId); + dbVals.resultValue = rs.getString(1); + } + } catch (Exception e) { + throw new RuntimeException("Error getting id of new sm id ", e); + } + } else { + throw new RuntimeException("Error adding new sm id for tissue w/ id " + tissueId + " it was updating " + result + " rows"); + } + } catch (SQLException ex) { + dbVals.resultException = ex; + } + return dbVals; + }); + + if (results.resultException != null) { + throw new RuntimeException("Error adding new sm id for tissue w/ id " + tissueId, results.resultException); + } else { + return (String) results.resultValue; + } + } + + public boolean isUnique(String smIdValue, String smIdPk) { + SimpleResult results = inTransaction((conn) -> { + SimpleResult dbVals = new SimpleResult(); + try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_SM_ID_VALUE_WITH_ID)) { + stmt.setString(1, smIdValue); + stmt.setString(2, smIdPk);// added to let updating + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + dbVals.resultValue = false; + } else { + dbVals.resultValue = true; + } + } + } catch (SQLException ex) { + dbVals.resultException = ex; + } + return dbVals; + }); + + if (results.resultException != null) { + throw new RuntimeException("Error getting values from sm_id table matching " + smIdValue, results.resultException); + } + + return (boolean) results.resultValue; + } + + public boolean isUnique(String smIdValue) { + SimpleResult results = inTransaction((conn) -> { + SimpleResult dbVals = new SimpleResult(); + try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_SM_ID_VALUE)) { + stmt.setString(1, smIdValue); + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + dbVals.resultValue = false; + } else { + dbVals.resultValue = true; + } + } + } catch (SQLException ex) { + dbVals.resultException = ex; + } + return dbVals; + }); + + if (results.resultException != null) { + throw new RuntimeException("Error getting values from sm_id table matching " + smIdValue, results.resultException); + } + + return (boolean) results.resultValue; + } +} diff --git a/src/main/java/org/broadinstitute/dsm/db/dao/kit/BSPDummyKitDao.java b/src/main/java/org/broadinstitute/dsm/db/dao/kit/BSPDummyKitDao.java index 54b83c791..a48f833fc 100644 --- a/src/main/java/org/broadinstitute/dsm/db/dao/kit/BSPDummyKitDao.java +++ b/src/main/java/org/broadinstitute/dsm/db/dao/kit/BSPDummyKitDao.java @@ -2,11 +2,13 @@ import org.broadinstitute.ddp.db.SimpleResult; import org.broadinstitute.dsm.db.DDPInstance; +import org.broadinstitute.dsm.db.OncHistoryDetail; import org.broadinstitute.dsm.db.dao.Dao; import org.broadinstitute.dsm.db.dto.kit.ClinicalKitDto; import org.broadinstitute.dsm.model.elastic.ESProfile; import org.broadinstitute.dsm.model.elastic.search.ElasticSearchParticipantDto; import org.broadinstitute.dsm.statics.DBConstants; +import org.broadinstitute.dsm.util.DBUtil; import org.broadinstitute.dsm.util.ElasticSearchUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,6 +24,8 @@ public class BSPDummyKitDao implements Dao { private static final String SQL_UPDATE_DUMMY_KIT = "UPDATE ddp_kit SET kit_label = ? where dsm_kit_request_id = ?"; private static final String SQL_SELECT_RANDOM_PT = "SELECT ddp_participant_id FROM ddp_kit_request req, ddp_kit kit where req.dsm_kit_request_id = kit.dsm_kit_request_id and deactivated_date is null and ddp_instance_id = ? group by ddp_participant_id ORDER BY RAND() LIMIT 1"; + private static final String SQL_SELECT_RANDOM_SUFFIX = " ORDER BY RAND() LIMIT 1"; + private static final Logger logger = LoggerFactory.getLogger(BSPDummyKitDao.class); public void updateKitLabel(String kitLabel, String dsmKitRequestId) { @@ -83,6 +87,30 @@ public Optional getRandomParticipantIdForStudy(String ddpInstanceId) { return Optional.ofNullable((String) results.resultValue); } + public String getRandomOncHistoryForStudy(String ddpInstanceName) { + SimpleResult results = inTransaction((conn) -> { + SimpleResult dbVals = new SimpleResult(); + try (PreparedStatement stmt = conn.prepareStatement(DBUtil.getFinalQuery(OncHistoryDetail.SQL_SELECT_ONC_HISTORY_DETAIL + " AND oD.accession_number is not null ", SQL_SELECT_RANDOM_SUFFIX))) { + stmt.setString(1, ddpInstanceName); + ResultSet rs = stmt.executeQuery(); + if (rs.next()) { + dbVals.resultValue = rs.getString(DBConstants.ONC_HISTORY_DETAIL_ID); + }else{ + throw new RuntimeException("Couldn't find a valid random onc history with accession number in realm "+ddpInstanceName); + + } + } + catch (SQLException e) { + dbVals.resultException = e; + } + return dbVals; + }); + if (results.resultException != null) { + throw new RuntimeException("Problem getting a random participant id for instance " + ddpInstanceName, results.resultException); + } + return (String)results.resultValue; + } + @Override public int create(ClinicalKitDto clinicalKitDto) { return 0; diff --git a/src/main/java/org/broadinstitute/dsm/db/dao/kit/BSPKitDao.java b/src/main/java/org/broadinstitute/dsm/db/dao/kit/BSPKitDao.java index 2f45613c9..051ffd08e 100644 --- a/src/main/java/org/broadinstitute/dsm/db/dao/kit/BSPKitDao.java +++ b/src/main/java/org/broadinstitute/dsm/db/dao/kit/BSPKitDao.java @@ -5,7 +5,7 @@ import org.broadinstitute.ddp.db.TransactionWrapper; import org.broadinstitute.dsm.db.dao.Dao; import org.broadinstitute.dsm.db.dto.kit.BSPKitDto; -import org.broadinstitute.dsm.model.BSPKit; +import org.broadinstitute.dsm.model.gp.BSPKit; import org.broadinstitute.dsm.statics.DBConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/broadinstitute/dsm/db/dao/kit/ClinicalKitDao.java b/src/main/java/org/broadinstitute/dsm/db/dao/kit/ClinicalKitDao.java new file mode 100644 index 000000000..7ff6bd7d9 --- /dev/null +++ b/src/main/java/org/broadinstitute/dsm/db/dao/kit/ClinicalKitDao.java @@ -0,0 +1,91 @@ +package org.broadinstitute.dsm.db.dao.kit; + +import org.apache.commons.lang3.StringUtils; +import org.broadinstitute.ddp.db.SimpleResult; +import org.broadinstitute.dsm.db.DDPInstance; +import org.broadinstitute.dsm.db.dto.kit.ClinicalKitDto; +import org.broadinstitute.dsm.model.gp.ClinicalKitWrapper; +import org.broadinstitute.dsm.statics.DBConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Optional; + +import static org.broadinstitute.ddp.db.TransactionWrapper.inTransaction; + +public class ClinicalKitDao { + private static final Logger logger = LoggerFactory.getLogger(ClinicalKitDao.class); + private final static String SQL_GET_CLINICAL_KIT_BASED_ON_SM_ID_VALUE = "SELECT p.ddp_participant_id, accession_number, ddp.instance_name, bsp_organism, bsp_collection, " + + "kit_type_name, bsp_material_type, bsp_receptacle_type, ddp.ddp_instance_id " + + "FROM sm_id sm " + + "LEFT JOIN ddp_tissue t on (t.tissue_id = sm.tissue_id) " + + "LEFT JOIN ddp_onc_history_detail oD on (oD.onc_history_detail_id = t.onc_history_detail_id) " + + "LEFT JOIN ddp_medical_record mr on (mr.medical_record_id = oD.medical_record_id) " + + "LEFT JOIN ddp_institution inst on (mr.institution_id = inst.institution_id AND NOT mr.deleted <=> 1) " + + "LEFT JOIN ddp_participant as p on (p.participant_id = inst.participant_id) " + + "LEFT JOIN ddp_instance as ddp on (ddp.ddp_instance_id = p.ddp_instance_id) " + + "LEFT JOIN sm_id_type sit on (sit.sm_id_type_id = sm.sm_id_type_id) " + + "LEFT JOIN kit_type ktype on ( sit.kit_type_id = ktype.kit_type_id) " + + "WHERE sm.sm_id_value = ? "; + + public Optional getClinicalKitFromSMId(String smIdValue) { + SimpleResult results = inTransaction((conn) -> { + SimpleResult dbVals = new SimpleResult(); + try (PreparedStatement stmt = conn.prepareStatement(SQL_GET_CLINICAL_KIT_BASED_ON_SM_ID_VALUE)) { + stmt.setString(1, smIdValue); + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + ClinicalKitDto clinicalKitDto = new ClinicalKitDto( + null, + rs.getString(DBConstants.BSP_COLLECTION), + rs.getString(DBConstants.BSP_ORGANISM), + rs.getString(DBConstants.BSP_MATERIAL_TYPE), + rs.getString(DBConstants.BSP_RECEPTABLE_TYPE), + null, + null, + null, + null, + null, + rs.getString(DBConstants.ACCESSION_NUMBER), + null + ); + clinicalKitDto.setSampleType(rs.getString(DBConstants.KIT_TYPE_NAME)); + ClinicalKitWrapper clinicalKitWrapper = new ClinicalKitWrapper(clinicalKitDto, + Integer.parseInt(rs.getString(DBConstants.DDP_INSTANCE_ID)), + rs.getString(DBConstants.DDP_PARTICIPANT_ID)); + dbVals.resultValue = clinicalKitWrapper; + logger.info("found clinical kit for sm id value: " + smIdValue); + } + } catch (Exception e) { + throw new RuntimeException("Error getting clinical kit", e); + } + } catch (SQLException ex) { + dbVals.resultException = ex; + } + + return dbVals; + }); + + if (results.resultException != null) { + throw new RuntimeException("Error getting clinicalKit based on smId " + smIdValue, results.resultException); + } + return Optional.ofNullable((ClinicalKitWrapper) results.resultValue); + } + + public ClinicalKitDto getClinicalKitBasedOnSmId(String smIdValue) { + logger.info("Checking the kit for SM Id value " + smIdValue); + Optional maybeClinicalKitWrapper = getClinicalKitFromSMId(smIdValue); + maybeClinicalKitWrapper.orElseThrow(); + ClinicalKitWrapper clinicalKitWrapper = maybeClinicalKitWrapper.get(); + ClinicalKitDto clinicalKitDto = clinicalKitWrapper.getClinicalKitDto(); + DDPInstance ddpInstance = DDPInstance.getDDPInstanceById(clinicalKitWrapper.getDdpInstanceId()); + clinicalKitDto.setNecessaryParticipantDataToClinicalKit(clinicalKitWrapper.getDdpParticipantId(), ddpInstance); + if (StringUtils.isNotBlank(clinicalKitDto.getAccessionNumber())) { + return clinicalKitDto; + } + throw new RuntimeException("The kit doesn't have an accession number! SM ID is: " + smIdValue); + } +} diff --git a/src/main/java/org/broadinstitute/dsm/db/dto/kit/ClinicalKitDto.java b/src/main/java/org/broadinstitute/dsm/db/dto/kit/ClinicalKitDto.java index 3a44ca124..aee7f8bee 100644 --- a/src/main/java/org/broadinstitute/dsm/db/dto/kit/ClinicalKitDto.java +++ b/src/main/java/org/broadinstitute/dsm/db/dto/kit/ClinicalKitDto.java @@ -2,32 +2,49 @@ import com.google.gson.annotations.SerializedName; import lombok.Data; +import org.apache.commons.lang3.StringUtils; +import org.broadinstitute.dsm.db.DDPInstance; +import org.broadinstitute.dsm.db.KitRequestShipping; +import org.broadinstitute.dsm.db.OncHistoryDetail; +import org.broadinstitute.dsm.model.ddp.DDPActivityConstants; +import org.broadinstitute.dsm.model.elastic.ESActivities; +import org.broadinstitute.dsm.model.elastic.ESDsm; +import org.broadinstitute.dsm.model.elastic.ESProfile; +import org.broadinstitute.dsm.model.elastic.search.ElasticSearchParticipantDto; +import org.broadinstitute.dsm.util.ElasticSearchUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; @Data public class ClinicalKitDto { - @SerializedName ("participant_id") + @SerializedName("participant_id") String collaboratorParticipantId; - @SerializedName ("sample_id") + @SerializedName("sample_id") String sampleId; - @SerializedName ("sample_collection") + @SerializedName("sample_collection") String sampleCollection; - @SerializedName ("material_type") + @SerializedName("material_type") String materialType; - @SerializedName ("vessel_type") + @SerializedName("vessel_type") String vesselType; - @SerializedName ("first_name") + @SerializedName("first_name") String firstName; - @SerializedName ("last_name") + @SerializedName("last_name") String lastName; - @SerializedName ("date_of_birth") + @SerializedName("date_of_birth") String dateOfBirth; @SerializedName("sample_type") @@ -45,10 +62,29 @@ public class ClinicalKitDto { @SerializedName("kit_label") String mfBarcode; - public ClinicalKitDto(){} + private static final Logger logger = LoggerFactory.getLogger(ClinicalKitDto.class); + + public ClinicalKitDto(String collaboratorParticipantId, String sampleId, String sampleCollection, String materialType, String vesselType, + String firstName, String lastName, String dateOfBirth, String sampleType, String gender, String accessionNumber, String mfBarcode) { + this.collaboratorParticipantId = collaboratorParticipantId; + this.sampleId = sampleId; + this.sampleCollection = sampleCollection; + this.materialType = materialType; + this.vesselType = vesselType; + this.firstName = firstName; + this.lastName = lastName; + this.dateOfBirth = dateOfBirth; + this.sampleType = sampleType; + this.gender = gender; + this.accessionNumber = accessionNumber; + this.mfBarcode = mfBarcode; + } + + public ClinicalKitDto() { + } - public void setSampleType(String kitType){ - switch (kitType.toLowerCase()){ + public void setSampleType(String kitType) { + switch (kitType.toLowerCase()) { case "saliva": this.sampleType = "Normal"; break; @@ -61,8 +97,8 @@ public void setSampleType(String kitType){ } } - public void setGender(String genderString){ - switch (genderString.toLowerCase()){ + public void setGender(String genderString) { + switch (genderString.toLowerCase()) { case "male": this.gender = "M"; break; @@ -75,4 +111,54 @@ public void setGender(String genderString){ } } + public void setNecessaryParticipantDataToClinicalKit(String ddpParticipantId, DDPInstance ddpInstance) { + Optional maybeParticipantESDataByParticipantId = + ElasticSearchUtil.getParticipantESDataByParticipantId(ddpInstance.getParticipantIndexES(), ddpParticipantId); + if (maybeParticipantESDataByParticipantId.isEmpty()) { + throw new RuntimeException("Participant ES Data is not found for " + ddpParticipantId); + } + + try { + this.setDateOfBirth(maybeParticipantESDataByParticipantId.get().getDsm().map(ESDsm::getDateOfBirth).orElse("")); + this.setFirstName(maybeParticipantESDataByParticipantId.get().getProfile().map(ESProfile::getFirstName).orElse("")); + this.setLastName(maybeParticipantESDataByParticipantId.get().getProfile().map(ESProfile::getLastName).orElse("")); + this.setGender(getParticipantGender(maybeParticipantESDataByParticipantId.get(), ddpInstance.getName())); + String shortId = maybeParticipantESDataByParticipantId.get().getProfile().map(ESProfile::getHruid).orElse(""); + String collaboratorParticipantId = KitRequestShipping.getCollaboratorParticipantId(ddpInstance.getBaseUrl(), ddpInstance.getDdpInstanceId(), ddpInstance.isMigratedDDP(), + ddpInstance.getCollaboratorIdPrefix(), ddpParticipantId, shortId, null); + this.setCollaboratorParticipantId(collaboratorParticipantId); + } catch (Exception e) { + throw new RuntimeException("Participant doesn't exist / is not valid for kit " + e.getMessage()); + } + } + + private String getParticipantGender(ElasticSearchParticipantDto participantByShortId, String realm) { + // if gender is set on tissue page use that + List list = new ArrayList(); + list.add(participantByShortId.getParticipantId()); + Map> oncHistoryDetails = OncHistoryDetail.getOncHistoryDetailsByParticipantIds(realm, list); + if (!oncHistoryDetails.isEmpty()) { + Optional oncHistoryWithGender = oncHistoryDetails.get(participantByShortId.getParticipantId()).stream().filter(o -> StringUtils.isNotBlank(o.getGender())).findFirst(); + if (oncHistoryWithGender.isPresent()) { + return oncHistoryWithGender.get().getGender(); + } + } + //if gender is not set on tissue page get answer from "ABOUT_YOU.ASSIGNED_SEX" + return getGenderFromActivities(participantByShortId.getActivities()); + } + + private String getGenderFromActivities(List activities) { + Optional maybeAboutYouActivity = activities.stream() + .filter(activity -> DDPActivityConstants.ACTIVITY_ABOUT_YOU.equals(activity.getActivityCode())) + .findFirst(); + return (String) maybeAboutYouActivity.map(aboutYou -> { + List> questionsAnswers = aboutYou.getQuestionsAnswers(); + Optional> maybeGenderQuestionAnswer = questionsAnswers.stream() + .filter(q -> DDPActivityConstants.ABOUT_YOU_ACTIVITY_GENDER.equals(q.get(DDPActivityConstants.DDP_ACTIVITY_STABLE_ID))) + .findFirst(); + return maybeGenderQuestionAnswer + .map(answer -> answer.get(DDPActivityConstants.ACTIVITY_QUESTION_ANSWER)) + .orElse("U"); + }).orElse("U"); + } } diff --git a/src/main/java/org/broadinstitute/dsm/model/BSPKit.java b/src/main/java/org/broadinstitute/dsm/model/BSPKit.java deleted file mode 100644 index 0bfc9a09a..000000000 --- a/src/main/java/org/broadinstitute/dsm/model/BSPKit.java +++ /dev/null @@ -1,182 +0,0 @@ -package org.broadinstitute.dsm.model; - -import lombok.NonNull; -import org.apache.commons.lang3.StringUtils; -import org.broadinstitute.ddp.db.TransactionWrapper; -import org.broadinstitute.dsm.db.DDPInstance; -import org.broadinstitute.dsm.db.InstanceSettings; -import org.broadinstitute.dsm.db.KitRequestShipping; -import org.broadinstitute.dsm.db.dao.ddp.instance.DDPInstanceDao; -import org.broadinstitute.dsm.db.dao.ddp.kitrequest.KitRequestDao; -import org.broadinstitute.dsm.db.dao.kit.BSPKitDao; -import org.broadinstitute.dsm.db.dto.ddp.instance.DDPInstanceDto; -import org.broadinstitute.dsm.db.dto.kit.BSPKitDto; -import org.broadinstitute.dsm.db.dto.settings.InstanceSettingsDto; -import org.broadinstitute.dsm.model.bsp.BSPKitInfo; -import org.broadinstitute.dsm.model.bsp.BSPKitStatus; -import org.broadinstitute.dsm.model.elastic.export.painless.UpsertPainlessFacade; -import org.broadinstitute.dsm.statics.ApplicationConfigConstants; -import org.broadinstitute.dsm.statics.DBConstants; -import org.broadinstitute.dsm.statics.ESObjectConstants; -import org.broadinstitute.dsm.util.ElasticSearchDataUtil; -import org.broadinstitute.dsm.util.ElasticSearchUtil; -import org.broadinstitute.dsm.util.EventUtil; -import org.broadinstitute.dsm.util.NotificationUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.sql.Connection; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -public class BSPKit { - private static Logger logger = LoggerFactory.getLogger(BSPKit.class); - - public Optional getKitStatus(@NonNull String kitLabel, NotificationUtil notificationUtil) { - logger.info("Checking label " + kitLabel); - BSPKitDao bspKitDao = new BSPKitDao(); - Optional bspKitQueryResult = bspKitDao.getBSPKitQueryResult(kitLabel); - Optional result = Optional.empty(); - if (bspKitQueryResult.isEmpty()) { - logger.info("No kit w/ label " + kitLabel + " found"); - } - else { - BSPKitDto maybeBspKitQueryResult = bspKitQueryResult.get(); - if (StringUtils.isNotBlank(maybeBspKitQueryResult.getParticipantExitId())) { - String message = "Kit of exited participant " + maybeBspKitQueryResult.getBspParticipantId() + " was received by GP.
"; - notificationUtil.sentNotification(maybeBspKitQueryResult.getNotificationRecipient(), message, NotificationUtil.DSM_SUBJECT); - result = Optional.of(new BSPKitStatus(BSPKitStatus.EXITED)); - } - else if (StringUtils.isNotBlank(maybeBspKitQueryResult.getDeactivationDate())) { - result = Optional.of(new BSPKitStatus(BSPKitStatus.DEACTIVATED)); - } - } - return result; - } - - public boolean canReceiveKit(@NonNull String kitLabel) { - BSPKitDao bspKitDao = new BSPKitDao(); - Optional bspKitQueryResult = bspKitDao.getBSPKitQueryResult(kitLabel); - if (bspKitQueryResult.isEmpty()) { - logger.info("No kit w/ label " + kitLabel + " found"); - return false; - } - else { - BSPKitDto maybeBspKitQueryResult = bspKitQueryResult.get(); - if (StringUtils.isNotBlank(maybeBspKitQueryResult.getParticipantExitId()) || StringUtils.isNotBlank(maybeBspKitQueryResult.getDeactivationDate())) { - logger.info("Kit can not be received."); - return false; - } - } - return true; - } - - public Optional receiveBSPKit(String kitLabel, NotificationUtil notificationUtil) { - logger.info("Trying to receive kit " + kitLabel); - BSPKitDao bspKitDao = new BSPKitDao(); - Optional bspKitQueryResult = bspKitDao.getBSPKitQueryResult(kitLabel); - if (bspKitQueryResult.isEmpty()) { - logger.warn("returning empty object for "+kitLabel); - return Optional.empty(); - } - BSPKitDto maybeBspKitQueryResult = bspKitQueryResult.get(); - if (StringUtils.isBlank(maybeBspKitQueryResult.getDdpParticipantId())) { - throw new RuntimeException("No participant id for " + kitLabel + " from " + maybeBspKitQueryResult.getInstanceName()); - } - logger.info("participant id is " + maybeBspKitQueryResult.getDdpParticipantId()); - DDPInstance ddpInstance = DDPInstance.getDDPInstance(maybeBspKitQueryResult.getInstanceName()); - InstanceSettings instanceSettings = new InstanceSettings(); - InstanceSettingsDto instanceSettingsDto = instanceSettings.getInstanceSettings(maybeBspKitQueryResult.getInstanceName()); - instanceSettingsDto.getKitBehaviorChange() - .flatMap(kitBehavior -> kitBehavior.stream().filter(o -> o.getName().equals(InstanceSettings.INSTANCE_SETTING_RECEIVED)).findFirst()) - .ifPresentOrElse(received -> { - Map> participants = ElasticSearchUtil.getFilteredDDPParticipantsFromES(ddpInstance, - ElasticSearchUtil.BY_GUID + maybeBspKitQueryResult.getDdpParticipantId()); - writeSampleReceivedToES(ddpInstance, maybeBspKitQueryResult); - Map participant = participants.get(maybeBspKitQueryResult.getDdpParticipantId()); - if (participant != null) { - boolean triggerDDP = true; - boolean specialBehavior = InstanceSettings.shouldKitBehaveDifferently(participant, received); - if (specialBehavior) { - //don't trigger ddp to sent out email, only email to study staff - triggerDDP = false; - if (InstanceSettings.TYPE_NOTIFICATION.equals(received.getType())) { - String message = "Kit of participant " + maybeBspKitQueryResult.getBspParticipantId() + " was received by GP.
" + - "CollaboratorSampleId: " + maybeBspKitQueryResult.getBspSampleId() + "
" + - received.getValue(); - notificationUtil.sentNotification(maybeBspKitQueryResult.getNotificationRecipient(), message, NotificationUtil.UNIVERSAL_NOTIFICATION_TEMPLATE, NotificationUtil.DSM_SUBJECT); - } - else { - logger.error("Instance settings behavior for kit was not known " + received.getType()); - } - } - updateKitAndExport(kitLabel, bspKitDao, maybeBspKitQueryResult, triggerDDP); - } - }, () -> { - updateKitAndExport(kitLabel, bspKitDao, maybeBspKitQueryResult, true); - }); - - String bspParticipantId = maybeBspKitQueryResult.getBspParticipantId(); - String bspSampleId = maybeBspKitQueryResult.getBspSampleId(); - String bspMaterialType = maybeBspKitQueryResult.getBspMaterialType(); - String bspReceptacleType = maybeBspKitQueryResult.getBspReceptacleType(); - int bspOrganism; - try { - bspOrganism = Integer.parseInt(maybeBspKitQueryResult.getBspOrganism()); - } - catch (NumberFormatException e) { - throw new RuntimeException("Organism " + maybeBspKitQueryResult.getBspOrganism() + " can't be parsed to integer", e); - } - - logger.info("Returning info for kit w/ label " + kitLabel + " for " + maybeBspKitQueryResult.getInstanceName()); - logger.info("Kit returned has sample id " + bspSampleId); - return Optional.of(new BSPKitInfo(maybeBspKitQueryResult.getBspCollection(), - bspOrganism, - "U", - bspParticipantId, - bspSampleId, - bspMaterialType, - bspReceptacleType, - ddpInstance.getName(), - maybeBspKitQueryResult.getKitTypeName())); - - } - - private void updateKitAndExport(String kitLabel, BSPKitDao bspKitDao, BSPKitDto maybeBspKitQueryResult, boolean triggerDDP) { - long receivedDate = System.currentTimeMillis(); - bspKitDao.setKitReceivedAndTriggerDDP(kitLabel, triggerDDP, maybeBspKitQueryResult); - - KitRequestShipping kitRequestShipping = new KitRequestShipping(); - kitRequestShipping.setReceiveDate(receivedDate); - kitRequestShipping.setKitLabel(kitLabel); - - DDPInstanceDto ddpInstanceDto = new DDPInstanceDao().getDDPInstanceByInstanceName(maybeBspKitQueryResult.getInstanceName()).orElseThrow(); - - UpsertPainlessFacade.of(DBConstants.DDP_KIT_REQUEST_ALIAS, kitRequestShipping, ddpInstanceDto, ESObjectConstants.KIT_LABEL - , ESObjectConstants.KIT_LABEL, kitLabel) - .export(); - } - - private void writeSampleReceivedToES(DDPInstance ddpInstance, BSPKitDto bspKitInfo) { - String kitRequestId = new KitRequestDao().getKitRequestIdByBSPParticipantId(bspKitInfo.getBspParticipantId()); - Map nameValuesMap = new HashMap<>(); - ElasticSearchDataUtil.setCurrentStrictYearMonthDay(nameValuesMap, ESObjectConstants.RECEIVED); - ElasticSearchUtil.writeSample(ddpInstance, kitRequestId, bspKitInfo.getDdpParticipantId(), ESObjectConstants.SAMPLES, - ESObjectConstants.KIT_REQUEST_ID, nameValuesMap); - } - - public void triggerDDP(Connection conn, @NonNull BSPKitDto bspKitInfo, boolean firstTimeReceived, String kitLabel) { - try { - if (bspKitInfo.isHasParticipantNotifications() && firstTimeReceived) { - KitDDPNotification kitDDPNotification = KitDDPNotification.getKitDDPNotification(TransactionWrapper.getSqlFromConfig(ApplicationConfigConstants.GET_RECEIVED_KIT_INFORMATION_FOR_NOTIFICATION_EMAIL), kitLabel, 1); - if (kitDDPNotification != null) { - EventUtil.triggerDDP(conn, kitDDPNotification); - } - } - } - catch (Exception e) { - logger.error("Failed doing DSM internal received things for kit w/ label " + kitLabel, e); - } - } -} diff --git a/src/main/java/org/broadinstitute/dsm/model/gp/BSPKit.java b/src/main/java/org/broadinstitute/dsm/model/gp/BSPKit.java new file mode 100644 index 000000000..034839b97 --- /dev/null +++ b/src/main/java/org/broadinstitute/dsm/model/gp/BSPKit.java @@ -0,0 +1,57 @@ +package org.broadinstitute.dsm.model.gp; + +import lombok.NonNull; +import org.apache.commons.lang3.StringUtils; +import org.broadinstitute.ddp.db.TransactionWrapper; +import org.broadinstitute.dsm.db.dao.kit.BSPKitDao; +import org.broadinstitute.dsm.db.dto.kit.BSPKitDto; +import org.broadinstitute.dsm.model.KitDDPNotification; +import org.broadinstitute.dsm.model.gp.bsp.BSPKitStatus; +import org.broadinstitute.dsm.statics.ApplicationConfigConstants; +import org.broadinstitute.dsm.util.EventUtil; +import org.broadinstitute.dsm.util.NotificationUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Connection; +import java.util.Optional; + +public class BSPKit extends GPReceivedKit { + + private static Logger logger = LoggerFactory.getLogger(BSPKit.class); + + public Optional getKitStatus(@NonNull BSPKitDto bspKitQueryResult, NotificationUtil notificationUtil) { + if (StringUtils.isNotBlank(bspKitQueryResult.getParticipantExitId())) { + String message = "Kit of exited participant " + bspKitQueryResult.getBspParticipantId() + " was received by GP.
"; + notificationUtil.sentNotification(bspKitQueryResult.getNotificationRecipient(), message, NotificationUtil.DSM_SUBJECT); + return Optional.of(new BSPKitStatus(BSPKitStatus.EXITED)); + } else if (StringUtils.isNotBlank(bspKitQueryResult.getDeactivationDate())) { + return Optional.of(new BSPKitStatus(BSPKitStatus.DEACTIVATED)); + } + return Optional.empty(); + } + + public Optional canReceiveKit(@NonNull String kitLabel) { + BSPKitDao bspKitDao = new BSPKitDao(); + Optional bspKitQueryResult = bspKitDao.getBSPKitQueryResult(kitLabel); + if (bspKitQueryResult.isEmpty()) { + logger.info("No kit w/ label " + kitLabel + " found"); + return Optional.empty(); + } else { + return bspKitQueryResult; + } + } + + public void triggerDDP(Connection conn, @NonNull BSPKitDto bspKitInfo, boolean firstTimeReceived, String kitLabel) { + try { + if (bspKitInfo.isHasParticipantNotifications() && firstTimeReceived) { + KitDDPNotification kitDDPNotification = KitDDPNotification.getKitDDPNotification(TransactionWrapper.getSqlFromConfig(ApplicationConfigConstants.GET_RECEIVED_KIT_INFORMATION_FOR_NOTIFICATION_EMAIL), kitLabel, 1); + if (kitDDPNotification != null) { + EventUtil.triggerDDP(conn, kitDDPNotification); + } + } + } catch (Exception e) { + logger.error("Failed doing DSM internal received things for kit w/ label " + kitLabel, e); + } + } +} diff --git a/src/main/java/org/broadinstitute/dsm/model/gp/ClinicalKitWrapper.java b/src/main/java/org/broadinstitute/dsm/model/gp/ClinicalKitWrapper.java new file mode 100644 index 000000000..496eac8b0 --- /dev/null +++ b/src/main/java/org/broadinstitute/dsm/model/gp/ClinicalKitWrapper.java @@ -0,0 +1,17 @@ +package org.broadinstitute.dsm.model.gp; + +import lombok.Data; +import org.broadinstitute.dsm.db.dto.kit.ClinicalKitDto; + +@Data +public class ClinicalKitWrapper { + ClinicalKitDto clinicalKitDto; + Integer ddpInstanceId; + String ddpParticipantId; + + public ClinicalKitWrapper(ClinicalKitDto clinicalKitDto, int ddpInstanceId, String ddpParticipantId) { + this.clinicalKitDto = clinicalKitDto; + this.ddpInstanceId = ddpInstanceId; + this.ddpParticipantId = ddpParticipantId; + } +} diff --git a/src/main/java/org/broadinstitute/dsm/model/gp/GPReceivedKit.java b/src/main/java/org/broadinstitute/dsm/model/gp/GPReceivedKit.java new file mode 100644 index 000000000..2c7948387 --- /dev/null +++ b/src/main/java/org/broadinstitute/dsm/model/gp/GPReceivedKit.java @@ -0,0 +1,110 @@ +package org.broadinstitute.dsm.model.gp; + +import org.broadinstitute.dsm.db.DDPInstance; +import org.broadinstitute.dsm.db.InstanceSettings; +import org.broadinstitute.dsm.db.KitRequestShipping; +import org.broadinstitute.dsm.db.dao.ddp.instance.DDPInstanceDao; +import org.broadinstitute.dsm.db.dao.ddp.kitrequest.KitRequestDao; +import org.broadinstitute.dsm.db.dao.kit.BSPKitDao; +import org.broadinstitute.dsm.db.dto.ddp.instance.DDPInstanceDto; +import org.broadinstitute.dsm.db.dto.kit.BSPKitDto; +import org.broadinstitute.dsm.db.dto.settings.InstanceSettingsDto; +import org.broadinstitute.dsm.model.elastic.export.painless.UpsertPainlessFacade; +import org.broadinstitute.dsm.statics.DBConstants; +import org.broadinstitute.dsm.statics.ESObjectConstants; +import org.broadinstitute.dsm.util.ElasticSearchDataUtil; +import org.broadinstitute.dsm.util.ElasticSearchUtil; +import org.broadinstitute.dsm.util.NotificationUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public class GPReceivedKit { + + private static Logger logger = LoggerFactory.getLogger(BSPKit.class); + + public static Optional receiveKit(String kitLabel, BSPKitDto bspKitQueryResult, NotificationUtil notificationUtil) { + logger.info("participant id is " + bspKitQueryResult.getDdpParticipantId()); + DDPInstance ddpInstance = DDPInstance.getDDPInstance(bspKitQueryResult.getInstanceName()); + InstanceSettings instanceSettings = new InstanceSettings(); + BSPKitDao bspKitDao = new BSPKitDao(); + InstanceSettingsDto instanceSettingsDto = instanceSettings.getInstanceSettings(bspKitQueryResult.getInstanceName()); + instanceSettingsDto.getKitBehaviorChange() + .flatMap(kitBehavior -> kitBehavior.stream().filter(o -> o.getName().equals(InstanceSettings.INSTANCE_SETTING_RECEIVED)).findFirst()) + .ifPresentOrElse(received -> { + Map> participants = ElasticSearchUtil.getFilteredDDPParticipantsFromES(ddpInstance, + ElasticSearchUtil.BY_GUID + bspKitQueryResult.getDdpParticipantId()); + writeSampleReceivedToES(ddpInstance, bspKitQueryResult); + Map participant = participants.get(bspKitQueryResult.getDdpParticipantId()); + if (participant != null) { + boolean triggerDDP = true; + boolean specialBehavior = InstanceSettings.shouldKitBehaveDifferently(participant, received); + if (specialBehavior) { + //don't trigger ddp to sent out email, only email to study staff + triggerDDP = false; + if (InstanceSettings.TYPE_NOTIFICATION.equals(received.getType())) { + String message = "Kit of participant " + bspKitQueryResult.getBspParticipantId() + " was received by GP.
" + + "CollaboratorSampleId: " + bspKitQueryResult.getBspSampleId() + "
" + + received.getValue(); + notificationUtil.sentNotification(bspKitQueryResult.getNotificationRecipient(), message, NotificationUtil.UNIVERSAL_NOTIFICATION_TEMPLATE, NotificationUtil.DSM_SUBJECT); + } else { + logger.error("Instance settings behavior for kit was not known " + received.getType()); + } + } + updateKitAndExport(kitLabel, bspKitDao, bspKitQueryResult, triggerDDP); + } + }, () -> { + updateKitAndExport(kitLabel, bspKitDao, bspKitQueryResult, true); + }); + + String bspParticipantId = bspKitQueryResult.getBspParticipantId(); + String bspSampleId = bspKitQueryResult.getBspSampleId(); + String bspMaterialType = bspKitQueryResult.getBspMaterialType(); + String bspReceptacleType = bspKitQueryResult.getBspReceptacleType(); + int bspOrganism; + try { + bspOrganism = Integer.parseInt(bspKitQueryResult.getBspOrganism()); + } catch (NumberFormatException e) { + throw new RuntimeException("Organism " + bspKitQueryResult.getBspOrganism() + " can't be parsed to integer", e); + } + + logger.info("Returning info for kit w/ label " + kitLabel + " for " + bspKitQueryResult.getInstanceName()); + logger.info("Kit returned has sample id " + bspSampleId); + return Optional.of(new KitInfo(bspKitQueryResult.getBspCollection(), + bspOrganism, + "U", + bspParticipantId, + bspSampleId, + bspMaterialType, + bspReceptacleType, + ddpInstance.getName(), + bspKitQueryResult.getKitTypeName())); + + } + + private static void updateKitAndExport(String kitLabel, BSPKitDao bspKitDao, BSPKitDto maybeBspKitQueryResult, boolean triggerDDP) { + long receivedDate = System.currentTimeMillis(); + bspKitDao.setKitReceivedAndTriggerDDP(kitLabel, triggerDDP, maybeBspKitQueryResult); + + KitRequestShipping kitRequestShipping = new KitRequestShipping(); + kitRequestShipping.setReceiveDate(receivedDate); + kitRequestShipping.setKitLabel(kitLabel); + + DDPInstanceDto ddpInstanceDto = new DDPInstanceDao().getDDPInstanceByInstanceName(maybeBspKitQueryResult.getInstanceName()).orElseThrow(); + + UpsertPainlessFacade.of(DBConstants.DDP_KIT_REQUEST_ALIAS, kitRequestShipping, ddpInstanceDto, ESObjectConstants.KIT_LABEL, + ESObjectConstants.KIT_LABEL, kitLabel) + .export(); + } + + private static void writeSampleReceivedToES(DDPInstance ddpInstance, BSPKitDto bspKitInfo) { + String kitRequestId = new KitRequestDao().getKitRequestIdByBSPParticipantId(bspKitInfo.getBspParticipantId()); + Map nameValuesMap = new HashMap<>(); + ElasticSearchDataUtil.setCurrentStrictYearMonthDay(nameValuesMap, ESObjectConstants.RECEIVED); + ElasticSearchUtil.writeSample(ddpInstance, kitRequestId, bspKitInfo.getDdpParticipantId(), ESObjectConstants.SAMPLES, + ESObjectConstants.KIT_REQUEST_ID, nameValuesMap); + } +} diff --git a/src/main/java/org/broadinstitute/dsm/model/bsp/BSPKitInfo.java b/src/main/java/org/broadinstitute/dsm/model/gp/KitInfo.java similarity index 65% rename from src/main/java/org/broadinstitute/dsm/model/bsp/BSPKitInfo.java rename to src/main/java/org/broadinstitute/dsm/model/gp/KitInfo.java index 7a11bd2ca..8e11151c7 100644 --- a/src/main/java/org/broadinstitute/dsm/model/bsp/BSPKitInfo.java +++ b/src/main/java/org/broadinstitute/dsm/model/gp/KitInfo.java @@ -1,27 +1,27 @@ -package org.broadinstitute.dsm.model.bsp; +package org.broadinstitute.dsm.model.gp; import lombok.Getter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Getter -public class BSPKitInfo { +public class KitInfo { - private static final Logger logger = LoggerFactory.getLogger(BSPKitInfo.class); + private static final Logger logger = LoggerFactory.getLogger(KitInfo.class); private String collaboratorParticipantId, collaboratorSampleId, sampleCollectionBarcode, gender, materialInfo, receptacleName, - accessionNumber, realm, kitTypeName; + accessionNumber, realm, kitTypeName; private final int organismClassificationId; - public BSPKitInfo(String sampleCollectionBarcode, - int organismClassificationId, - String gender, - String bspParticipantId, - String bspSampleId, - String materialInfo, - String receptacleName, - String realm, - String kitTypeName) { + public KitInfo(String sampleCollectionBarcode, + int organismClassificationId, + String gender, + String bspParticipantId, + String bspSampleId, + String materialInfo, + String receptacleName, + String realm, + String kitTypeName) { this.sampleCollectionBarcode = sampleCollectionBarcode; // note that organism is bsp's internal organismClassificationId, as per Damien this.organismClassificationId = organismClassificationId; diff --git a/src/main/java/org/broadinstitute/dsm/model/bsp/BSPKitRegistration.java b/src/main/java/org/broadinstitute/dsm/model/gp/bsp/BSPKitRegistration.java similarity index 83% rename from src/main/java/org/broadinstitute/dsm/model/bsp/BSPKitRegistration.java rename to src/main/java/org/broadinstitute/dsm/model/gp/bsp/BSPKitRegistration.java index 2218b4e55..e5b49a045 100644 --- a/src/main/java/org/broadinstitute/dsm/model/bsp/BSPKitRegistration.java +++ b/src/main/java/org/broadinstitute/dsm/model/gp/bsp/BSPKitRegistration.java @@ -1,4 +1,4 @@ -package org.broadinstitute.dsm.model.bsp; +package org.broadinstitute.dsm.model.gp.bsp; import lombok.Data; diff --git a/src/main/java/org/broadinstitute/dsm/model/bsp/BSPKitStatus.java b/src/main/java/org/broadinstitute/dsm/model/gp/bsp/BSPKitStatus.java similarity index 86% rename from src/main/java/org/broadinstitute/dsm/model/bsp/BSPKitStatus.java rename to src/main/java/org/broadinstitute/dsm/model/gp/bsp/BSPKitStatus.java index 94a43de9b..364a51039 100644 --- a/src/main/java/org/broadinstitute/dsm/model/bsp/BSPKitStatus.java +++ b/src/main/java/org/broadinstitute/dsm/model/gp/bsp/BSPKitStatus.java @@ -1,4 +1,4 @@ -package org.broadinstitute.dsm.model.bsp; +package org.broadinstitute.dsm.model.gp.bsp; import lombok.Getter; diff --git a/src/main/java/org/broadinstitute/dsm/route/BSPKitRegisteredRoute.java b/src/main/java/org/broadinstitute/dsm/route/BSPKitRegisteredRoute.java index c59813e4d..9ea001b3e 100644 --- a/src/main/java/org/broadinstitute/dsm/route/BSPKitRegisteredRoute.java +++ b/src/main/java/org/broadinstitute/dsm/route/BSPKitRegisteredRoute.java @@ -2,7 +2,7 @@ import com.google.gson.Gson; import org.broadinstitute.ddp.db.SimpleResult; -import org.broadinstitute.dsm.model.bsp.BSPKitRegistration; +import org.broadinstitute.dsm.model.gp.bsp.BSPKitRegistration; import org.broadinstitute.dsm.statics.DBConstants; import spark.Request; import spark.Response; diff --git a/src/main/java/org/broadinstitute/dsm/route/BSPKitRoute.java b/src/main/java/org/broadinstitute/dsm/route/BSPKitRoute.java index ca2e5735e..ac7804f01 100644 --- a/src/main/java/org/broadinstitute/dsm/route/BSPKitRoute.java +++ b/src/main/java/org/broadinstitute/dsm/route/BSPKitRoute.java @@ -2,8 +2,9 @@ import lombok.NonNull; import org.apache.commons.lang3.StringUtils; -import org.broadinstitute.dsm.model.BSPKit; -import org.broadinstitute.dsm.model.bsp.BSPKitStatus; +import org.broadinstitute.dsm.db.dto.kit.BSPKitDto; +import org.broadinstitute.dsm.model.gp.BSPKit; +import org.broadinstitute.dsm.model.gp.bsp.BSPKitStatus; import org.broadinstitute.dsm.statics.RequestParameter; import org.broadinstitute.dsm.util.NotificationUtil; import spark.Request; @@ -26,17 +27,22 @@ public Object handle(Request request, Response response) { if (StringUtils.isBlank(kitLabel)) { throw new RuntimeException("Please include a kit label as a path parameter"); } + BSPKit bspKit = new BSPKit(); - if (!bspKit.canReceiveKit(kitLabel)) { - Optional result = bspKit.getKitStatus(kitLabel, notificationUtil); - if(result.isEmpty()){ - response.status(404); - return null; - } - return result.get(); + Optional optionalBSPKitDto = bspKit.canReceiveKit(kitLabel); + //kit does not exist in ddp_kit table + if (optionalBSPKitDto.isEmpty()) { + response.status(404); + return null; } - return bspKit.receiveBSPKit(kitLabel, this.notificationUtil).get(); + //check if kit is from a pt which is withdrawn + Optional result = bspKit.getKitStatus(optionalBSPKitDto.get(), notificationUtil); + if (!result.isEmpty()) { + return result.get(); + } + //kit found in ddp_kit table + return bspKit.receiveKit(kitLabel, optionalBSPKitDto.get(), this.notificationUtil).get(); } } diff --git a/src/main/java/org/broadinstitute/dsm/route/ClinicalKitsRoute.java b/src/main/java/org/broadinstitute/dsm/route/ClinicalKitsRoute.java index fef5f0fa9..5171ee8a3 100644 --- a/src/main/java/org/broadinstitute/dsm/route/ClinicalKitsRoute.java +++ b/src/main/java/org/broadinstitute/dsm/route/ClinicalKitsRoute.java @@ -3,19 +3,13 @@ import lombok.NonNull; import org.apache.commons.lang3.StringUtils; import org.broadinstitute.dsm.db.DDPInstance; -import org.broadinstitute.dsm.db.OncHistoryDetail; -import org.broadinstitute.dsm.db.dao.kit.BSPKitDao; +import org.broadinstitute.dsm.db.dao.kit.ClinicalKitDao; import org.broadinstitute.dsm.db.dto.kit.BSPKitDto; import org.broadinstitute.dsm.db.dto.kit.ClinicalKitDto; -import org.broadinstitute.dsm.model.BSPKit; -import org.broadinstitute.dsm.model.bsp.BSPKitInfo; -import org.broadinstitute.dsm.model.bsp.BSPKitStatus; -import org.broadinstitute.dsm.model.ddp.DDPActivityConstants; -import org.broadinstitute.dsm.model.elastic.ESActivities; -import org.broadinstitute.dsm.model.elastic.ESDsm; -import org.broadinstitute.dsm.model.elastic.ESProfile; -import org.broadinstitute.dsm.model.elastic.search.ElasticSearch; -import org.broadinstitute.dsm.model.elastic.search.ElasticSearchParticipantDto; +import org.broadinstitute.dsm.model.gp.BSPKit; +import org.broadinstitute.dsm.model.gp.GPReceivedKit; +import org.broadinstitute.dsm.model.gp.KitInfo; +import org.broadinstitute.dsm.model.gp.bsp.BSPKitStatus; import org.broadinstitute.dsm.statics.RequestParameter; import org.broadinstitute.dsm.util.NotificationUtil; import org.slf4j.Logger; @@ -24,7 +18,7 @@ import spark.Response; import spark.Route; -import java.util.*; +import java.util.Optional; public class ClinicalKitsRoute implements Route { private String FIRSTNAME = "firstName"; @@ -46,25 +40,28 @@ public Object handle(Request request, Response response) { throw new RuntimeException("Please include a kit label as a path parameter"); } BSPKit bspKit = new BSPKit(); - if (!bspKit.canReceiveKit(kitLabel)) { - Optional result = bspKit.getKitStatus(kitLabel, notificationUtil); - if(result.isEmpty()){ - response.status(404); - return null; + Optional optionalBSPKitDto = bspKit.canReceiveKit(kitLabel); + + //kit found in ddp_kit table + if (!optionalBSPKitDto.isEmpty()) { + //check if kit is from a pt which is withdrawn + Optional result = bspKit.getKitStatus(optionalBSPKitDto.get(), notificationUtil); + if (!result.isEmpty()) { + return result.get(); } - return result.get(); } - return getClinicalKit(kitLabel); + return getClinicalKit(kitLabel, optionalBSPKitDto); } - private ClinicalKitDto getClinicalKit(String kitLabel) { + private ClinicalKitDto getClinicalKit(String kitLabel, Optional optionalBSPKitDto) { logger.info("Checking label " + kitLabel); - BSPKitDao bspKitDao = new BSPKitDao(); - // this method already sets the received time, check for exited and deactivation and special behaviour, and triggers DDP, we don't need a new - BSPKit bspKit = new BSPKit(); - ClinicalKitDto clinicalKit = new ClinicalKitDto(); - Optional maybeKitInfo = bspKit.receiveBSPKit(kitLabel, notificationUtil); - maybeKitInfo.ifPresent(kitInfo -> { + if (optionalBSPKitDto.isEmpty()) { + //kit not found in ddp_kit table -> check tissue smi-ids + return new ClinicalKitDao().getClinicalKitBasedOnSmId(kitLabel); + } else { + Optional maybeKitInfo = GPReceivedKit.receiveKit(kitLabel, optionalBSPKitDto.get(), notificationUtil); + KitInfo kitInfo = maybeKitInfo.get(); + ClinicalKitDto clinicalKit = new ClinicalKitDto(); logger.info("Creating clinical kit to return to GP " + kitLabel); clinicalKit.setCollaboratorParticipantId(kitInfo.getCollaboratorParticipantId()); clinicalKit.setSampleId(kitInfo.getCollaboratorSampleId()); @@ -73,67 +70,10 @@ private ClinicalKitDto getClinicalKit(String kitLabel) { clinicalKit.setSampleType(kitInfo.getKitType()); clinicalKit.setMfBarcode(kitLabel); clinicalKit.setSampleCollection(kitInfo.getSampleCollectionBarcode()); - Optional bspKitQueryResult = bspKitDao.getBSPKitQueryResult(kitLabel); - bspKitQueryResult.orElseThrow(() -> {throw new RuntimeException("kit label was not found "+kitLabel);}); - BSPKitDto maybeBspKitQueryResult = bspKitQueryResult.get(); - DDPInstance ddpInstance = DDPInstance.getDDPInstance(maybeBspKitQueryResult.getInstanceName()); - String hruid = maybeBspKitQueryResult.getBspParticipantId(); - if (hruid.indexOf('_') != -1) { - hruid = maybeBspKitQueryResult.getBspParticipantId().substring(maybeBspKitQueryResult.getBspParticipantId().lastIndexOf('_') + 1); - } - ElasticSearchParticipantDto participantByShortId = - new ElasticSearch().getParticipantById(ddpInstance.getParticipantIndexES(), hruid); - setNecessaryParticipantDataToClinicalKit(clinicalKit, participantByShortId, kitInfo.getRealm()); - }); - maybeKitInfo.orElseThrow(); - return clinicalKit; - - } - - private void setNecessaryParticipantDataToClinicalKit(ClinicalKitDto clinicalKit, - ElasticSearchParticipantDto participantByShortId, String instanceName) { - try { - clinicalKit.setDateOfBirth(Objects.requireNonNull(participantByShortId).getDsm().map(ESDsm::getDateOfBirth).orElse("")); - String firstName = participantByShortId.getProfile().map(ESProfile::getFirstName).orElse(""); - String lastName = participantByShortId.getProfile().map(ESProfile::getLastName).orElse(""); - String gender = getParticipantGender(participantByShortId, instanceName); - clinicalKit.setFirstName(firstName); - clinicalKit.setLastName(lastName); - clinicalKit.setGender(gender); - } catch (Exception e) { - throw new RuntimeException("Participant doesn't exist / is not valid for kit "); + DDPInstance ddpInstance = DDPInstance.getDDPInstance(kitInfo.getRealm()); + clinicalKit.setNecessaryParticipantDataToClinicalKit(optionalBSPKitDto.get().getDdpParticipantId(), ddpInstance); + return clinicalKit; } } - private String getParticipantGender(ElasticSearchParticipantDto participantByShortId, String realm) { - // if gender is set on tissue page use that - List list = new ArrayList(); - list.add(participantByShortId.getParticipantId()); - Map> oncHistoryDetails = OncHistoryDetail.getOncHistoryDetailsByParticipantIds(realm, list); - if(!oncHistoryDetails.isEmpty()){ - Optional oncHistoryWithGender = oncHistoryDetails.get(participantByShortId.getParticipantId()).stream().filter(o -> StringUtils.isNotBlank(o.getGender())).findFirst(); - if(oncHistoryWithGender.isPresent()){ - return oncHistoryWithGender.get().getGender(); - } - } - //if gender is not set on tissue page get answer from "ABOUT_YOU.ASSIGNED_SEX" - return participantByShortId.getActivities().size() > 0 - ? getGenderFromActivities(participantByShortId.getActivities()) - : "U"; - } - - private String getGenderFromActivities(List activities) { - Optional maybeAboutYouActivity = activities.stream() - .filter(activity -> DDPActivityConstants.ACTIVITY_ABOUT_YOU.equals(activity.getActivityCode())) - .findFirst(); - return (String) maybeAboutYouActivity.map(aboutYou -> { - List> questionsAnswers = aboutYou.getQuestionsAnswers(); - Optional> maybeGenderQuestionAnswer = questionsAnswers.stream() - .filter(q -> DDPActivityConstants.ABOUT_YOU_ACTIVITY_GENDER.equals(q.get(DDPActivityConstants.DDP_ACTIVITY_STABLE_ID))) - .findFirst(); - return maybeGenderQuestionAnswer - .map(answer -> answer.get(DDPActivityConstants.ACTIVITY_QUESTION_ANSWER)) - .orElse(""); - }).orElse(""); - } } diff --git a/src/main/java/org/broadinstitute/dsm/route/CreateClinicalDummyKitRoute.java b/src/main/java/org/broadinstitute/dsm/route/CreateClinicalDummyKitRoute.java index 3c2a40a8d..22f827cd9 100644 --- a/src/main/java/org/broadinstitute/dsm/route/CreateClinicalDummyKitRoute.java +++ b/src/main/java/org/broadinstitute/dsm/route/CreateClinicalDummyKitRoute.java @@ -1,10 +1,9 @@ package org.broadinstitute.dsm.route; import org.apache.commons.lang3.StringUtils; -import org.broadinstitute.dsm.db.DDPInstance; -import org.broadinstitute.dsm.db.KitRequestShipping; -import org.broadinstitute.dsm.db.KitType; +import org.broadinstitute.dsm.db.*; import org.broadinstitute.dsm.db.dao.bookmark.BookmarkDao; +import org.broadinstitute.dsm.db.dao.ddp.tissue.TissueSMIDDao; import org.broadinstitute.dsm.db.dao.kit.BSPDummyKitDao; import org.broadinstitute.dsm.model.elastic.ESProfile; import org.broadinstitute.dsm.model.elastic.search.ElasticSearchParticipantDto; @@ -18,6 +17,7 @@ import java.util.List; import java.util.Optional; +import java.util.Random; public class CreateClinicalDummyKitRoute implements Route { private static final Logger logger = LoggerFactory.getLogger(CreateClinicalDummyKitRoute.class); @@ -25,6 +25,10 @@ public class CreateClinicalDummyKitRoute implements Route { private static String CLINICAL_KIT_PREFIX = "CLINICALKIT_"; private int REALM; private static final String USER_ID = "MERCURY"; + private final String FFPE_USER = "ffpe-dummy-kit-creator"; + private final String FFPE = "ffpe"; + private final String FFPE_SCROLL = "ffpe-scroll"; + private final String FFPE_SECTION = "ffpe-section"; @Override public Object handle(Request request, Response response) { @@ -35,13 +39,14 @@ public Object handle(Request request, Response response) { response.status(500); return "Please include a kit label as a path parameter"; } - logger.info("Got a new Clinical Kit request with kit label " + kitLabel+" and kit type "+kitTypeString); + logger.info("Got a new Clinical Kit request with kit label " + kitLabel + " and kit type " + kitTypeString); new BookmarkDao().getBookmarkByInstance(CLINICAL_KIT_REALM).ifPresentOrElse(book -> { REALM = (int) book.getValue(); }, () -> { throw new RuntimeException("Bookmark doesn't exist for " + CLINICAL_KIT_REALM); }); DDPInstance ddpInstance = DDPInstance.getDDPInstanceById(REALM); + BSPDummyKitDao bspDummyKitDao = new BSPDummyKitDao(); if (ddpInstance != null) { String kitRequestId = CLINICAL_KIT_PREFIX + KitRequestShipping.createRandom(20); String ddpParticipantId = new BSPDummyKitDao().getRandomParticipantForStudy(ddpInstance); @@ -49,20 +54,59 @@ public Object handle(Request request, Response response) { List kitTypes = KitType.getKitTypes(ddpInstance.getName(), null); KitType desiredKitType = kitTypes.stream().filter(k -> kitTypeString.equalsIgnoreCase(k.getName())).findFirst().orElseThrow(); logger.info("Found kit type " + desiredKitType.getName()); - maybeParticipantByParticipantId.ifPresentOrElse(p -> { + + if (maybeParticipantByParticipantId.isEmpty()) { + throw new RuntimeException("PT not found " + ddpParticipantId); + } + + if (kitTypeString.toLowerCase().indexOf(FFPE) == -1) { String participantCollaboratorId = KitRequestShipping.getCollaboratorParticipantId(ddpInstance.getBaseUrl(), ddpInstance.getDdpInstanceId(), ddpInstance.isMigratedDDP(), - ddpInstance.getCollaboratorIdPrefix(), ddpParticipantId, p.getProfile().map(ESProfile::getHruid).orElseThrow(), null); + ddpInstance.getCollaboratorIdPrefix(), ddpParticipantId, maybeParticipantByParticipantId.get().getProfile().map(ESProfile::getHruid).orElseThrow(), null); String collaboratorSampleId = KitRequestShipping.getCollaboratorSampleId(desiredKitType.getKitId(), participantCollaboratorId, desiredKitType.getName()); logger.info("Found collaboratorSampleId " + collaboratorSampleId); //if instance not null String dsmKitRequestId = KitRequestShipping.writeRequest(ddpInstance.getDdpInstanceId(), kitRequestId, desiredKitType.getKitId(), ddpParticipantId, participantCollaboratorId, collaboratorSampleId, USER_ID, "", "", "", false, "", ddpInstance); - new BSPDummyKitDao().updateKitLabel(kitLabel, dsmKitRequestId); + bspDummyKitDao.updateKitLabel(kitLabel, dsmKitRequestId); + } else { + String smIdType; + if (kitTypeString.equalsIgnoreCase(FFPE_SCROLL)) { + smIdType = TissueSmId.SCROLLS; + } else if (kitTypeString.equalsIgnoreCase(FFPE_SECTION)) { + smIdType = TissueSmId.USS; + } else { + throw new RuntimeException("The FFPE kit type does not match any of the valid types " + kitTypeString); + } + int tries = 0; + String randomOncHistoryDetailId = bspDummyKitDao.getRandomOncHistoryForStudy(ddpInstance.getName()); + OncHistoryDetail oncHistoryDetail = OncHistoryDetail.getOncHistoryDetail(randomOncHistoryDetailId, ddpInstance.getName()); + ddpParticipantId = oncHistoryDetail.getDdpParticipantId(); + Optional maybeParticipant = ElasticSearchUtil.getParticipantESDataByParticipantId(ddpInstance.getParticipantIndexES(), ddpParticipantId); + logger.info("found randomOncHistoryDetailId " + randomOncHistoryDetailId); + logger.info("found short id " + maybeParticipant.get().getProfile().map(ESProfile::getHruid)); + while (tries < 10 && (oncHistoryDetail == null || StringUtils.isBlank(oncHistoryDetail.getAccessionNumber()) || maybeParticipant.isEmpty() || maybeParticipant.get().getProfile().map(ESProfile::getHruid).isEmpty())) { + randomOncHistoryDetailId = bspDummyKitDao.getRandomOncHistoryForStudy(ddpInstance.getName()); + oncHistoryDetail = OncHistoryDetail.getOncHistoryDetail(randomOncHistoryDetailId, ddpInstance.getName()); + ddpParticipantId = oncHistoryDetail.getDdpParticipantId(); + maybeParticipant = ElasticSearchUtil.getParticipantESDataByParticipantId(ddpInstance.getParticipantIndexES(), ddpParticipantId); + logger.info("found randomOncHistoryDetailId " + randomOncHistoryDetailId); + logger.info("found short id " + maybeParticipant.get().getProfile().map(ESProfile::getHruid)); + tries++; + } + if (tries >= 10) { + throw new RuntimeException("couldn't find a valid onc history to create dummy"); + } + List tissueIds = OncHistoryDetail.getOncHistoryDetail(randomOncHistoryDetailId, ddpInstance.getName()).getTissues(); + String tissueId; - }, () -> { - throw new RuntimeException(" Participant " + ddpParticipantId + " was not found!"); - }); + if (tissueIds.isEmpty()) { + tissueId = Tissue.createNewTissue(randomOncHistoryDetailId, FFPE_USER); + } else { + tissueId = String.valueOf(tissueIds.get(new Random().nextInt(tissueIds.size())).getTissueId()); + } + new TissueSMIDDao().createNewSMIDForTissueWithValue(tissueId, FFPE_USER, smIdType, kitLabel); + } logger.info("Kit added successfully"); response.status(200); return null; diff --git a/src/main/java/org/broadinstitute/dsm/statics/DBConstants.java b/src/main/java/org/broadinstitute/dsm/statics/DBConstants.java index dd5e8da4f..33d9eb202 100644 --- a/src/main/java/org/broadinstitute/dsm/statics/DBConstants.java +++ b/src/main/java/org/broadinstitute/dsm/statics/DBConstants.java @@ -27,6 +27,7 @@ public class DBConstants { public static final String DDP_ONC_HISTORY_ALIAS = "o"; public static final String DDP_ONC_HISTORY_DETAIL_ALIAS = "oD"; public static final String DDP_TISSUE_ALIAS = "t"; + public static final String SM_ID_ALIAS = "sm"; public static final String DDP_KIT_REQUEST_ALIAS = "k"; public static final String DDP_ABSTRACTION_ALIAS = "a"; public static final String DRUG_ALIAS = "d"; @@ -46,6 +47,8 @@ public class DBConstants { public static final String CARRIER_USERNAME = "carrier_username"; public static final String CARRIER_PASSWORD= "carrier_password"; public static final String CARRIER_ACCESSKEY = "carrier_accesskey"; + public static final String BSP_COLLECTION = "bsp_collection"; + public static final String BSP_ORGANISM = "bsp_organism"; //kit request public static final String DSM_KIT_ID = "dsm_kit_id"; @@ -62,9 +65,8 @@ public class DBConstants { public static final String UPS_RETURN_DATE = "ups_return_date"; public static final String SAMPLE_TYPE = "sample_type"; public static final String DDP_KIT_REQUEST_TABLE_ABBR = "req."; - - - + public static final String BSP_MATERIAL_TYPE = "bsp_material_type"; + public static final String BSP_RECEPTABLE_TYPE = "bsp_receptacle_type"; public static final String DSM_LABEL_TO = "label_url_to"; public static final String DSM_LABEL_RETURN = "label_url_return"; public static final String DSM_CARRIER_TO = "carrierTo"; @@ -246,7 +248,9 @@ public class DBConstants { public static final String SCROLLS_COUNT = "scrolls_count"; public static final String H_E_COUNT = "h_e_count"; public static final String BLOCKS_COUNT = "blocks_count"; - + public static final String USS_SMIDS = "uss_sm_ids"; + public static final String SCROLL_SMIDS = "scrolls_sm_ids"; + public static final String HE_SMIDS = "he_sm_ids"; //field_settings public static final String FIELD_SETTING_ID = "field_settings_id"; @@ -485,6 +489,18 @@ public class DBConstants { //access_user public static final String PHONE_NUMBER = "phone_number"; + //sm_id table + public static final String SM_ID_TABLE = "sm_id"; + public static final String SM_ID_TABLE_ALIAS = "sm"; + public static final String SM_ID_PK = "sm_id_pk"; + public static final String SM_ID_TYPE_ID = "sm_id_type_id"; + public static final String SM_ID_VALUE = "sm_id_value"; + public static final String SM_ID_TISSUE_ID = "tissue_id"; + + //sm_id_type table + public static final String SM_ID_TYPE_TABLE = "sm_id_type"; + public static final String SM_ID_TYPE_TABLE_ALIAS = "smt"; + public static final String SM_ID_TYPE = "sm_id_type"; public static final String LABEL_URL_RETURN = "label_url_return"; diff --git a/src/test/java/org/broadinstitute/dsm/RouteTestSample.java b/src/test/java/org/broadinstitute/dsm/RouteTestSample.java index 995246d9f..453f66650 100644 --- a/src/test/java/org/broadinstitute/dsm/RouteTestSample.java +++ b/src/test/java/org/broadinstitute/dsm/RouteTestSample.java @@ -13,9 +13,9 @@ import org.broadinstitute.dsm.exception.RateNotAvailableException; import org.broadinstitute.dsm.model.*; import org.broadinstitute.dsm.model.KitType; -import org.broadinstitute.dsm.model.bsp.BSPKitInfo; -import org.broadinstitute.dsm.model.bsp.BSPKitRegistration; -import org.broadinstitute.dsm.model.bsp.BSPKitStatus; +import org.broadinstitute.dsm.model.gp.KitInfo; +import org.broadinstitute.dsm.model.gp.bsp.BSPKitRegistration; +import org.broadinstitute.dsm.model.gp.bsp.BSPKitStatus; import org.broadinstitute.dsm.model.ddp.DDPParticipant; import org.broadinstitute.dsm.route.KitStatusChangeRoute; import org.broadinstitute.dsm.statics.DBConstants; @@ -643,7 +643,7 @@ public void skipDDPEventBloodReceived() throws Exception { HttpResponse response = bspKit("FAKE_SPK_UUID_tt4"); Gson gson = new GsonBuilder().create(); - BSPKitInfo bspMetaData = gson.fromJson(DDPRequestUtil.getContentAsString(response), BSPKitInfo.class); + KitInfo bspMetaData = gson.fromJson(DDPRequestUtil.getContentAsString(response), KitInfo.class); Assert.assertEquals("FAKE_BSP_COLL_ID_tt4", bspMetaData.getCollaboratorParticipantId()); Assert.assertEquals("FAKE_BSP_SAM_ID_tt4", bspMetaData.getCollaboratorSampleId()); Assert.assertEquals("U", bspMetaData.getGender()); @@ -659,7 +659,7 @@ public void skipDDPEventBloodReceived() throws Exception { public void bspNormalKit() throws Exception { HttpResponse response = bspKit("testing123"); Gson gson = new GsonBuilder().create(); - BSPKitInfo bspMetaData = gson.fromJson(DDPRequestUtil.getContentAsString(response), BSPKitInfo.class); + KitInfo bspMetaData = gson.fromJson(DDPRequestUtil.getContentAsString(response), KitInfo.class); Assert.assertEquals("JJGUNZLLAY6HK9AAFWZQ", bspMetaData.getCollaboratorParticipantId()); Assert.assertEquals("VTLI45RTA3VGZRJBssfQ7", bspMetaData.getCollaboratorSampleId()); Assert.assertEquals("U", bspMetaData.getGender()); @@ -1174,7 +1174,7 @@ private void bspEndpoint(String instanceId, int kitType, String suffix, String m Assert.assertNotNull(DDPRequestUtil.getContentAsString(response)); Gson gson = new GsonBuilder().create(); - BSPKitInfo bspKitInfo = gson.fromJson(DDPRequestUtil.getContentAsString(response), BSPKitInfo.class); + KitInfo bspKitInfo = gson.fromJson(DDPRequestUtil.getContentAsString(response), KitInfo.class); Assert.assertEquals(1, bspKitInfo.getOrganismClassificationId()); //human Assert.assertEquals("FAKE_BSP_COLL_ID" + suffix, bspKitInfo.getCollaboratorParticipantId()); diff --git a/src/test/java/org/broadinstitute/dsm/model/elastic/migration/BaseCollectionMigratorTest.java b/src/test/java/org/broadinstitute/dsm/model/elastic/migration/BaseCollectionMigratorTest.java index 0c7959523..8aebab49b 100644 --- a/src/test/java/org/broadinstitute/dsm/model/elastic/migration/BaseCollectionMigratorTest.java +++ b/src/test/java/org/broadinstitute/dsm/model/elastic/migration/BaseCollectionMigratorTest.java @@ -30,7 +30,7 @@ public void transformObject() { private List mockOncHistoryDetail() { OncHistoryDetail oncHistoryDetail = new OncHistoryDetail(23, 0, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, mockTissues(), null, null, false); + null, null, null, null, null, null, null, null, null, mockTissues(), null, null, false, null, null); return Collections.singletonList(oncHistoryDetail); } @@ -38,10 +38,10 @@ private List mockTissues() { List fieldValue = new ArrayList<>(List.of(new Tissue(11, 22, "notes", 0, null, "awdwadawdawdawd", null, null, null, null, null, null, null, null, "Awdawd", null, null, null, null, null, null, null, - null, 0, 0, 0, 0), new Tissue(555, 777, + null, 0, 0, 0, 0, null, null, null), new Tissue(555, 777, null, 0, null, null, null, null, null, "awdawd", null, null, null, null, "awdawddwa", null, null, null, null, null, null, null, - null, 0, 0, 0, 0))); + null, 0, 0, 0, 0, null, null, null))); return fieldValue; }