diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml new file mode 100644 index 00000000..a64ef6aa --- /dev/null +++ b/.github/workflows/build_and_upload.yml @@ -0,0 +1,58 @@ +# This workflow will build a Java project with Maven +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven + +name: Java CI with Maven + +on: + push: + branches: + - master + workflow_dispatch: +env: + ORG_NAME: BahmniIndiaDistro + EVENT_TYPE: hip-module-trigger + +jobs: + build: + name: build and upload hip omod + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Cache Maven packages + uses: actions/cache@v2 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2- + - name: Build with Maven + run: mvn clean install + - run: mkdir staging && cp omod/target/*.omod staging + - uses: actions/upload-artifact@v2 + with: + name: Package + path: staging + + trigger-dependent-repos: + name: Trigger Workflows + needs: build + runs-on: ubuntu-latest + strategy: + matrix: + dependent-repos: [ 'bahmni-india-package' ] + steps: + - name: Create repository_dispatch + env: + REPOSITORY_NAME: ${{ matrix.dependent-repos }} + run: | + trigger_result=$(curl -s -o trigger_response.txt -w "%{http_code}" -X POST -H "Accept: application/vnd.github.v3+json" -H 'authorization: Bearer ${{ secrets.BAHMNI_PAT }}' https://api.github.com/repos/${ORG_NAME}/${REPOSITORY_NAME}/dispatches -d '{"event_type":"'"${EVENT_TYPE}"'"}') + if [ $trigger_result == 204 ];then + echo "Trigger to $ORG_NAME/$REPOSITORY_NAME Success" + else + echo "Trigger to $ORG_NAME/$REPOSITORY_NAME Failed" + cat trigger_response.txt + exit 1 + fi diff --git a/.gitignore b/.gitignore index 320b19a9..ddfdd4f0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,10 @@ .project .classpath target - +.idea +*.DS_Store # Package Files # *.jar *.war *.ear +*.iml diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 4c25686e..00000000 --- a/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,274 +0,0 @@ -#Tue Feb 08 13:16:22 EST 2011 -eclipse.preferences.version=1 -org.eclipse.jdt.core.codeComplete.argumentPrefixes= -org.eclipse.jdt.core.codeComplete.argumentSuffixes= -org.eclipse.jdt.core.codeComplete.fieldPrefixes= -org.eclipse.jdt.core.codeComplete.fieldSuffixes= -org.eclipse.jdt.core.codeComplete.localPrefixes= -org.eclipse.jdt.core.codeComplete.localSuffixes= -org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= -org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.processAnnotations=disabled -org.eclipse.jdt.core.compiler.source=1.5 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=20 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=19 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=20 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=18 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=20 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=18 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=1 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=1 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true -org.eclipse.jdt.core.formatter.comment.format_block_comments=false -org.eclipse.jdt.core.formatter.comment.format_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=false -org.eclipse.jdt.core.formatter.comment.format_source_code=false -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert -org.eclipse.jdt.core.formatter.comment.line_length=100 -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=125 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=tab -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=true -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs deleted file mode 100644 index 56d6d2d0..00000000 --- a/.settings/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,10 +0,0 @@ -#Thu Nov 13 13:26:19 EST 2008 -eclipse.preferences.version=1 -formatter_profile=_OpenMRS Formatter -formatter_settings_version=11 -org.eclipse.jdt.ui.exception.name=e -org.eclipse.jdt.ui.gettersetter.use.is=true -org.eclipse.jdt.ui.javadoc=true -org.eclipse.jdt.ui.keywordthis=false -org.eclipse.jdt.ui.overrideannotation=true -org.eclipse.jdt.ui.text.custom_code_templates= diff --git a/.settings/org.maven.ide.eclipse.prefs b/.settings/org.maven.ide.eclipse.prefs deleted file mode 100644 index 1fd430ec..00000000 --- a/.settings/org.maven.ide.eclipse.prefs +++ /dev/null @@ -1,9 +0,0 @@ -#Tue Feb 08 13:15:09 EST 2011 -activeProfiles= -eclipse.preferences.version=1 -fullBuildGoals=process-test-resources -includeModules=true -resolveWorkspaceProjects=true -resourceFilterGoals=process-resources resources\:testResources -skipCompilerPlugin=true -version=1 diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..14b45289 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Thoughtworks Technologies India Private limited + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 3cd1155b..c46b3018 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,18 @@ -openmrs-module-basicmodule +openmrs-module-hipmodule ========================== -A demonstration module for new OpenMRS module developers +HIP module for exposing HIP specific features from OpenMRS. Description ----------- -This is a very basic module which can be used as a starting point in creating a new module. +This module is supporting the HIP service with all necessary endpoints exposed that are required by the HIP service. Building from Source -------------------- -You will need to have Java 1.6+ and Maven 2.x+ installed. Use the command 'mvn package' to -compile and package the module. The .omod file will be in the omod/target folder. +You will need to have Java 1.6+ and Maven 2.x+ installed. +You need to install the OpenMrs module SDK from https://github.com/openmrs/openmrs-sdk (see Readme for installation instructions) -Alternatively you can add the snippet provided in the [Creating Modules](https://wiki.openmrs.org/x/cAEr) page to your -omod/pom.xml and use the mvn command: - - mvn package -P deploy-web -D deploy.path="../../openmrs-1.8.x/webapp/src/main/webapp" - -It will allow you to deploy any changes to your web -resources such as jsp or js files without re-installing the module. The deploy path says -where OpenMRS is deployed. +Use the command `mvn clean install` to build the module, the .omod file will be in the omod/target folder. Installation ------------ @@ -30,3 +23,32 @@ If uploads are not allowed from the web (changable via a runtime property), you into the ~/.OpenMRS/modules folder. (Where ~/.OpenMRS is assumed to be the Application Data Directory that the running openmrs is currently using.) After putting the file in there simply restart OpenMRS/tomcat and the module will be loaded and started. + +Configure values +------------ +## Vagrant setup + +You can configure values like, say location, concept and attribute names. you can check **api/src/main/java/org/bahmni/module/hip/Config.java** to know what are the values you can configure and default values. + +### One time setup + +1. create a file. For example, created `env_file` in `/etc/openmrs/` directory. +2. To create conf file for openmrs service,`systemctl edit openmrs`. It will open blank file. paste the following lines in it +``` +[Service] +EnvironmentFile=/etc/openmrs/env_file +``` +Note: You need to specify your created file path from 1st step in `EnvironmentFile` variable + +### To configure values + +You need to add values to the `env_file`. For example, if you need to specify custom values for Location and Phone Number attribute. +``` +LOCATION=your_location +PHONE_NUMBER=your_phoneNumber_attribute_name +``` +Note: Attribute Name should be exactly same as enum keys from **api/src/main/java/org/bahmni/module/hip/Config.java** + +## Docker setup + +You can add values to the openmrs Environment variables, specifying same attribute name. \ No newline at end of file diff --git a/api/basicmodule-api.iml b/api/basicmodule-api.iml new file mode 100644 index 00000000..75fc53ef --- /dev/null +++ b/api/basicmodule-api.iml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/api/pom.xml b/api/pom.xml index 388a1dae..f1fe6327 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -2,13 +2,44 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 - org.openmrs.module - basicmodule + org.bahmni.module + hipmodule 0.1-SNAPSHOT - basicmodule-api + hipmodule-api jar - Basic Module API - API project for Basic Module + HIP Module API + API project for HIP Module + + + + org.openmrs.api + openmrs-api + 2.4.2 + provided + + + org.openmrs.module + emrapi-api + provided + + + org.openmrs.module + emrapi-omod + provided + + + org.projectlombok + lombok + 1.18.10 + provided + + + org.openmrs.module + episodes-api + 1.0-SNAPSHOT + compile + + diff --git a/api/src/main/java/org/openmrs/module/basicmodule/BasicModuleActivator.java b/api/src/main/java/org/bahmni/module/hip/BasicModuleActivator.java similarity index 93% rename from api/src/main/java/org/openmrs/module/basicmodule/BasicModuleActivator.java rename to api/src/main/java/org/bahmni/module/hip/BasicModuleActivator.java index a5672c55..cbda086c 100644 --- a/api/src/main/java/org/openmrs/module/basicmodule/BasicModuleActivator.java +++ b/api/src/main/java/org/bahmni/module/hip/BasicModuleActivator.java @@ -11,31 +11,32 @@ * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ -package org.openmrs.module.basicmodule; +package org.bahmni.module.hip; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openmrs.module.BaseModuleActivator; +import org.openmrs.module.ModuleActivator; /** * This class contains the logic that is run every time this module is either started or shutdown */ public class BasicModuleActivator extends BaseModuleActivator { - + private Log log = LogFactory.getLog(this.getClass()); - + /** * @see org.openmrs.module.Activator#startup() */ public void startup() { log.info("Starting Basic Module"); } - + /** * @see org.openmrs.module.Activator#shutdown() */ public void shutdown() { log.info("Shutting down Basic Module"); } - + } diff --git a/api/src/main/java/org/bahmni/module/hip/Config.java b/api/src/main/java/org/bahmni/module/hip/Config.java new file mode 100644 index 00000000..b03cf59b --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/Config.java @@ -0,0 +1,61 @@ +package org.bahmni.module.hip; + +public enum Config { + + + PATIENT_DOCUMENTS_PATH("/home/bahmni/document_images/"), + LOCATION("Bahmni Clinic"), + + //attribute name + PHONE_NUMBER("phoneNumber"), + + //identifier type + ABHA_ADDRESS("ABHA Address"), + ABHA_NUMBER("ABHA Number"), + + //encounterType + CONSULTATION("Consultation"), + PATIENT_DOCUMENT("Patient Document"), + RADIOLOGY_TYPE( "RADIOLOGY"), + ORDER_TYPE("Order"), + + //concepts + DOCUMENT_TYPE("Document"), + RADIOLOGY_REPORT("Radiology Report"), + CHIEF_COMPLAINT( "Chief Complaint"), + PROCEDURE_NOTES( "Procedure Notes"), + DISCHARGE_SUMMARY( "Discharge Summary"), + CODED_DIAGNOSIS( "Coded Diagnosis"), + NON_CODED_DIAGNOSIS( "Non-coded Diagnosis"), + LAB_REPORT( "LAB_REPORT"), + RADIOLOGY_ORDER( "Radiology Order"), + LAB_ORDER( "Lab Order"), + IMAGE("Image"), + PATIENT_VIDEO("Patient Video"), + CONCEPT_DETAILS_CONCEPT_CLASS("Concept Details"), + CHIEF_COMPLAINT_CODED("Chief Complaint Coded"), + SIGN_SYMPTOM_DURATION("Sign/symptom duration"), + CHIEF_COMPLAINT_DURATION("Chief Complaint Duration"), + + //Physical_Examination_Ignoring_Form_List + Forms_To_Ignore_In_Physical_Examination("Discharge Summary, Death Note, Delivery Note, Opioid Substitution Therapy - Intake, Opportunistic Infection, " + + "Safe Abortion, ECG Notes, Operative Notes, USG Notes, Procedure Notes,Triage Reference, History and Examination, Visit Diagnoses, Patient Video"), + + + PROP_HFR_ID("bahmniHip.healthFacilityRegistryId"), + PROP_HFR_NAME( "bahmniHip.healthFacilityName"), + PROP_HFR_SYSTEM( "bahmniHip.healthFacilitySystem"), + PROP_HFR_URL( "bahmniHip.healthFacilityUrl"); + + + private final String value; + + Config(String val) { + value = val; + } + + public String getValue() { + return System.getenv().getOrDefault(name(),this.value); + } + +} diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/CareContextRepository.java b/api/src/main/java/org/bahmni/module/hip/api/dao/CareContextRepository.java new file mode 100644 index 00000000..48a81dc9 --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/CareContextRepository.java @@ -0,0 +1,13 @@ +package org.bahmni.module.hip.api.dao; + +import org.bahmni.module.hip.model.PatientCareContext; +import org.openmrs.Patient; + +import java.util.List; + +public interface CareContextRepository { + List getPatientCareContext(String patientUuid); + + List getNewPatientCareContext(Patient patient); + +} diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/Constants.java b/api/src/main/java/org/bahmni/module/hip/api/dao/Constants.java new file mode 100644 index 00000000..a4eee283 --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/Constants.java @@ -0,0 +1,8 @@ +package org.bahmni.module.hip.api.dao; + +public class Constants { + + public static final String VISIT_TYPE = "VISIT_TYPE"; + public static final String PROGRAM = "PROGRAM"; + public static final String ORDER_ACTION = "DISCONTINUE"; +} diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/ConsultationDao.java b/api/src/main/java/org/bahmni/module/hip/api/dao/ConsultationDao.java new file mode 100644 index 00000000..abd5515e --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/ConsultationDao.java @@ -0,0 +1,18 @@ +package org.bahmni.module.hip.api.dao; + +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Patient; +import org.openmrs.Visit; + +import java.util.Date; +import java.util.List; + +public interface ConsultationDao { + List getChiefComplaints(Visit visit); + List getChiefComplaintForProgram(String programName, Date fromDate, Date toDate, Patient patient); + List getPhysicalExamination(Visit visit); + List getOrders(Visit visit); + List getOrdersForProgram(String programName, Date fromDate, Date toDate, Patient patient); + List getPhysicalExaminationForProgram(String programName, Date fromDate, Date toDate, Patient patient); +} diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/DiagnosticReportDao.java b/api/src/main/java/org/bahmni/module/hip/api/dao/DiagnosticReportDao.java new file mode 100644 index 00000000..60ae92db --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/DiagnosticReportDao.java @@ -0,0 +1,14 @@ +package org.bahmni.module.hip.api.dao; + +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Visit; + +import java.util.List; +import java.util.Map; + +public interface DiagnosticReportDao { + Map> getAllUnorderedUploadsForVisit(String patientUUID, Visit visit); + Map> getAllOrderedTestUploads(String patientUUID,Visit visit); +} \ No newline at end of file diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/DischargeSummaryDao.java b/api/src/main/java/org/bahmni/module/hip/api/dao/DischargeSummaryDao.java new file mode 100644 index 00000000..a017abea --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/DischargeSummaryDao.java @@ -0,0 +1,15 @@ +package org.bahmni.module.hip.api.dao; + +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.Visit; + +import java.util.Date; +import java.util.List; + +public interface DischargeSummaryDao { + List getCarePlan(Visit visit); + List getProcedures(Visit visit); + List getProceduresForProgram(String programName, Date fromDate, Date toDate, Patient patient); + List getCarePlanForProgram(String programName, Date fromDate, Date toDate, Patient patient); +} \ No newline at end of file diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/EncounterDao.java b/api/src/main/java/org/bahmni/module/hip/api/dao/EncounterDao.java new file mode 100644 index 00000000..b2206cb1 --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/EncounterDao.java @@ -0,0 +1,19 @@ +package org.bahmni.module.hip.api.dao; + +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Visit; + +import java.util.Date; +import java.util.List; + +public interface EncounterDao { + + List GetEpisodeEncounterIds(); + List GetOrdersForVisit(Visit visit); + List GetEncountersForVisit(Visit visit, String encounterType); + List GetAllObsForVisit(Visit visit, String encounterType, String conceptName); + List GetEncounterIdsForProgramForPrescriptions(String patientUUID, String program, String programEnrollmentID, Date fromDate, Date toDate) ; + List GetEncounterIdsForProgramForDiagnosticReport(String patientUUID, String program, String programEnrollmentID, Date fromDate, Date toDate); +} diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/ExistingPatientDao.java b/api/src/main/java/org/bahmni/module/hip/api/dao/ExistingPatientDao.java new file mode 100644 index 00000000..ec072b3a --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/ExistingPatientDao.java @@ -0,0 +1,16 @@ +package org.bahmni.module.hip.api.dao; + +import org.openmrs.Patient; + +import java.util.List; + +public interface ExistingPatientDao { + String getPatientUuidWithHealthId(String healthId); + + List getPatientsWithPhoneNumber(String phoneNumber); + + String getPhoneNumber(Integer patientId); + + String getPatientHealthIdWithPatientId(Integer patientId); + +} diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/HipVisitDao.java b/api/src/main/java/org/bahmni/module/hip/api/dao/HipVisitDao.java new file mode 100644 index 00000000..cb5f8306 --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/HipVisitDao.java @@ -0,0 +1,14 @@ +package org.bahmni.module.hip.api.dao; + +import org.openmrs.Patient; +import org.openmrs.Visit; + +import java.util.Date; +import java.util.List; + +public interface HipVisitDao { + + List GetVisitIdsForProgramForLabResults(String patientUUID, String program, String programEnrollmentID, Date fromDate, Date toDate); + List GetVisitIdsForVisitForLabResults(String patientUUID, String visit, Date visitStartDate) ; + Visit getPatientVisit(Patient patient, String visitType, Date visitStartDate); +} diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/OPConsultDao.java b/api/src/main/java/org/bahmni/module/hip/api/dao/OPConsultDao.java new file mode 100644 index 00000000..042ec250 --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/OPConsultDao.java @@ -0,0 +1,21 @@ +package org.bahmni.module.hip.api.dao; + +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.module.emrapi.conditionslist.Condition; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +public interface OPConsultDao { + Map> getMedicalHistoryConditions(Visit visit); + List getMedicalHistoryDiagnosis(Visit visit); + List getProcedures(Visit visit); + List getProceduresForProgram(String programName, Date fromDate, Date toDate, Patient patient); + Map> getMedicalHistoryConditionsForProgram(String programName, Date fromDate, Date toDate, Patient patient); + List getMedicalHistoryDiagnosisForProgram(String programName, Date fromDate, Date toDate, Patient patient); + Map> getPatientDocumentsForVisit(Visit visit); +} diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/PrescriptionOrderDao.java b/api/src/main/java/org/bahmni/module/hip/api/dao/PrescriptionOrderDao.java new file mode 100644 index 00000000..d57dc6eb --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/PrescriptionOrderDao.java @@ -0,0 +1,15 @@ +package org.bahmni.module.hip.api.dao; + +import org.openmrs.DrugOrder; +import org.openmrs.OrderType; +import org.openmrs.Patient; +import org.openmrs.Visit; + +import java.util.Date; +import java.util.List; + +public interface PrescriptionOrderDao { + List getDrugOrders(Visit visit); + List getDrugOrdersForProgram(Patient patient, Date fromDate, Date toDate, OrderType orderType, String program, String programEnrollmentId); + +} diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/impl/CareContextRepositoryImpl.java b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/CareContextRepositoryImpl.java new file mode 100644 index 00000000..6ab6255b --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/CareContextRepositoryImpl.java @@ -0,0 +1,131 @@ +package org.bahmni.module.hip.api.dao.impl; + +import org.bahmni.module.hip.api.dao.CareContextRepository; +import org.bahmni.module.hip.api.dao.EncounterDao; +import org.bahmni.module.hip.model.PatientCareContext; +import org.hibernate.Query; +import org.hibernate.SessionFactory; +import org.openmrs.Encounter; +import org.openmrs.Patient; +import org.openmrs.PatientProgram; +import org.openmrs.Visit; +import org.openmrs.api.PatientService; +import org.openmrs.api.ProgramWorkflowService; +import org.openmrs.api.VisitService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.bahmni.module.hip.api.dao.Constants.PROGRAM; +import static org.bahmni.module.hip.api.dao.Constants.VISIT_TYPE; + +@Repository +public class CareContextRepositoryImpl implements CareContextRepository { + private SessionFactory sessionFactory; + private PatientService patientService; + private VisitService visitService; + private ProgramWorkflowService programWorkflowService; + private EncounterDao encounterDao; + + + @Autowired + public CareContextRepositoryImpl(SessionFactory sessionFactory, PatientService patientService, VisitService visitService, ProgramWorkflowService programWorkflowService, EncounterDao encounterDao) { + this.sessionFactory = sessionFactory; + this.patientService = patientService; + this.visitService = visitService; + this.programWorkflowService = programWorkflowService; + this.encounterDao = encounterDao; + } + + @Override + public List getPatientCareContext(String patientUuid) { + List careContexts = new ArrayList<>(); + Patient patient = patientService.getPatientByUuid(patientUuid); + List visits = getAllVisitForPatient(patient); + List patientPrograms = getAllPrograms(patient); + for (Visit visit: visits) { + careContexts.add(getPatientCareContext(visit)); + } + for (PatientProgram program: patientPrograms) { + careContexts.add(getPatientCareContext(program)); + } + return careContexts; + } + + + @Override + public List getNewPatientCareContext(Patient patient) { + List careContexts = new ArrayList<>(); + List visits = getAllVisitForPatient(patient); + List patientPrograms = getAllPrograms(patient); + Visit visit = !visits.isEmpty() ? visits.get(0) : null; + PatientProgram program = !patientPrograms.isEmpty() ? patientPrograms.get(0) : null; + if(visit == null && program != null) + careContexts.add(getPatientCareContext(program)); + else if(visit != null && program == null) + careContexts.add(getPatientCareContext(visit)); + else if(visit != null && program != null) { + if (program.getDateCreated().before(visit.getStartDatetime())) + careContexts.add(getPatientCareContext(visit)); + else + careContexts.add(getPatientCareContext(program)); + } + return careContexts; + } + + private PatientCareContext getPatientCareContext(Visit visit) { + return new PatientCareContext(VISIT_TYPE, + visit.getVisitType().getName().concat(" / ").concat(visit.getStartDatetime().toString()), + visit.getCreator().getPersonName().getFullName()); + } + + private PatientCareContext getPatientCareContext(PatientProgram program) { + return new PatientCareContext(PROGRAM, + program.getProgram().getName(), + getProgramEnrollementId(program.getPatientProgramId()).get(0)); + } + + private List getEpisodeIds() { + Query query = this.sessionFactory.getCurrentSession().createSQLQuery("select\n" + + "\t\tepisode_id\n" + + "\tfrom\n" + + "\t\tepisode_encounter\n"); + return query.list(); + } + + private List getProgramEnrollementId(Integer patientProgramId) { + Query query = this.sessionFactory.getCurrentSession().createSQLQuery("SELECT\n" + + " value_reference FROM patient_program_attribute WHERE patient_program_id = :patientProgramId\n"); + query.setParameter("patientProgramId", patientProgramId); + return query.list(); + } + + private List getAllVisitForPatient(Patient patient){ + List visits = new ArrayList<>(); + for (Visit visit: visitService.getVisitsByPatient(patient)) { + Set encounters = visit.getEncounters().stream() + .filter(encounter -> !encounterDao.GetEpisodeEncounterIds().contains(encounter.getEncounterId())) + .collect(Collectors.toSet()); + if(!encounters.isEmpty()) + visits.add(visit); + } + return visits; + } + + private List getAllPrograms(Patient patient){ + List programs = new ArrayList<>(); + List episodeIds = getEpisodeIds(); + Set patientPrograms = new HashSet<>(programWorkflowService.getPatientPrograms(patient, null, null, null, null, null, false)); + for (PatientProgram program: patientPrograms) { + if(episodeIds.contains(program.getId())) + programs.add(program); + } + return programs; + } + +} diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/impl/ConsultationDaoImpl.java b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/ConsultationDaoImpl.java new file mode 100644 index 00000000..0d012065 --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/ConsultationDaoImpl.java @@ -0,0 +1,145 @@ +package org.bahmni.module.hip.api.dao.impl; + +import org.bahmni.module.hip.Config; +import org.bahmni.module.hip.api.dao.ConsultationDao; +import org.bahmni.module.hip.api.dao.EncounterDao; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Patient; +import org.openmrs.PatientProgram; +import org.openmrs.Visit; +import org.openmrs.api.ObsService; +import org.openmrs.api.OrderService; +import org.openmrs.api.ProgramWorkflowService; +import org.openmrs.module.episodes.Episode; +import org.openmrs.module.episodes.service.EpisodeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.bahmni.module.hip.api.dao.Constants.ORDER_ACTION; + +@Repository +public class ConsultationDaoImpl implements ConsultationDao { + + public static final ArrayList ORDER_TYPES = new ArrayList() {{ + add(Config.LAB_ORDER.getValue()); + add(Config.RADIOLOGY_ORDER.getValue()); + }}; + private final ProgramWorkflowService programWorkflowService; + private final EpisodeService episodeService; + private final EncounterDao encounterDao; + private final ObsService obsService; + private final OrderService orderService; + + @Autowired + public ConsultationDaoImpl(ObsService obsService, OrderService orderService, ProgramWorkflowService programWorkflowService, EpisodeService episodeService, EncounterDao encounterDao) { + this.obsService = obsService; + this.orderService = orderService; + this.programWorkflowService = programWorkflowService; + this.episodeService = episodeService; + this.encounterDao = encounterDao; + } + + @Override + public List getChiefComplaints(Visit visit) { + List chiefComplaintObsMap = encounterDao.GetAllObsForVisit(visit,Config.CONSULTATION.getValue(),Config.CHIEF_COMPLAINT.getValue()) + .stream().filter(o -> o.getValueCoded() != null && o.getConcept().getName().getLocalePreferred()) + .collect(Collectors.toList()); + return chiefComplaintObsMap; + } + + @Override + public List getChiefComplaintForProgram(String programName, Date fromDate, Date toDate, Patient patient) { + List obs = getAllObs(programName, fromDate, toDate, patient); + List obsSet = new ArrayList<>(); + for (Obs o : obs) { + if (Objects.equals(o.getEncounter().getEncounterType().getName(), Config.CONSULTATION.getValue()) + && Objects.equals(o.getConcept().getName().getName(), Config.CHIEF_COMPLAINT.getValue()) + && o.getValueCoded() != null + && o.getConcept().getName().getLocalePreferred()) { + obsSet.add(o); + } + } + return obsSet; + } + + public List getAllObs(String programName, Date fromDate, Date toDate, Patient patient) { + List patientPrograms = programWorkflowService.getPatientPrograms(patient, programWorkflowService.getProgramByName(programName), fromDate, toDate, null, null, false); + Set patientProgramSet = new HashSet<>(patientPrograms); + List obs = new ArrayList<>(); + for (PatientProgram patientProgram : patientProgramSet) { + Episode episode = episodeService.getEpisodeForPatientProgram(patientProgram); + Set encounterSet = episode.getEncounters(); + for (Encounter encounter : encounterSet) { + obs.addAll(encounter.getAllObs()); + } + } + return obs; + } + + @Override + public List getPhysicalExamination(Visit visit) { + final String[] formNames = Config.Forms_To_Ignore_In_Physical_Examination.getValue().split("\\s*,\\s*"); + List physicalExaminationObsMap = encounterDao.GetAllObsForVisit(visit,Config.CONSULTATION.getValue(),null) + .stream().filter(o -> o.getValueCoded() == null + && o.getObsGroup() == null + && !Arrays.asList(formNames).contains(o.getConcept().getName().getName()) ) + .collect(Collectors.toList()); + return physicalExaminationObsMap; + } + + @Override + public List getOrders(Visit visit) { + return encounterDao.GetOrdersForVisit(visit).stream() + .filter(order -> order.getDateStopped() == null && !Objects.equals(order.getAction().toString(), ORDER_ACTION)) + .filter(order -> ORDER_TYPES.contains(order.getOrderType().getName())) + .collect(Collectors.toList()); + } + + @Override + public List getOrdersForProgram(String programName, Date fromDate, Date toDate, Patient patient) { + List orderSet = new ArrayList<>(); + List patientPrograms = programWorkflowService.getPatientPrograms(patient, programWorkflowService.getProgramByName(programName), fromDate, toDate, null, null, false); + Set patientProgramSet = new HashSet<>(patientPrograms); + for (PatientProgram patientProgram : patientProgramSet) { + Episode episode = episodeService.getEpisodeForPatientProgram(patientProgram); + Set encounterSet = episode.getEncounters(); + for (Encounter encounter : encounterSet) { + for (Order order : encounter.getOrders()) { + if (order.getDateStopped() == null && !Objects.equals(order.getAction().toString(), ORDER_ACTION) && ORDER_TYPES.contains(order.getOrderType().getName())) { + orderSet.add(order); + } + } + } + } + return orderSet; + } + + @Override + public List getPhysicalExaminationForProgram(String programName, Date fromDate, Date toDate, Patient patient) { + final String[] formNames = Config.Forms_To_Ignore_In_Physical_Examination.getValue().split("\\s*,\\s*"); + List physicalExaminationObsMap = new ArrayList<>(); + List obs = getAllObs(programName, fromDate, toDate, patient); + for (Obs o : obs) { + if (Objects.equals(o.getEncounter().getEncounterType().getName(), Config.CONSULTATION.getValue()) + && o.getValueCoded() == null + && o.getConcept().getName().getLocalePreferred() + && o.getObsGroup() == null + && !Arrays.asList(formNames).contains(o.getConcept().getName().getName())) { + physicalExaminationObsMap.add(o); + } + } + return physicalExaminationObsMap; + } +} + diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/impl/DiagnosticReportDaoImpl.java b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/DiagnosticReportDaoImpl.java new file mode 100644 index 00000000..1c12c5f7 --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/DiagnosticReportDaoImpl.java @@ -0,0 +1,115 @@ +package org.bahmni.module.hip.api.dao.impl; + +import org.bahmni.module.hip.Config; +import org.bahmni.module.hip.api.dao.DiagnosticReportDao; +import org.hibernate.Query; +import org.hibernate.SessionFactory; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Person; +import org.openmrs.Visit; +import org.openmrs.api.ConceptService; +import org.openmrs.api.EncounterService; +import org.openmrs.api.ObsService; +import org.openmrs.api.PatientService; +import org.openmrs.api.PersonService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + + + +@Repository +public class DiagnosticReportDaoImpl implements DiagnosticReportDao { + + private SessionFactory sessionFactory; + private PersonService personService; + private ObsService obsService; + private ConceptService conceptService; + private EncounterService encounterService; + private PatientService patientService; + + + @Autowired + public DiagnosticReportDaoImpl(PersonService personService, ObsService obsService, + ConceptService conceptService, EncounterService encounterService, + SessionFactory sessionFactory, PatientService patientService) + { + this.obsService = obsService; + this.personService = personService; + this.conceptService = conceptService; + this.encounterService = encounterService; + this.sessionFactory = sessionFactory; + this.patientService = patientService; + } + + + private List getAllObsForDiagnosticReports(String patientUUID, Boolean linkedWithOrder) { + Person person = personService.getPersonByUuid(patientUUID); + Concept concept = conceptService.getConcept(Config.LAB_REPORT.getValue()); + List obs = obsService.getObservationsByPersonAndConcept(person,concept); + if(linkedWithOrder) + return obs.stream().filter(o -> o.getOrder() != null).collect(Collectors.toList()); + return obs.stream().filter(o -> o.getOrder() == null).collect(Collectors.toList()); + } + + @Override + public Map> getAllUnorderedUploadsForVisit(String patientUUID, Visit visit){ + Map> labReportsMap = new HashMap<>();; + List labReports = getAllObsForDiagnosticReports(patientUUID,false); + List encounters = encounterService.getEncountersByVisit(visit,false); + if(encounters.size() != 0) { + List nextEncounters = encounterService.getEncountersByPatient(patientService.getPatientByUuid(patientUUID)).stream().filter(e -> + encounters.get(encounters.size() - 1).getId() < e.getId() + ).collect(Collectors.toList()); + for (Obs obs : labReports) { + for (Encounter encounter : encounters) { + Encounter nextEncounter; + Date nextEncounterDate = nextEncounters.size() != 0 ? nextEncounters.get(0).getDateCreated() : new Date(); + if (encounters.indexOf(encounter) < (encounters.size() - 1)) { + nextEncounter = encounterService.getEncounter(encounters.get(encounters.indexOf(encounter) + 1).getId()); + nextEncounterDate = nextEncounter.getDateCreated(); + } + if (obs.getDateCreated().equals(encounter.getDateCreated()) || (obs.getDateCreated().before(nextEncounterDate) && obs.getDateCreated().after(encounter.getDateCreated()))) { + if (labReportsMap.containsKey(encounter)) { + labReportsMap.get(encounter).add(obs); + } else { + labReportsMap.put(encounter, new ArrayList() {{ + add(obs); + }}); + } + } + } + } + } + return labReportsMap; + } + + @Override + public Map> getAllOrderedTestUploads(String patientUuid,Visit visit) { + Map> documentObs = new HashMap<>(); + List obsList = getAllObsForDiagnosticReports(patientUuid,true); + List encounters = encounterService.getEncountersByVisit(visit,false); + + for (Obs obs : obsList) { + Encounter orderEncounter = obs.getOrder().getEncounter(); + if(encounters.contains(orderEncounter)) { + if (documentObs.containsKey(orderEncounter)) { + documentObs.get(orderEncounter).add(obs); + } else { + documentObs.put(orderEncounter, new ArrayList() {{ + add(obs); + }}); + } + } + } + return documentObs; + } +} \ No newline at end of file diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/impl/DischargeSummaryDaoImpl.java b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/DischargeSummaryDaoImpl.java new file mode 100644 index 00000000..4c4d7e82 --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/DischargeSummaryDaoImpl.java @@ -0,0 +1,101 @@ +package org.bahmni.module.hip.api.dao.impl; + +import org.bahmni.module.hip.Config; +import org.bahmni.module.hip.api.dao.DischargeSummaryDao; +import org.bahmni.module.hip.api.dao.EncounterDao; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.PatientProgram; +import org.openmrs.Visit; +import org.openmrs.api.ObsService; +import org.openmrs.api.ProgramWorkflowService; +import org.openmrs.module.episodes.Episode; +import org.openmrs.module.episodes.service.EpisodeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + + +@Repository +public class DischargeSummaryDaoImpl implements DischargeSummaryDao { + + private final ObsService obsService; + private final ProgramWorkflowService programWorkflowService; + private final EpisodeService episodeService; + private final EncounterDao encounterDao; + + @Autowired + public DischargeSummaryDaoImpl(ObsService obsService, ProgramWorkflowService programWorkflowService, EpisodeService episodeService, EncounterDao encounterDao) { + this.obsService = obsService; + this.programWorkflowService = programWorkflowService; + this.episodeService = episodeService; + this.encounterDao = encounterDao; + } + + @Override + public List getCarePlan(Visit visit) { + List carePlanObs = encounterDao.GetAllObsForVisit(visit, Config.CONSULTATION.getValue(), Config.DISCHARGE_SUMMARY.getValue()).stream() + .filter(obs -> obs.getConcept().getName().getLocalePreferred()) + .collect(Collectors.toList()); + + return carePlanObs; + } + + @Override + public List getCarePlanForProgram(String programName, Date fromDate, Date toDate, Patient patient) { + List patientPrograms = programWorkflowService.getPatientPrograms(patient,programWorkflowService.getProgramByName(programName), fromDate, toDate,null,null,false); + Set patientProgramSet = new HashSet<>(patientPrograms); + List carePlanObs= new ArrayList<>(); + for (PatientProgram patientProgram: patientProgramSet) { + Episode episode = episodeService.getEpisodeForPatientProgram(patientProgram); + Set encounterSet = episode.getEncounters(); + for (Encounter encounter : encounterSet) { + for (Obs o : encounter.getAllObs()) { + if (Config.DISCHARGE_SUMMARY.getValue().equals(o.getConcept().getName().getName()) + && o.getConcept().getName().getLocalePreferred()) { + carePlanObs.add(o); + } + } + } + } + return carePlanObs; + } + + @Override + public List getProcedures(Visit visit) { + List proceduresObsMap = encounterDao.GetAllObsForVisit(visit,Config.CONSULTATION.getValue(), Config.PROCEDURE_NOTES.getValue()).stream() + .filter(obs -> obs.getObsGroup() == null) + .collect(Collectors.toList()); + return proceduresObsMap; + } + + @Override + public List getProceduresForProgram(String programName, Date fromDate, Date toDate, Patient patient) { + List patientPrograms = programWorkflowService.getPatientPrograms(patient,programWorkflowService.getProgramByName(programName), fromDate, toDate,null,null,false); + Set patientProgramSet = new HashSet<>(patientPrograms); + List proceduresObsSet= new ArrayList<>(); + for (PatientProgram patientProgram: patientProgramSet) { + Episode episode = episodeService.getEpisodeForPatientProgram(patientProgram); + Set encounterSet = episode.getEncounters(); + for (Encounter encounter : encounterSet) { + for (Obs o : encounter.getAllObs()) { + if (Objects.equals(o.getEncounter().getEncounterType().getName(), Config.CONSULTATION.getValue()) + && o.getObsGroup() == null + && Objects.equals(o.getConcept().getName().getName(), Config.PROCEDURE_NOTES.getValue()) + ) { + proceduresObsSet.add(o); + } + } + } + } + return proceduresObsSet; + } +} \ No newline at end of file diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/impl/EncounterDaoImpl.java b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/EncounterDaoImpl.java new file mode 100644 index 00000000..79950796 --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/EncounterDaoImpl.java @@ -0,0 +1,200 @@ +package org.bahmni.module.hip.api.dao.impl; + +import org.bahmni.module.hip.Config; +import org.bahmni.module.hip.api.dao.EncounterDao; +import org.hibernate.Query; +import org.hibernate.SessionFactory; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Visit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + + + +@Repository +public class EncounterDaoImpl implements EncounterDao { + + private SessionFactory sessionFactory; + + @Autowired + public EncounterDaoImpl(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + private String sqlGetEpisodeEncounterIds = "select\n" + + "\t\tencounter_id\n" + + "\tfrom\n" + + "\t\tepisode_encounter\n"; + + private String sqlGetEncounterIdsForProgramForPrescriptions = "SELECT\n" + + " le.encounter_id\n" + + "FROM\n" + + " patient_program AS pp\n" + + " INNER JOIN program AS p ON pp.program_id = p.program_id\n" + + " INNER JOIN (\n" + + " SELECT\n" + + " ee.episode_id,\n" + + " ee.encounter_id,\n" + + " epp.patient_program_id,\n" + + " v.date_started\n" + + " FROM\n" + + " episode_encounter AS ee\n" + + " INNER JOIN episode_patient_program AS epp ON ee.episode_id = epp.episode_id\n" + + " INNER JOIN encounter AS e ON e.encounter_id = ee.encounter_id\n" + + " INNER JOIN visit AS v ON v.visit_id = e.visit_id\n" + + " ) AS le ON le.patient_program_id = pp.patient_program_id\n" + + "WHERE\n" + + " p.name = :programName\n" + + " AND pp.patient_id = (\n" + + " SELECT\n" + + " person_id\n" + + " FROM\n" + + " person AS p2\n" + + " WHERE\n" + + " p2.uuid = :patientUUID\n" + + " )\n" + + " AND pp.patient_program_id IN (\n" + + " SELECT\n" + + " patient_program_id\n" + + " FROM\n" + + " program_attribute_type AS pat\n" + + " INNER JOIN patient_program_attribute AS ppa ON pat.program_attribute_type_id = ppa.attribute_type_id\n" + + " WHERE\n" + + " name = \"ID_Number\"\n" + + " AND value_reference = :programEnrollmentId\n" + + " )\n" + + " AND le.date_started BETWEEN :fromDate AND :toDate ;\n"; + + private String sqlGetEncounterIdsForProgramForDiagnosticReports = "SELECT\n" + + " res.encounter_id\n" + + "FROM\n" + + " (\n" + + " SELECT\n" + + " *\n" + + " from(\n" + + " SELECT\n" + + " o.encounter_id,\n" + + " p.uuid AS person_uuid,\n" + + " p2.name AS pro_name,\n" + + " ppa.value_reference,\n" + + " pp.date_enrolled,\n" + + " o.concept_id AS obs_concept_id,\n" + + " o.value_text,\n" + + " o.void_reason AS obs_void_reason\n" + + " from\n" + + " obs o\n" + + " inner join person p on p.person_id = o.person_id\n" + + " inner join patient_program pp on pp.patient_id = p.person_id\n" + + " inner join program p2 on p2.program_id = pp.program_id\n" + + " inner join patient_program_attribute ppa on ppa.patient_program_id = pp.patient_program_id\n" + + " where\n" + + " encounter_id in (\n" + + " SELECT\n" + + " encounter_id\n" + + " from\n" + + " encounter e\n" + + " inner join encounter_type as et on et.encounter_type_id = e.encounter_type\n" + + " where\n" + + " (\n" + + " et.name = '" + Config.RADIOLOGY_TYPE.getValue() + "'\n" + + " or et.name = '" + Config.PATIENT_DOCUMENT.getValue() + "'\n" + + " )\n" + + " and visit_id in (\n" + + " SELECT\n" + + " visit_id\n" + + " from\n" + + " encounter e2\n" + + " inner join episode_encounter ee on e2.encounter_id = ee.encounter_id\n" + + " )\n" + + " )\n" + + " ) as t\n" + + " INNER JOIN concept_name AS cn ON cn.concept_id = t.obs_concept_id\n" + + " WHERE\n" + + " name = '" + Config.DOCUMENT_TYPE.getValue() + "'\n" + + " and obs_void_reason is null\n" + + " and person_uuid = :patientUUID\n" + + " and pro_name = :programName\n" + + " and value_reference = :programEnrollmentId\n" + + " ) as res\n" + + " inner join encounter as e on e.encounter_id = res.encounter_id\n" + + " inner join visit as v on v.visit_id = e.visit_id\n" + + "where\n" + + " date_started between :fromDate\n" + + " and :toDate ;\n"; + + @Override + public List GetEpisodeEncounterIds() { + + Query query = this.sessionFactory.getCurrentSession().createSQLQuery(sqlGetEpisodeEncounterIds); + return query.list(); + } + + @Override + public List GetEncountersForVisit(Visit visit, String encounterType) { + List episodeEncounters = GetEpisodeEncounterIds(); + List encounters = visit.getEncounters().stream() + .filter(encounter -> !episodeEncounters.contains(encounter.getId())) + .filter(encounter -> Objects.equals(encounter.getEncounterType().getName(), encounterType)) + .collect(Collectors.toList()); + return encounters; + } + + @Override + public List GetAllObsForVisit(Visit visit, String encounterType, String conceptName) { + List observations = new ArrayList<>(); + List encounters = GetEncountersForVisit(visit,encounterType); + for (Encounter encounter : encounters) { + if(conceptName == null) + observations.addAll(encounter.getAllObs()); + observations.addAll(encounter.getAllObs().stream() + .filter(o -> Objects.equals(o.getConcept().getName().getName(), conceptName)) + .collect(Collectors.toList())); + } + return observations; + } + + @Override + public List GetOrdersForVisit(Visit visit) { + List episodeEncounters = GetEpisodeEncounterIds(); + List encounters = visit.getEncounters().stream() + .filter(encounter -> !episodeEncounters.contains(encounter.getId())) + .collect(Collectors.toList()); + List orderList = new ArrayList<>(); + for (Encounter encounter: encounters) { + orderList.addAll(encounter.getOrders()); + } + return orderList; + } + + @Override + public List GetEncounterIdsForProgramForPrescriptions(String patientUUID, String program, String programEnrollmentID, Date fromDate, Date toDate) { + Query query = this.sessionFactory.getCurrentSession().createSQLQuery(sqlGetEncounterIdsForProgramForPrescriptions); + query.setParameter("patientUUID", patientUUID); + query.setParameter("programName", program); + query.setParameter("programEnrollmentId", programEnrollmentID); + query.setParameter("fromDate", fromDate); + query.setParameter("toDate", toDate); + + return query.list(); + } + + @Override + public List GetEncounterIdsForProgramForDiagnosticReport(String patientUUID, String program, String programEnrollmentID, Date fromDate, Date toDate) { + Query query = this.sessionFactory.getCurrentSession().createSQLQuery(sqlGetEncounterIdsForProgramForDiagnosticReports); + query.setParameter("patientUUID", patientUUID); + query.setParameter("programName", program); + query.setParameter("programEnrollmentId", programEnrollmentID); + query.setParameter("fromDate", fromDate); + query.setParameter("toDate", toDate); + + return query.list(); + } +} diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/impl/ExistingPatientDaoImpl.java b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/ExistingPatientDaoImpl.java new file mode 100644 index 00000000..e26eb92d --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/ExistingPatientDaoImpl.java @@ -0,0 +1,74 @@ +package org.bahmni.module.hip.api.dao.impl; + +import org.bahmni.module.hip.Config; +import org.bahmni.module.hip.api.dao.ExistingPatientDao; +import org.hibernate.Criteria; +import org.hibernate.Query; +import org.hibernate.SessionFactory; +import org.hibernate.criterion.Restrictions; +import org.openmrs.Patient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public class ExistingPatientDaoImpl implements ExistingPatientDao { + + private final SessionFactory sessionFactory; + + @Autowired + public ExistingPatientDaoImpl(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + + @Override + public String getPatientUuidWithHealthId(String healthId) { + String getPatientWithHealthIdQuery = "SELECT p.uuid FROM person AS p INNER JOIN \n" + + "\t\t\t\t patient_identifier AS pi ON p.person_id = pi.patient_id \n" + + "\t\t\t\t WHERE identifier = :healthId ;"; + Query query = this.sessionFactory.openSession().createSQLQuery(getPatientWithHealthIdQuery); + query.setParameter("healthId", healthId); + List patientUuids = query.list(); + return patientUuids.size() > 0 ? patientUuids.get(0) : null; + } + + @Override + public List getPatientsWithPhoneNumber(String phoneNumber) { + Criteria criteria = this.sessionFactory.getCurrentSession().createCriteria(Patient.class); + criteria.createCriteria("attributes", "pa") + .add(Restrictions.like("pa.value", "%" + phoneNumber)); + return criteria.list(); + } + + @Override + public String getPhoneNumber(Integer patientId) { + String getPatientPhoneNumberWithPatientIdQuery = + " SELECT value FROM person_attribute INNER JOIN person_attribute_type ON" + + " person_attribute.person_attribute_type_id = person_attribute_type.person_attribute_type_id " + + "where person_id = :patientId and name = \"phoneNumber\";"; + Query query = this.sessionFactory.openSession().createSQLQuery(getPatientPhoneNumberWithPatientIdQuery); + query.setParameter("patientId", patientId); + List phoneNumbers = query.list(); + return phoneNumbers.size() > 0 ? phoneNumbers.get(0) : null; + } + + @Override + public String getPatientHealthIdWithPatientId(Integer patientId) { + String getPatientHealthId = "select\n" + + "\tpi.identifier\n" + + "from\n" + + "\tpatient_identifier as pi\n" + + "inner join patient_identifier_type as piy on\n" + + "\tpi.identifier_type = piy.patient_identifier_type_id\n" + + "where\n" + + "\tpi.patient_id = :patientId\n" + + "\tand piy.name = :healthId ;"; + Query query = this.sessionFactory.openSession().createSQLQuery(getPatientHealthId); + query.setParameter("patientId", patientId); + query.setParameter("healthId", Config.ABHA_ADDRESS.getValue()); + List healthIds = query.list(); + return healthIds.size() > 0 ? healthIds.get(0) : null; + } +} \ No newline at end of file diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/impl/HipVisitDaoImpl.java b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/HipVisitDaoImpl.java new file mode 100644 index 00000000..127b7fe3 --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/HipVisitDaoImpl.java @@ -0,0 +1,78 @@ +package org.bahmni.module.hip.api.dao.impl; + +import org.bahmni.module.hip.api.dao.HipVisitDao; +import org.hibernate.Query; +import org.hibernate.SessionFactory; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.VisitService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +@Repository +public class HipVisitDaoImpl implements HipVisitDao { + + private SessionFactory sessionFactory; + private VisitService visitService; + + @Autowired + public HipVisitDaoImpl(SessionFactory sessionFactory, VisitService visitService) { + this.sessionFactory = sessionFactory; + this.visitService = visitService; + } + + private String sqlGetVisitIdsForVisitForLabResults = + "select distinct e.visit_id\n" + + "from visit as v join visit_type as vt on v.visit_type_id = vt.visit_type_id\n" + + "join encounter e on e.visit_id = v.visit_id\n" + + "where \n" + + " vt.name = :visit \n" + + " and v.date_started = :visitStartDate \n" + + " and e.visit_id not in (select e1.visit_id from encounter as e1 inner join episode_encounter on episode_encounter.encounter_id = e1.encounter_id) \n" + + "and v.patient_id in (select person_id from person as p2 where p2.uuid = :patientUUID) ;" ; + + private String sqlGetVisitIdsForProgramForLabResults = "\n" + + "select distinct e.visit_id from encounter as e, patient_program_attribute as ppa, visit as v, patient_program pp, program p where \n" + + "p.name = :programName and \n" + + "pp.program_id = p.program_id and pp.patient_id = v.patient_id\n" + + "and ppa.value_reference = :programEnrollmentId and ppa.attribute_type_id = 1 and\n" + + " v.date_started between :fromDate and :toDate and\n" + + "e.visit_id in (select e1.visit_id from encounter as e1 inner join episode_encounter on episode_encounter.encounter_id = e1.encounter_id) \n" + + "and v.patient_id in (select person_id from person as p2 where p2.uuid = :patientUUID) ;"; + + + + @Override + public List GetVisitIdsForProgramForLabResults(String patientUUID, String program, String programEnrollmentID, Date fromDate, Date toDate) { + Query query = this.sessionFactory.getCurrentSession().createSQLQuery(sqlGetVisitIdsForProgramForLabResults); + query.setParameter("patientUUID", patientUUID); + query.setParameter("programName", program); + query.setParameter("programEnrollmentId", programEnrollmentID); + query.setParameter("fromDate", fromDate); + query.setParameter("toDate", toDate); + + return query.list(); + } + + @Override + public List GetVisitIdsForVisitForLabResults(String patientUUID, String visit, Date visitStartDate) { + + Query query = this.sessionFactory.getCurrentSession().createSQLQuery(sqlGetVisitIdsForVisitForLabResults); + query.setParameter("patientUUID", patientUUID); + query.setParameter("visit", visit); + query.setParameter("visitStartDate",new java.sql.Timestamp(visitStartDate.getTime())); + return query.list(); + } + + @Override + public Visit getPatientVisit(Patient patient, String visitType, Date visitStartDate){ + Visit visit = visitService.getVisitsByPatient(patient) + .stream().filter(obj -> obj.getStartDatetime().getTime() == visitStartDate.getTime()) + .filter(obj -> obj.getVisitType().getName().equals(visitType)).collect(Collectors.toList()).get(0); + return visit; + } +} diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/impl/OPConsultDaoImpl.java b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/OPConsultDaoImpl.java new file mode 100644 index 00000000..505bb612 --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/OPConsultDaoImpl.java @@ -0,0 +1,278 @@ +package org.bahmni.module.hip.api.dao.impl; +import org.bahmni.module.hip.Config; +import org.bahmni.module.hip.api.dao.EncounterDao; +import org.bahmni.module.hip.api.dao.OPConsultDao; +import org.openmrs.Concept; +import org.openmrs.ConditionClinicalStatus; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.PatientProgram; +import org.openmrs.Visit; +import org.openmrs.api.EncounterService; +import org.openmrs.api.ObsService; +import org.openmrs.api.ProgramWorkflowService; +import org.openmrs.api.context.Context; +import org.openmrs.module.emrapi.conditionslist.Condition; +import org.openmrs.module.episodes.Episode; +import org.openmrs.module.episodes.service.EpisodeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import org.openmrs.api.ConditionService; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + + +@Repository +public class OPConsultDaoImpl implements OPConsultDao { + + private final ObsService obsService; + private final ConditionService conditionService; + private final EncounterService encounterService; + private final ProgramWorkflowService programWorkflowService; + private final EpisodeService episodeService; + private final EncounterDao encounterDao; + + + @Autowired + public OPConsultDaoImpl(ObsService obsService, ConditionService conditionService, EncounterService encounterService, ProgramWorkflowService programWorkflowService, EpisodeService episodeService, EncounterDao encounterDao) { + this.obsService = obsService; + this.conditionService = conditionService; + this.encounterService = encounterService; + this.programWorkflowService = programWorkflowService; + this.episodeService = episodeService; + this.encounterDao = encounterDao; + } + + + @Override + public Map> getMedicalHistoryConditions(Visit visit) { + final String conditionStatusHistoryOf = "HISTORY_OF"; + final String conditionStatusActive = "ACTIVE"; + List encounters = encounterDao.GetEncountersForVisit(visit, Config.CONSULTATION.getValue()); + if(encounters.size() == 0) + return new HashMap<>(); + List conditions = conditionService.getActiveConditions(visit.getPatient()) + .stream() + .filter(condition -> condition.getClinicalStatus().name().equals(conditionStatusActive) || + condition.getClinicalStatus().name().equals(conditionStatusHistoryOf)) + + .collect(Collectors.toList()); + List emrapiconditions = new ArrayList<>(); + for(org.openmrs.Condition condition : conditions){ + org.openmrs.module.emrapi.conditionslist.Condition emrapicondition = convertCoreConditionToEmrapiCondition(condition); + emrapiconditions.add(emrapicondition); + } + + Map> encounterConditionsMap = new HashMap<>(); + List nextEncounters = encounterService.getEncountersByPatient(visit.getPatient()).stream().filter(e -> + encounters.get(encounters.size()-1).getId() < e.getId() + ).collect(Collectors.toList()); + for(Condition condition : emrapiconditions) { + for (Encounter encounter: encounters) { + Encounter nextEncounter; + Date nextEncounterDate = nextEncounters.size() != 0 ? nextEncounters.get(0).getDateCreated() : new Date(); + if(encounters.indexOf(encounter) < (encounters.size() - 1)){ + nextEncounter = encounterService.getEncounter(encounters.get(encounters.indexOf(encounter)+1).getId()); + nextEncounterDate = nextEncounter.getDateCreated(); + } + if(condition.getDateCreated().equals(encounter.getDateCreated()) || (condition.getDateCreated().before(nextEncounterDate) && condition.getDateCreated().after(encounter.getDateCreated()))){ + if (encounterConditionsMap.containsKey(encounter)) { + encounterConditionsMap.get(encounter).add(condition); + } else { + encounterConditionsMap.put(encounter, new ArrayList() {{ + add(condition); + }}); + } + } + } + } + return encounterConditionsMap; + } + + + @Override + public List getMedicalHistoryDiagnosis(Visit visit) { + List medicalHistoryDiagnosisObsMap = encounterDao.GetAllObsForVisit(visit, Config.CONSULTATION.getValue(), Config.CODED_DIAGNOSIS.getValue()); + medicalHistoryDiagnosisObsMap.addAll(encounterDao.GetAllObsForVisit(visit, Config.CONSULTATION.getValue(), Config.NON_CODED_DIAGNOSIS.getValue())); + return medicalHistoryDiagnosisObsMap; + } + + @Override + public List getProcedures(Visit visit) { + List proceduresObsMap = encounterDao.GetAllObsForVisit(visit, Config.CONSULTATION.getValue(), Config.PROCEDURE_NOTES.getValue()).stream() + .filter(o -> !o.getVoided()) + .collect(Collectors.toList()); + + return proceduresObsMap; + } + + @Override + public List getProceduresForProgram(String programName, Date fromDate, Date toDate, Patient patient) { + List patientPrograms = programWorkflowService.getPatientPrograms(patient,programWorkflowService.getProgramByName(programName), fromDate, toDate,null,null,false); + Set patientProgramSet = new HashSet<>(patientPrograms); + List proceduresObsSet= new ArrayList<>(); + for (PatientProgram patientProgram: patientProgramSet) { + Episode episode = episodeService.getEpisodeForPatientProgram(patientProgram); + Set encounterSet = episode.getEncounters(); + for (Encounter encounter : encounterSet) { + for (Obs o : encounter.getAllObs()) { + if (Objects.equals(o.getEncounter().getEncounterType().getName(), Config.CONSULTATION.getValue()) + && !o.getVoided() + && Objects.equals(o.getConcept().getName().getName(), Config.PROCEDURE_NOTES.getValue()) + ) { + proceduresObsSet.add(o); + } + } + } + } + return proceduresObsSet; + } + + @Override + public Map> getMedicalHistoryConditionsForProgram(String programName, Date fromDate, Date toDate, Patient patient) { + final String conditionStatusHistoryOf = "HISTORY_OF"; + final String conditionStatusActive = "ACTIVE"; + List patientPrograms = programWorkflowService.getPatientPrograms(patient,programWorkflowService.getProgramByName(programName), fromDate, toDate,null,null,false); + List encounterList = new ArrayList<>(); + Set patientProgramSet = new HashSet<>(patientPrograms); + for (PatientProgram patientProgram: patientProgramSet) { + Episode episode = episodeService.getEpisodeForPatientProgram(patientProgram); + encounterList.addAll(episode.getEncounters()); + } + List encounters = encounterList + .stream() + .filter(encounter -> Objects.equals(encounter.getEncounterType().getName(), "Consultation")) + .collect(Collectors.toList()); + List conditions = conditionService.getActiveConditions(patient) + .stream() + .filter(condition -> condition.getClinicalStatus().name().equals(conditionStatusActive) || + condition.getClinicalStatus().name().equals(conditionStatusHistoryOf)) + .collect(Collectors.toList()); + + List emrapiconditions = new ArrayList<>(); + for(org.openmrs.Condition condition : conditions){ + org.openmrs.module.emrapi.conditionslist.Condition emrapicondition = convertCoreConditionToEmrapiCondition(condition); + emrapiconditions.add(emrapicondition); + } + + Map> encounterConditionsMap = new HashMap<>(); + + for(Condition condition : emrapiconditions){ + for(Encounter encounter : encounters){ + Encounter nextEncounter; + Date nextEncounterDate = new Date(); + if(encounters.indexOf(encounter) < (encounters.size() - 1)){ + nextEncounter = encounterService.getEncounter(encounters.get(encounters.indexOf(encounter)+1).getId()); + nextEncounterDate = nextEncounter.getDateCreated(); + } + if(condition.getDateCreated().equals(encounter.getDateCreated()) || condition.getDateCreated().after(encounter.getDateCreated()) && condition.getDateCreated().before(nextEncounterDate)) { + if(encounterConditionsMap.containsKey(encounter)) { + encounterConditionsMap.get(encounter).add(condition); + } else { + encounterConditionsMap.put(encounter, new ArrayList() {{ + add(condition); + }}); + } + } + } + } + return encounterConditionsMap; + } + + @Override + public List getMedicalHistoryDiagnosisForProgram(String programName, Date fromDate, Date toDate, Patient patient) { + List patientPrograms = programWorkflowService.getPatientPrograms(patient,programWorkflowService.getProgramByName(programName), fromDate, toDate,null,null,false); + Set patientProgramSet = new HashSet<>(patientPrograms); + List obsSet= new ArrayList<>(); + for (PatientProgram patientProgram: patientProgramSet) { + Episode episode = episodeService.getEpisodeForPatientProgram(patientProgram); + Set encounterSet = episode.getEncounters(); + for (Encounter encounter: encounterSet) { + for(Obs o : encounter.getAllObs()){ + if(Objects.equals(o.getEncounter().getEncounterType().getName(), Config.CONSULTATION.getValue()) + && Objects.equals(o.getConcept().getName().getName(), Config.CODED_DIAGNOSIS.getValue()) + && o.getValueCoded() != null + && o.getConcept().getName().getLocalePreferred()) + { + obsSet.add(o); + } + } + } + } + return obsSet; + } + + public Map> getPatientDocumentsForVisit(Visit visit){ + List patientObs = encounterDao.GetAllObsForVisit(visit, Config.PATIENT_DOCUMENT.getValue(),null) + .stream().filter(o -> !o.getConcept().getName().getName().equals(Config.DOCUMENT_TYPE.getValue()) ).collect(Collectors.toList()); + patientObs.addAll(encounterDao.GetAllObsForVisit(visit, Config.CONSULTATION.getValue(), Config.IMAGE.getValue())); + patientObs.addAll(encounterDao.GetAllObsForVisit(visit, Config.CONSULTATION.getValue(), Config.PATIENT_VIDEO.getValue())); + HashMap> encounterListMap = new HashMap<>(); + for (Obs obs: patientObs) { + Encounter encounter = obs.getEncounter(); + if(!encounterListMap.containsKey(encounter)) + encounterListMap.put(encounter, new ArrayList(){{ add(obs); }}); + else + encounterListMap.get(encounter).add(obs); + } + return encounterListMap; + } + + private org.openmrs.module.emrapi.conditionslist.Condition convertCoreConditionToEmrapiCondition(org.openmrs.Condition coreCondition) { + org.openmrs.module.emrapi.conditionslist.Condition cListCondition = new org.openmrs.module.emrapi.conditionslist.Condition(); + Concept concept; + + if (coreCondition.getCondition().getCoded() != null) { + concept = Context.getConceptService() + .getConceptByUuid(coreCondition.getCondition().getCoded().getUuid()); + + if(coreCondition.getCondition().getSpecificName() == null) { + coreCondition.getCondition().setSpecificName(coreCondition.getCondition().getCoded().getName(Context.getLocale())); + } + } else { + concept = new Concept(); + } + + cListCondition.setUuid(coreCondition.getUuid()); + cListCondition.setConcept(concept); + cListCondition.setAdditionalDetail(coreCondition.getAdditionalDetail()); + cListCondition.setPatient(coreCondition.getPatient()); + cListCondition.setConditionNonCoded(coreCondition.getCondition().getNonCoded()); + cListCondition.setOnsetDate(coreCondition.getOnsetDate()); + cListCondition.setVoided(coreCondition.getVoided()); + cListCondition.setVoidReason(coreCondition.getVoidReason()); + cListCondition.setEndDate(coreCondition.getEndDate()); + cListCondition.setCreator(coreCondition.getCreator()); + cListCondition.setDateCreated(coreCondition.getDateCreated()); + cListCondition.setStatus(convertClinicalStatus(coreCondition.getClinicalStatus())); + if (coreCondition.getPreviousVersion() != null) { + cListCondition.setPreviousCondition(convertCoreConditionToEmrapiCondition(coreCondition.getPreviousVersion())); + } + + return cListCondition; + } + + private Condition.Status convertClinicalStatus(ConditionClinicalStatus clinicalStatus) { + Condition.Status convertedStatus = Condition.Status.ACTIVE; + + if (clinicalStatus == ConditionClinicalStatus.ACTIVE) { + convertedStatus = Condition.Status.ACTIVE; + } else if (clinicalStatus == ConditionClinicalStatus.INACTIVE) { + convertedStatus = Condition.Status.INACTIVE; + } else if (clinicalStatus == ConditionClinicalStatus.HISTORY_OF) { + convertedStatus = Condition.Status.HISTORY_OF; + } + + return convertedStatus; + } +} diff --git a/api/src/main/java/org/bahmni/module/hip/api/dao/impl/PrescriptionOrderDaoImpl.java b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/PrescriptionOrderDaoImpl.java new file mode 100644 index 00000000..81e3cf16 --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/api/dao/impl/PrescriptionOrderDaoImpl.java @@ -0,0 +1,60 @@ +package org.bahmni.module.hip.api.dao.impl; + +import org.bahmni.module.hip.api.dao.EncounterDao; +import org.bahmni.module.hip.api.dao.PrescriptionOrderDao; +import org.hibernate.Criteria; +import org.hibernate.SessionFactory; +import org.hibernate.criterion.Restrictions; +import org.openmrs.DrugOrder; +import org.openmrs.Order; +import org.openmrs.OrderType; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.OrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +@Repository +public class PrescriptionOrderDaoImpl implements PrescriptionOrderDao { + private SessionFactory sessionFactory; + private EncounterDao encounterDao; + private final OrderService orderService; + + @Autowired + public PrescriptionOrderDaoImpl(SessionFactory sessionFactory, EncounterDao encounterDao, OrderService orderService) { + this.sessionFactory = sessionFactory; + this.encounterDao = encounterDao; + this.orderService = orderService; + } + + public List getDrugOrders(Visit visit) { + List orderLists = encounterDao.GetOrdersForVisit(visit).stream() + .filter(order -> order.getOrderType().getUuid().equals(OrderType.DRUG_ORDER_TYPE_UUID)) + .map(order -> (DrugOrder) order) + .collect(Collectors.toList()); + + return orderLists; + } + + public List getDrugOrdersForProgram(Patient patient, Date fromDate, Date toDate, OrderType orderType, String program, String programEnrollmentId) { + + Integer [] encounterIds = encounterDao.GetEncounterIdsForProgramForPrescriptions(patient.getUuid(), program, programEnrollmentId, fromDate, toDate).toArray(new Integer[0]); + if(encounterIds.length == 0) + return new ArrayList< DrugOrder > (); + Criteria criteria = this.sessionFactory.getCurrentSession().createCriteria(Order.class); + criteria.createCriteria("encounter", "e") + .createCriteria("visit", "v"); + criteria.add(Restrictions.eq("patient", patient)); + criteria.add(Restrictions.eq("orderType", orderType)); + criteria.add(Restrictions.eq("voided", false)); + criteria.add(Restrictions.in( "e.encounterId", encounterIds)); + criteria.add(Restrictions.between("dateCreated", fromDate, toDate)); + return criteria.list(); + } + +} diff --git a/api/src/main/java/org/bahmni/module/hip/model/PatientCareContext.java b/api/src/main/java/org/bahmni/module/hip/model/PatientCareContext.java new file mode 100644 index 00000000..58605fd3 --- /dev/null +++ b/api/src/main/java/org/bahmni/module/hip/model/PatientCareContext.java @@ -0,0 +1,22 @@ +package org.bahmni.module.hip.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@NoArgsConstructor +@Setter +@Getter +@Builder +@AllArgsConstructor +public class PatientCareContext { + private String careContextType; + private String careContextName; + private String careContextReference; + + public String getCareContextName() { + return careContextName; + } +} diff --git a/api/src/main/resources/liquibase.xml b/api/src/main/resources/liquibase.xml index 0fa49c63..3666d543 100644 --- a/api/src/main/resources/liquibase.xml +++ b/api/src/main/resources/liquibase.xml @@ -1,40 +1,133 @@ - - - - - - - - \ No newline at end of file + + + + + + + SELECT COUNT(*) FROM users where username = 'admin' + + + Populate username for admin user + + + system_id='admin' + + + + + + select count(*) from patient_identifier_type where name='ABHA Number' + + Adding ABHA Number Identifier type + + insert into patient_identifier_type( name, description,creator, uuid, uniqueness_behavior, location_behavior, date_created) Select 'ABHA Number','Health Id identifier type',creator,uuid(),'UNIQUE','NOT_USED',now() from users where username='admin'; + + + + + + select count(*) from patient_identifier_type where name='ABHA Number' + select count(*) from global_property where property = 'bahmni.extraPatientIdentifierTypes' and property_value LIKE CONCAT('%', (Select uuid from patient_identifier_type where name = 'ABHA Number')) + + Updating global property for ABHA Number + + update global_property set property_value=(SELECT CONCAT(IF(ISNULL(property_value),'',CONCAT(property_value,',')),uuid) from patient_identifier_type where name = 'ABHA Number') where property = 'bahmni.extraPatientIdentifierTypes'; + + + + + + select count(*) from patient_identifier_type where name='ABHA Address' + + Adding ABHA Address Identifier type + + insert into patient_identifier_type( name, description,creator, uuid, uniqueness_behavior, location_behavior, date_created) Select 'ABHA Address','PHR Address identifier type',creator,uuid(),'UNIQUE','NOT_USED',now() from users where username='admin'; + + + + + + select count(*) from patient_identifier_type where name='ABHA Address' + select count(*) from global_property where property = 'bahmni.extraPatientIdentifierTypes' and property_value LIKE CONCAT('%', (Select uuid from patient_identifier_type where name = 'ABHA Address')) + + Updating global property for ABHA address + + update global_property set property_value=(SELECT CONCAT(IF(ISNULL(property_value),'',CONCAT(property_value,',')),uuid) from patient_identifier_type where name = 'ABHA Address') where property = 'bahmni.extraPatientIdentifierTypes'; + + + + + + + select count(*) from global_property where property = 'mrs.genders' and property_value='{"M":"Male", "F":"Female","O":"Other"}' + + + Adding Undisclosed to gender + + update global_property set property_value='{"M":"Male", "F":"Female","O":"Other", "U":"Undisclosed"}' where property = 'mrs.genders'; + + + + + + select count(*) from global_property where property='abdm.encounterTypesToBeIgnored' + + Adding global property for encounter types to be ignored + + insert into global_property(property,description,property_value,uuid) values('abdm.encounterTypesToBeIgnored','Encounter types to be ignored for hip atomfeeds','ADMISSION,REG,TRANSFER,VALIDATION NOTES',uuid()); + + + + + + select count(*) from global_property where property='abdm.formFieldsToBeIgnored' + + Adding global property for form fields to be ignored + + insert into global_property(property,description,property_value,uuid) values('abdm.formFieldsToBeIgnored','Form fields to be ignored for hip atomfeeds','',uuid()); + + + + + + select count(*) from global_property where property='abdm.conceptsTypesToBeIgnored' + + Adding global property for concept types to be ignored + + insert into global_property(property,description,property_value,uuid) values('abdm.conceptsTypesToBeIgnored','Concept types to be ignored for hip atomfeeds','',uuid()); + + + + + select count(*) from privilege where privilege='app:abdm' + + Adding new privilage for ABDM services + + insert into privilege(privilege,description,uuid) values('app:abdm','privilege to view abdm services',uuid()); + + + + + select count(*) from role where role='ABDM' + + Adding new role for ABDM services + + insert into role(role,description,uuid) values('ABDM','Will have full access to abdm services',uuid()); + + + + + select count(*) from role where role='ABDM' + select count(*) from privilege where privilege='app:abdm' + + Providing abdm privilege to ABDM role + + insert into role_privilege(role,privilege) values('ABDM','app:abdm'); + + + + diff --git a/basicmodule.iml b/basicmodule.iml new file mode 100644 index 00000000..f409c0ea --- /dev/null +++ b/basicmodule.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/omod/basicmodule-omod.iml b/omod/basicmodule-omod.iml new file mode 100644 index 00000000..1a0706ef --- /dev/null +++ b/omod/basicmodule-omod.iml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/omod/docs/dev-setup.md b/omod/docs/dev-setup.md new file mode 100644 index 00000000..85165471 --- /dev/null +++ b/omod/docs/dev-setup.md @@ -0,0 +1,230 @@ +### Important links for reference: +- [OPENMRS WIKI](https://wiki.openmrs.org/) +- [FHIR](https://hl7.org/FHIR/documentation.html) +- [SBX healthID creation](https://healthidsbx.ndhm.gov.in/) +- [HIU](https://dev.ndhm.gov.in/hiu#/) +- [PHR/NDHM Architecture](https://sandbox.ndhm.gov.in/docs/building_blocks) +- [HIP API Standards](https://sandbox.ndhm.gov.in/swagger/ndhm-hip.yaml) + + +## Services: +Clone the basic 5 services: +- [OMOD-HIP](https://github.com/Bahmni-Covid19/openmrs-module-hip.git) +- [Hip Service](https://github.com/Bahmni-Covid19/hip-service) +- [BahmniApps](https://github.com/Bahmni-Covid19/openmrs-module-bahmniapps) +- [Ndhm-React](https://github.com/Bahmni-Covid19/ndhm-react) +- [Default-config](https://github.com/Bahmni-Covid19/default-config) + +Others can be found here : [Bahmni-Covid19](https://github.com/Bahmni-Covid19/) + +### Setup Bahmni using Vagrant: + +1. Install [Virtualbox](https://www.virtualbox.org/wiki/Downloads) +2. Install [Vagrant](https://www.vagrantup.com/downloads.html) +3. Clone the `bahmni-vagrant` repo from github inside a folder called `bahmni` + + ``` + mkdir bahmni + cd bahmni + git clone https://github.com/Bahmni/bahmni-vagrant.git + cd bahmni-vagrant + ``` + +4. Replace the contents of the `Vagrantfile` in `bahmni-vagrant` with the following: + + ``` + Vagrant.configure(2) do |config| + config.vm.box = "bento/centos-7.6" + config.vm.box_check_update = true + config.ssh.insert_key = false + config.vm.network "private_network", ip: "192.168.33.10" + config.vm.network "forwarded_port", guest: 3306, host: 3306 + config.vm.network "forwarded_port", guest: 8000, host: 8000 + config.vm.network "forwarded_port", guest: 80, host: 80 + + config.vm.synced_folder "..", "/bahmni", :owner => "vagrant" + config.vm.provider "virtualbox" do |v| + v.customize ["modifyvm", :id, "--memory", 3092, "--cpus", 2, "--name", "Bahmni-RPM"] + end + end + ``` + +5. Make vagrant up and open vagrant + + ``` + vagrant up && vagrant ssh + ``` + +6. Now, inside the vagrant box set up a local Bahmni instance by using this document +(Note: install the version 0.92 provided in the [link](https://bahmni.atlassian.net/wiki/spaces/BAH/pages/33128505/Install+Bahmni+on+CentOS)) + +7. Open [bahmni-emr-login](https://192.168.33.10/bahmni/home/index.html#/login), you should see bahmni up and running. + - Username: superman + - Password: Admin123 + +### Prerequisites for OMOD-HIP: + +- Download following jars and fhir + - [jackson-core-2.10.0.jar](https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.10.0/jackson-core-2.10.0.jar) + - [jackson-annotations-2.10.0.jar](https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.10.0/jackson-annotations-2.10.0.jar) + - [jackson-databind-2.10.0.jar](https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.10.0/jackson-databind-2.10.0.jar) + - [fhir2-omod-1.0.0-SNAPSHOT.omod](https://drive.google.com/drive/folders/180cdYOWqBU5vffZnzdRy5PsyEPvn3Ti5) +- Copy all files to `bahmni` folder +- Open vagrant and paste the files + + ``` + cd bahmni-vagrant + vagrant ssh + cp /bahmni/jackson-core-2.10.0.jar /opt/openmrs/openmrs/WEB-INF/lib/ + cp /bahmni/jackson-annotations-2.10.0.jar /opt/openmrs/openmrs/WEB-INF/lib/ + cp /bahmni/jackson-databind-2.10.0.jar /opt/openmrs/openmrs/WEB-INF/lib/ + cp /bahmni/fhir2-omod-1.0.0-SNAPSHOT.omod /opt/openmrs/modules/ + ``` +- Restart openmrs `systemctl restart openmrs` + +- Ensure that the module is successfully loaded by navigating through [openmrs](http://192.168.33.10/openmrs) + - username: superman + - password: Admin123 + - Click on `Administration` -> `Manage Modules` under `Modules` +- You can also check the log file for any errors/exceptions: `vi /opt/openmrs/openmrs.log` + in vagrant. + +### Setting up the OMOD-HIP + +(Make sure `bahmni` folder is created and `bahmni vagrant` is setup inside `bahmni`) +1. Clone OMOD-HIP + + ``` + cd bahmni + git clone https://github.com/Bahmni-Covid19/openmrs-module-hip.git + ``` + +2. Run the steps to build .omod file + + ``` + cd openmrs-module-hip + mvn clean install + ``` + +3. Move the newly build omod to vagrant and overwrite it and restart OMOD with the new omod + + ``` + vagrant ssh + sudo su + cp /bahmni/openmrs-module-hip/omod/target/hipmodule-omod-0.1-SNAPSHOT.omod /opt/openmrs/modules/ + systemctl restart openmrs + ``` + +4. (Optional) Check log file to see if any errors occurred inside vagrant + + ``` + vi /opt/openmrs/openmrs.log + + ``` +### Installations: + +Please make sure following are done before proceeding forward +- [Yarn](https://classic.yarnpkg.com/en/) +- [Node.js(v10.11.0)](https://classic.yarnpkg.com/en/) +- [Maven](https://maven.apache.org/) +- [Ruby v2.1 (or above)](https://www.ruby-lang.org/en/documentation/installation/) +- [Compass](http://compass-style.org/install/) to compile the SCSS files. +- Install Firefox to run tests for `bahmni-apps` + +### Setting up Bahmni-Apps + +1. Clone bahmni-apps + + ``` + cd bahmni + git clone https://github.com/Bahmni-Covid19/openmrs-module-bahmniapps.git + cd openmrs-module-bahmniapps + ``` + +2. Change branch to stream1/master (which is the current working master for Hip stream) + + ``` + git checkout stream1/master + ``` + +3. Run following to build the project + ``` + cd /ui + yarn install + yarn default + ``` +### Setting up ndhm-react (verify-btn pop-up) + +1. Clone ndhm-react + + ``` + cd bahmni + git clone https://github.com/Bahmni-Covid19/ndhm-react.git + cd ndhm-react + ``` + +2. In main branch run following to build project + + ``` + yarn install + yarn build + ``` + +### Setting up default-config + +1. Clone default-config + + ``` + cd bahmni + git clone https://github.com/Bahmni-Covid19/default-config.git + cd default-config + ``` +2. Change branch to stream1/master (which is the current working master for Hip stream) + + ``` + git checkout stream1/master + ``` +3. Browse to this file `openmrs/apps/registration/extension.json` and change host to localhost in `NDHMIdentifierLookup`,`extensionParams` + + ``` + "hipUrl" : "http://localhost:9052", + "bahmniUrl": "https://192.168.33.10/openmrs/ws/rest/v1/hip" + ``` + +## Linking the repos inside your local vagrant + +1. Go inside local vagrant + + ``` + cd bahmni-vagrant + vagrant ssh + cd /var/www/ + ll + ``` + you will see bahmniapps and bahmni_config being linked already to older versions, we will unlink and link to our local repos +2. Unlink old links + + ``` + unlink bahmniapps + unlink bahmni_config + ``` + +3. Link new build repositories + + ``` + ln -s /bahmni/ndhm-react/build ndhm + ln -s /bahmni/default-config bahmni_config + ln -s /bahmni/openmrs-module-bahmniapps/ui/app bahmniapps + ``` + +4. Change config setting for `ndhm` redirection + + ``` + vi /etc/httpd/conf.d/ssl.conf + ``` + +5. Search for Alias by typing `/Alias` and after this line `Alias /implementer-interface /var/www/implementer_interface` add + + ``` + Alias /ndhm /var/www/ndhm + ``` diff --git a/omod/pom.xml b/omod/pom.xml index 184afcfa..fd1dcd6f 100644 --- a/omod/pom.xml +++ b/omod/pom.xml @@ -1,43 +1,215 @@ - 4.0.0 - - org.openmrs.module - basicmodule - 0.1-SNAPSHOT - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + 4.0.0 + + org.bahmni.module + hipmodule + 0.1-SNAPSHOT + - basicmodule-omod - jar - Basic Module OMOD - OpenMRS module project for Basic Module + hipmodule-omod + jar + HIP Module OMOD + OpenMRS module project for HIP Module + + + repo.mybahmni.org + bahmni-artifactory-snapshots + https://oss.sonatype.org/content/repositories/snapshots + + always + + + + repo.mybahmni.org-release + bahmni-artifactory-release + https://oss.sonatype.org/content/repositories/release + + - + + + org.openmrs.api + openmrs-api + ${openMRSVersion} + jar + provided + + + javax.servlet + servlet-api + + + + org.openmrs.module - basicmodule-api - ${project.parent.version} - - - org.openmrs.web - openmrs-web - provided - - - - - ${project.parent.artifactId}-${project.parent.version} - - - - org.openmrs.maven.plugins - maven-openmrs-plugin - - - org.apache.maven.plugins - maven-dependency-plugin - - - + episodes-api + 1.0-SNAPSHOT + provided + + + org.bahmni.module + hipmodule-api + 0.1-SNAPSHOT + + + org.openmrs.web + openmrs-web + provided + ${openMRSVersion} + + + org.openmrs.module + webservices.rest-omod + provided + + + org.openmrs.module + fhir2-omod + ${fhir2ModuleVersion} + provided + + + + org.bahmni.module + bahmnicore-api + 0.94-SNAPSHOT + provided + + + rome + rome + + + + + + org.bahmni.module + bahmni-commons-api + + + + org.projectlombok + lombok + 1.18.10 + provided + + + + javax.servlet + javax.servlet-api + 3.0.1 + provided + + + + + + + + + javax.xml.bind + jaxb-api + 2.3.0 + test + + + com.fasterxml.jackson.core + jackson-core + 2.10.1 + test + + + + + + + + + org.springframework.boot + spring-boot-starter-test + 2.1.10.RELEASE + + + org.springframework.boot + spring-boot-starter-logging + + + test + + + javax.xml.bind + jaxb-api + 2.3.0 + test + + + org.openmrs.module + emrapi-api + provided + + + org.openmrs.module + emrapi-omod + provided + + + + + ${project.artifactId}-${project.version} + + + + org.openmrs.maven.plugins + maven-openmrs-plugin + true + + + init + initialize + + initialize-module + + + + pack + package + + package-module + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + Expand moduleApplicationContext and messages + + unpack-dependencies + + generate-resources + + ${project.parent.groupId} + ${project.parent.artifactId}-api + true + **/* + ${project.build.directory}/classes + + + + org.apache.maven.pluginsmaven-compiler-plugin1111 + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + + + diff --git a/omod/src/main/java/org/bahmni/module/hip/web/client/ClientError.java b/omod/src/main/java/org/bahmni/module/hip/web/client/ClientError.java new file mode 100644 index 00000000..5e09bbe0 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/client/ClientError.java @@ -0,0 +1,54 @@ +package org.bahmni.module.hip.web.client; + +import org.bahmni.module.hip.web.client.model.ErrorCode; +import lombok.Getter; +import lombok.ToString; + +import java.util.HashMap; + +@Getter +@ToString +public class ClientError { + private static HashMap errorMap = new HashMap<>(); + private Integer code; + private String message; + + public ClientError(Integer code, String message) { + this.code = code; + this.message = message; + } + + public static ClientError invalidPatientId() { + return new ClientError(ErrorCode.BAD_REQUEST.getValue(), "Invalid patient id"); + } + + public static ClientError noPatientFound() { + return new ClientError(ErrorCode.PATIENT_ID_NOT_FOUND.getValue(), "No patient found"); + } + + public static ClientError noPatientIdProvided() { + return new ClientError(ErrorCode.NO_PATIENT_ID_SUPPLIED.getValue(), "No Patient ID supplied"); + } + public static ClientError noVisitTypeProvided(){ + return new ClientError(ErrorCode.NO_VISIT_TYPE_SUPPLIED.getValue(),"No Visit type is supplied"); + } + public static ClientError noVisitStartDateProvided(){ + return new ClientError(ErrorCode.NO_VISIT_START_DATE_SUPPLIED.getValue(),"No Visit start date is supplied"); + } + public static ClientError invalidVisitType(){ + return new ClientError(ErrorCode.INVALID_VISIT_TYPE.getValue(),"Visit Type is invalid"); + } + public static ClientError noProgramNameProvided(){ + return new ClientError(ErrorCode.NO_PROGRAM_NAME_SUPPLIED.getValue(),"No program name supplied"); + } + public static ClientError noProgramIDProvided(){ + return new ClientError(ErrorCode.NO_PROGRAM_ID_SUPPLIED.getValue(),"No patient's program enrollment id supplied"); + } + public static ClientError invalidProgramName(){ + return new ClientError(ErrorCode.INVALID_PROGRAM_NAME.getValue(),"Program specified does not exist"); + } + public static ClientError patientIdentifierNotFound(){ + return new ClientError(ErrorCode.PATIENT_IDENTIFIER_NOT_FOUND.getValue(),"Patient identifier not found"); + } + +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/client/model/Error.java b/omod/src/main/java/org/bahmni/module/hip/web/client/model/Error.java new file mode 100644 index 00000000..6a716d64 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/client/model/Error.java @@ -0,0 +1,19 @@ +package org.bahmni.module.hip.web.client.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@JsonIgnoreProperties(ignoreUnknown = true) +@AllArgsConstructor +@Builder +@NoArgsConstructor +@Data +public class Error { + private ErrorCode code; + private String message; +} + + diff --git a/omod/src/main/java/org/bahmni/module/hip/web/client/model/ErrorCode.java b/omod/src/main/java/org/bahmni/module/hip/web/client/model/ErrorCode.java new file mode 100644 index 00000000..a218a97e --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/client/model/ErrorCode.java @@ -0,0 +1,39 @@ +package org.bahmni.module.hip.web.client.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Arrays; + +public enum ErrorCode { + UNKNOWN_ERROR_OCCURRED(1500), + BAD_REQUEST(1501), + PATIENT_ID_NOT_FOUND(1502), + NO_PATIENT_ID_SUPPLIED (1503), + NO_VISIT_TYPE_SUPPLIED(1504), + INVALID_VISIT_TYPE(1505), + NO_PROGRAM_NAME_SUPPLIED (1506), + NO_PROGRAM_ID_SUPPLIED(1507), + INVALID_PROGRAM_NAME(1508), + PATIENT_IDENTIFIER_NOT_FOUND(1509), + NO_VISIT_START_DATE_SUPPLIED(1510); + private final int value; + + ErrorCode(int val) { + value = val; + } + + // Adding @JsonValue annotation that tells the 'value' to be of integer type while de-serializing. + @JsonValue + public int getValue() { + return value; + } + + @JsonCreator + public static ErrorCode getNameByValue(int value) { + return Arrays.stream(ErrorCode.values()) + .filter(errorCode -> errorCode.value == value) + .findAny() + .orElse(ErrorCode.UNKNOWN_ERROR_OCCURRED); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/client/model/ErrorRepresentation.java b/omod/src/main/java/org/bahmni/module/hip/web/client/model/ErrorRepresentation.java new file mode 100644 index 00000000..14bcf144 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/client/model/ErrorRepresentation.java @@ -0,0 +1,16 @@ +package org.bahmni.module.hip.web.client.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@JsonIgnoreProperties(ignoreUnknown = true) +@AllArgsConstructor +@Builder +@NoArgsConstructor +@Data +public class ErrorRepresentation { + private Error error; +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/client/model/RespError.java b/omod/src/main/java/org/bahmni/module/hip/web/client/model/RespError.java new file mode 100644 index 00000000..0b2ea3bd --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/client/model/RespError.java @@ -0,0 +1,19 @@ +package org.bahmni.module.hip.web.client.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@JsonIgnoreProperties(ignoreUnknown = true) +@AllArgsConstructor +@Builder +@NoArgsConstructor +@Data +public class RespError implements Serializable { + private Integer code; + private String message; +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/client/model/Status.java b/omod/src/main/java/org/bahmni/module/hip/web/client/model/Status.java new file mode 100644 index 00000000..256f4b2e --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/client/model/Status.java @@ -0,0 +1,7 @@ +package org.bahmni.module.hip.web.client.model; + +public enum Status { + DEACTIVATED, + REACTIVATED, + DELETED +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/config/OpenMRSConfig.java b/omod/src/main/java/org/bahmni/module/hip/web/config/OpenMRSConfig.java new file mode 100644 index 00000000..96186288 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/config/OpenMRSConfig.java @@ -0,0 +1,21 @@ +package org.bahmni.module.hip.web.config; + +import org.openmrs.api.OrderService; +import org.openmrs.api.PatientService; +import org.openmrs.api.context.Context; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class OpenMRSConfig { + + @Bean + public PatientService patientService() { + return Context.getPatientService(); + } + + @Bean + public OrderService orderService() { + return Context.getOrderService(); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/controller/BundledMedicationRequestController.java b/omod/src/main/java/org/bahmni/module/hip/web/controller/BundledMedicationRequestController.java new file mode 100644 index 00000000..d97f9ce4 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/controller/BundledMedicationRequestController.java @@ -0,0 +1,54 @@ +package org.bahmni.module.hip.web.controller; + +import org.bahmni.module.hip.web.client.ClientError; +import org.bahmni.module.hip.web.service.BundleMedicationRequestService; +import org.bahmni.module.hip.web.service.ValidationService; +import org.hl7.fhir.r4.model.Bundle; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import static org.bahmni.module.hip.web.model.serializers.BundleSerializer.serializeBundle; + +@Validated +@RestController +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/hip") +public class BundledMedicationRequestController extends BaseRestController { + private final BundleMedicationRequestService bundledMedicationRequestService; + private final ValidationService validationService; + + @Autowired + public BundledMedicationRequestController(BundleMedicationRequestService bundledMedicationRequestService, ValidationService validationService) { + this.bundledMedicationRequestService = bundledMedicationRequestService; + this.validationService = validationService; + } + + @RequestMapping(method = RequestMethod.GET, value = "/medication", produces = MediaType.APPLICATION_JSON_VALUE) + public @ResponseBody + ResponseEntity getBundledMedicationRequestFor(@RequestParam(required = false) String patientId, + @RequestParam(required = false) String visitType) { + + if (patientId == null || patientId.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noPatientIdProvided()); + if (visitType == null || visitType.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noVisitTypeProvided()); + if (!validationService.isValidVisit(visitType)) + return ResponseEntity.badRequest().body(ClientError.invalidVisitType()); + if (!validationService.isValidPatient(patientId)) + return ResponseEntity.badRequest().body(ClientError.invalidPatientId()); + Bundle bundle = bundledMedicationRequestService.bundleMedicationRequestsFor(patientId, visitType); + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .body(serializeBundle(bundle)); + } + +} \ No newline at end of file diff --git a/omod/src/main/java/org/bahmni/module/hip/web/controller/CareContextController.java b/omod/src/main/java/org/bahmni/module/hip/web/controller/CareContextController.java new file mode 100644 index 00000000..88656f49 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/controller/CareContextController.java @@ -0,0 +1,62 @@ +package org.bahmni.module.hip.web.controller; + +import org.bahmni.module.hip.web.client.ClientError; +import org.bahmni.module.hip.web.service.CareContextService; +import org.bahmni.module.hip.web.service.ValidationService; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/hip") +@RestController +public class CareContextController extends BaseRestController { + private final CareContextService careContextService; + private final ValidationService validationService; + + @Autowired + public CareContextController(CareContextService careContextService, ValidationService validationService) { + this.careContextService = careContextService; + this.validationService = validationService; + } + + @RequestMapping(method = RequestMethod.GET, value = "/careContext", produces = MediaType.APPLICATION_JSON_VALUE) + public @ResponseBody + ResponseEntity getCareContextForPatient(@RequestParam(required = false) String patientUuid) { + if (patientUuid == null || patientUuid.trim().isEmpty()) { + return ResponseEntity.badRequest().body(ClientError.noPatientIdProvided()); + } + if (!validationService.isValidPatient(patientUuid)) + return ResponseEntity.badRequest().body(ClientError.invalidPatientId()); + Object careContextForPatient = careContextService.careContextForPatient(patientUuid); + if (careContextForPatient.equals(false)) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ClientError.noPatientFound()); + } + return ResponseEntity.ok(careContextForPatient); + } + + @RequestMapping(method = RequestMethod.GET, value = "/careContext/new", produces = MediaType.APPLICATION_JSON_VALUE) + public @ResponseBody + ResponseEntity getNewCareContextForPatient(@RequestParam(required = false) String patientUuid) { + if (patientUuid == null || patientUuid.trim().isEmpty()) { + return ResponseEntity.badRequest().body(ClientError.noPatientIdProvided()); + } + if (!validationService.isValidPatient(patientUuid)) + return ResponseEntity.badRequest().body(ClientError.invalidPatientId()); + Object careContextForPatient = careContextService.newCareContextsForPatient(patientUuid); + if (careContextForPatient.equals(false)) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ClientError.noPatientFound()); + } + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .body(careContextForPatient); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/controller/DiagnosticReportController.java b/omod/src/main/java/org/bahmni/module/hip/web/controller/DiagnosticReportController.java new file mode 100644 index 00000000..dac59373 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/controller/DiagnosticReportController.java @@ -0,0 +1,105 @@ +package org.bahmni.module.hip.web.controller; + +import org.bahmni.module.hip.web.client.ClientError; +import org.bahmni.module.hip.web.model.BundledDiagnosticReportResponse; +import org.bahmni.module.hip.web.model.DateRange; +import org.bahmni.module.hip.web.model.DiagnosticReportBundle; +import org.bahmni.module.hip.web.service.DiagnosticReportService; +import org.bahmni.module.hip.web.service.ValidationService; +import org.codehaus.jackson.map.ObjectMapper; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; + +import static org.bahmni.module.hip.web.utils.DateUtils.isDateBetweenDateRange; +import static org.bahmni.module.hip.web.utils.DateUtils.parseDate; +import static org.bahmni.module.hip.web.utils.DateUtils.parseDateTime; + +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/hip/diagnosticReports") +@RestController +public class DiagnosticReportController extends BaseRestController { + private final DiagnosticReportService diagnosticReportService; + private final ValidationService validationService; + private final ObjectMapper mapper = new ObjectMapper(); + + @Autowired + public DiagnosticReportController(DiagnosticReportService diagnosticReportService, ValidationService validationService) { + this.diagnosticReportService = diagnosticReportService; + this.validationService = validationService; + } + + @RequestMapping(method = RequestMethod.GET, value = "/visit", produces = MediaType.APPLICATION_JSON_VALUE) + public @ResponseBody + ResponseEntity getDiagnosticReportsForVisit(@RequestParam String patientId, + @RequestParam String visitType, + @RequestParam String visitStartDate, + @RequestParam String fromDate, + @RequestParam String toDate) throws ParseException, IOException { + if (patientId == null || patientId.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noPatientIdProvided()); + if (visitType == null || visitType.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noVisitTypeProvided()); + if (visitStartDate == null || visitStartDate.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noVisitTypeProvided()); + if (!validationService.isValidVisit(visitType)) + return ResponseEntity.badRequest().body(ClientError.invalidVisitType()); + if (!validationService.isValidPatient(patientId)) + return ResponseEntity.badRequest().body(ClientError.invalidPatientId()); + + List diagnosticReportBundle = new ArrayList<>(); + if(isDateBetweenDateRange(visitStartDate,fromDate,toDate)) { + diagnosticReportBundle = diagnosticReportService.getDiagnosticReportsForVisit(patientId, visitType, parseDateTime(visitStartDate)); + + diagnosticReportBundle.addAll(diagnosticReportService.getLabResultsForVisits(patientId, visitType, parseDateTime(visitStartDate))); + } + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .body(mapper.writeValueAsString(new BundledDiagnosticReportResponse(diagnosticReportBundle))); + } + + @RequestMapping(method = RequestMethod.GET, value = "/program", produces = MediaType.APPLICATION_JSON_VALUE) + public @ResponseBody + ResponseEntity getDiagnosticReportsForProgram( + @RequestParam String patientId, + @RequestParam String fromDate, + @RequestParam String toDate, + @RequestParam String programName, + @RequestParam String programEnrollmentId + ) throws ParseException, IOException { + programName = URLDecoder.decode(programName, "UTF-8"); + if (patientId == null || patientId.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noPatientIdProvided()); + if (programName == null || programName.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noVisitTypeProvided()); + if (!validationService.isValidProgram(programName)) + return ResponseEntity.badRequest().body(ClientError.invalidProgramName()); + if (!validationService.isValidPatient(patientId)) + return ResponseEntity.badRequest().body(ClientError.invalidPatientId()); + List diagnosticReportBundles = + diagnosticReportService.getDiagnosticReportsForProgram(patientId, new DateRange(parseDate(fromDate), + parseDate(toDate)), programName, programEnrollmentId); + + diagnosticReportBundles.addAll( + diagnosticReportService.getLabResultsForPrograms(patientId, new DateRange(parseDate(fromDate), + parseDate(toDate)), programName, programEnrollmentId) ); + + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .body(mapper.writeValueAsString(new BundledDiagnosticReportResponse(diagnosticReportBundles))); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/controller/DischargeSummaryController.java b/omod/src/main/java/org/bahmni/module/hip/web/controller/DischargeSummaryController.java new file mode 100644 index 00000000..846f6fb2 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/controller/DischargeSummaryController.java @@ -0,0 +1,106 @@ +package org.bahmni.module.hip.web.controller; + +import org.bahmni.module.hip.web.client.ClientError; +import org.bahmni.module.hip.web.model.BundledDischargeSummaryResponse; +import org.bahmni.module.hip.web.model.DateRange; +import org.bahmni.module.hip.web.model.DischargeSummaryBundle; +import org.bahmni.module.hip.web.service.DischargeSummaryService; +import org.bahmni.module.hip.web.service.ValidationService; +import org.codehaus.jackson.map.ObjectMapper; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RequestParam; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; + +import static org.bahmni.module.hip.web.utils.DateUtils.isDateBetweenDateRange; +import static org.bahmni.module.hip.web.utils.DateUtils.parseDate; +import static org.bahmni.module.hip.web.utils.DateUtils.parseDateTime; + +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/hip/dischargeSummary") +@RestController +public class DischargeSummaryController extends BaseRestController { + + private final ValidationService validationService; + private final DischargeSummaryService dischargeSummaryService; + private final ObjectMapper mapper = new ObjectMapper(); + + @Autowired + public DischargeSummaryController(ValidationService validationService, DischargeSummaryService dischargeSummaryService) { + this.validationService = validationService; + this.dischargeSummaryService = dischargeSummaryService; + } + + @RequestMapping(method = RequestMethod.GET, value = "/visit", produces = MediaType.APPLICATION_JSON_VALUE) + public @ResponseBody + ResponseEntity getDischargeSummaryForVisit(@RequestParam String patientId, + @RequestParam String visitType, + @RequestParam String visitStartDate, + @RequestParam String fromDate, + @RequestParam String toDate) throws ParseException, IOException { + + if (patientId == null || patientId.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noPatientIdProvided()); + if (visitType == null || visitType.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noVisitTypeProvided()); + if (visitStartDate == null || visitStartDate.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noVisitTypeProvided()); + if (!validationService.isValidVisit(visitType)) + return ResponseEntity.badRequest().body(ClientError.invalidVisitType()); + if (!validationService.isValidPatient(patientId)) + return ResponseEntity.badRequest().body(ClientError.invalidPatientId()); + + List dischargeSummaryBundle = new ArrayList<>(); + if(isDateBetweenDateRange(visitStartDate,fromDate,toDate)) { + dischargeSummaryBundle = dischargeSummaryService.getDischargeSummaryForVisit(patientId, visitType, parseDateTime(visitStartDate)); + } + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .body(mapper.writeValueAsString(new BundledDischargeSummaryResponse(dischargeSummaryBundle))); + } + + @RequestMapping(method = RequestMethod.GET, value = "/program", produces = MediaType.APPLICATION_JSON_VALUE) + public @ResponseBody + ResponseEntity getDischargeSummaryForProgram( + @RequestParam String patientId, + @RequestParam String fromDate, + @RequestParam String toDate, + @RequestParam String programName, + @RequestParam String programEnrollmentId + ) throws ParseException, IOException { + programName = URLDecoder.decode(programName, "UTF-8"); + if (patientId == null || patientId.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noPatientIdProvided()); + if (programName == null || programName.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noProgramNameProvided()); + if (!validationService.isValidProgram(programName)) + return ResponseEntity.badRequest().body(ClientError.invalidProgramName()); + if (!validationService.isValidPatient(patientId)) + return ResponseEntity.badRequest().body(ClientError.invalidPatientId()); + List dischargeSummaryBundle = + dischargeSummaryService.getDischargeSummaryForProgram(patientId, new DateRange(parseDate(fromDate), parseDate(toDate)), programName, programEnrollmentId); + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .body(mapper.writeValueAsString(new BundledDischargeSummaryResponse(dischargeSummaryBundle))); + } +} + + + + + + + diff --git a/omod/src/main/java/org/bahmni/module/hip/web/controller/HipControllerAdvice.java b/omod/src/main/java/org/bahmni/module/hip/web/controller/HipControllerAdvice.java new file mode 100644 index 00000000..317d0bca --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/controller/HipControllerAdvice.java @@ -0,0 +1,48 @@ +package org.bahmni.module.hip.web.controller; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.hip.web.exception.RequestParameterMissingException; +import org.bahmni.module.hip.web.model.ErrorResponse; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ControllerAdvice +public class HipControllerAdvice extends BaseRestController { + + private static Logger logger = LogManager.getLogger(HipControllerAdvice.class); + + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(RequestParameterMissingException.class) + public @ResponseBody + ErrorResponse missingRequestParameter(Exception ex) { + return new ErrorResponse(ex.getMessage()); + } + + @ResponseBody + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(IllegalArgumentException.class) + public String illegalArgumentException(Exception ex) { + return ex.getMessage(); + } + +// @ResponseBody +// @ResponseStatus(HttpStatus.BAD_REQUEST) +// @ExceptionHandler(Exception.class) +// public ErrorResponse genericException(Exception ex) { +// logger.error(ex.getMessage(), ex); +// return new ErrorResponse(ex.getMessage()); +// } + + @ResponseBody + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(NumberFormatException.class) + public ErrorResponse numberFormatException(Exception ex) { + logger.error(ex.getMessage(), ex); + return new ErrorResponse(ex.getMessage()); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/controller/OPConsultController.java b/omod/src/main/java/org/bahmni/module/hip/web/controller/OPConsultController.java new file mode 100644 index 00000000..269e8635 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/controller/OPConsultController.java @@ -0,0 +1,94 @@ +package org.bahmni.module.hip.web.controller; + +import org.bahmni.module.hip.web.client.ClientError; +import org.bahmni.module.hip.web.model.BundledOPConsultResponse; +import org.bahmni.module.hip.web.model.DateRange; +import org.bahmni.module.hip.web.model.OPConsultBundle; +import org.bahmni.module.hip.web.service.OPConsultService; +import org.bahmni.module.hip.web.service.ValidationService; +import org.codehaus.jackson.map.ObjectMapper; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; + +import static org.bahmni.module.hip.web.utils.DateUtils.isDateBetweenDateRange; +import static org.bahmni.module.hip.web.utils.DateUtils.parseDate; +import static org.bahmni.module.hip.web.utils.DateUtils.parseDateTime; + +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/hip/opConsults") +@RestController +public class OPConsultController extends BaseRestController { + private final OPConsultService opConsultService; + private final ValidationService validationService; + private final ObjectMapper mapper = new ObjectMapper(); + + @Autowired + public OPConsultController(OPConsultService opConsultService, ValidationService validationService) { + this.opConsultService = opConsultService; + this.validationService = validationService; + } + + @RequestMapping(method = RequestMethod.GET, value = "/visit", produces = MediaType.APPLICATION_JSON_VALUE) + public @ResponseBody + ResponseEntity getOpconsultForVisit(@RequestParam String patientId, + @RequestParam String visitType, + @RequestParam String visitStartDate, + @RequestParam String fromDate, + @RequestParam String toDate) throws ParseException, IOException { + if (patientId == null || patientId.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noPatientIdProvided()); + if (visitType == null || visitType.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noVisitTypeProvided()); + if (visitStartDate == null || visitStartDate.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noVisitTypeProvided()); + if (!validationService.isValidVisit(visitType)) + return ResponseEntity.badRequest().body(ClientError.invalidVisitType()); + if (!validationService.isValidPatient(patientId)) + return ResponseEntity.badRequest().body(ClientError.invalidPatientId()); + List opConsultBundle = new ArrayList<>(); + if(isDateBetweenDateRange(visitStartDate,fromDate,toDate)) + opConsultBundle = opConsultService.getOpConsultsForVisit(patientId,visitType,parseDateTime(visitStartDate)); + + + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .body(mapper.writeValueAsString(new BundledOPConsultResponse(opConsultBundle))); + } + + @RequestMapping(method = RequestMethod.GET, value = "/program", produces = MediaType.APPLICATION_JSON_VALUE) + public @ResponseBody + ResponseEntity getOpConsultForProgram( + @RequestParam String patientId, + @RequestParam String fromDate, + @RequestParam String toDate, + @RequestParam String programName, + @RequestParam String programEnrollmentId) + throws ParseException, IOException { + programName = URLDecoder.decode(programName, "UTF-8"); + if (patientId == null || patientId.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noPatientIdProvided()); + if (programName == null || programName.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noProgramNameProvided()); + if (!validationService.isValidProgram(programName)) + return ResponseEntity.badRequest().body(ClientError.invalidProgramName()); + if (!validationService.isValidPatient(patientId)) + return ResponseEntity.badRequest().body(ClientError.invalidPatientId()); + List opConsultBundle = + opConsultService.getOpConsultsForProgram(patientId, new DateRange(parseDate(fromDate), parseDate(toDate)), programName, programEnrollmentId); + + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .body(mapper.writeValueAsString(new BundledOPConsultResponse(opConsultBundle))); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/controller/PatientController.java b/omod/src/main/java/org/bahmni/module/hip/web/controller/PatientController.java new file mode 100644 index 00000000..fdf3661d --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/controller/PatientController.java @@ -0,0 +1,95 @@ +package org.bahmni.module.hip.web.controller; + +import org.bahmni.module.hip.web.client.ClientError; +import org.bahmni.module.hip.web.client.model.Error; +import org.bahmni.module.hip.web.client.model.ErrorCode; +import org.bahmni.module.hip.web.client.model.ErrorRepresentation; +import org.bahmni.module.hip.web.model.ExistingPatient; +import org.bahmni.module.hip.web.model.Location; +import org.bahmni.module.hip.web.service.ExistingPatientService; +import org.bahmni.module.hip.web.service.ValidationService; +import org.codehaus.jackson.map.ObjectMapper; +import org.openmrs.Patient; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.CookieValue; + +import java.io.IOException; +import java.util.List; +import java.util.Set; + +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/hip") +@RestController +public class PatientController { + private final ExistingPatientService existingPatientService; + private final ValidationService validationService; + + @Autowired + public PatientController(ExistingPatientService existingPatientService, ValidationService validationService) { + this.existingPatientService = existingPatientService; + this.validationService = validationService; + } + + @RequestMapping(method = RequestMethod.GET, value = "/existingPatients", produces = MediaType.APPLICATION_JSON_VALUE) + public @ResponseBody + ResponseEntity getExistingPatients(@RequestParam(required = false) String patientName, + @RequestParam String patientYearOfBirth, + @RequestParam String patientGender, + @RequestParam String phoneNumber, + @CookieValue(name = "bahmni.user.location") String location) throws IOException { + String locationUuid = new ObjectMapper().readValue(location,Location.class).getUuid(); + Set matchingPatients = existingPatientService.getMatchingPatients(locationUuid,phoneNumber,patientName, + Integer.parseInt(patientYearOfBirth), patientGender); + if (matchingPatients.size() == 0) { + return ResponseEntity.ok().body(new ErrorRepresentation(new Error( + ErrorCode.PATIENT_ID_NOT_FOUND, "No patient found"))); + } + List existingPatients = existingPatientService.getMatchingPatientDetails(matchingPatients); + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .body(existingPatients); + } + + @RequestMapping(method = RequestMethod.GET, value = "/existingPatients/{healthId}") + @ResponseBody + public ResponseEntity getExistingPatientsWithHealthId(@PathVariable String healthId) { + String patientUuid = existingPatientService.getPatientWithHealthId(healthId); + if (patientUuid != null) { + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .body(patientUuid); + } + else { + return ResponseEntity.ok() + .body(new ErrorRepresentation(new Error(ErrorCode.PATIENT_ID_NOT_FOUND, "No patient found"))); + } + } + + @RequestMapping(method = RequestMethod.GET, value = "/existingPatients/status", produces = MediaType.APPLICATION_JSON_VALUE) + public @ResponseBody + ResponseEntity perform(@RequestParam String healthId, @RequestParam String action) { + if(!validationService.isValidHealthId(healthId)) { + return ResponseEntity.ok().body(ClientError.patientIdentifierNotFound()); + } + existingPatientService.perform(healthId, action); + return ResponseEntity.ok().body(""); + } + + @RequestMapping(method = RequestMethod.GET, value = "/existingPatients/IdDeactivationStatus/{patientUuid}") + @ResponseBody + public ResponseEntity getIdentifierStatus(@PathVariable String patientUuid) { + boolean isHealthIdVoided = existingPatientService.isHealthIdVoided(patientUuid); + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .body(isHealthIdVoided); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/controller/PrescriptionController.java b/omod/src/main/java/org/bahmni/module/hip/web/controller/PrescriptionController.java new file mode 100644 index 00000000..5baf6224 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/controller/PrescriptionController.java @@ -0,0 +1,93 @@ +package org.bahmni.module.hip.web.controller; + +import org.bahmni.module.hip.web.client.ClientError; +import org.bahmni.module.hip.web.model.BundledPrescriptionResponse; +import org.bahmni.module.hip.web.model.DateRange; +import org.bahmni.module.hip.web.model.PrescriptionBundle; +import org.bahmni.module.hip.web.service.PrescriptionService; +import org.bahmni.module.hip.web.service.ValidationService; +import org.codehaus.jackson.map.ObjectMapper; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; + +import static org.bahmni.module.hip.web.utils.DateUtils.isDateBetweenDateRange; +import static org.bahmni.module.hip.web.utils.DateUtils.parseDate; +import static org.bahmni.module.hip.web.utils.DateUtils.parseDateTime; + +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/hip/prescriptions") +@RestController +public class PrescriptionController extends BaseRestController { + private final PrescriptionService prescriptionService; + private final ValidationService validationService; + private final ObjectMapper mapper = new ObjectMapper(); + + @Autowired + public PrescriptionController(PrescriptionService prescriptionService, ValidationService validationService) { + this.prescriptionService = prescriptionService; + this.validationService = validationService; + } + + @RequestMapping(method = RequestMethod.GET, value = "/visit", produces = MediaType.APPLICATION_JSON_VALUE) + public @ResponseBody + ResponseEntity getPrescriptionForVisit( + @RequestParam String patientId, + @RequestParam String fromDate, + @RequestParam String toDate, + @RequestParam String visitType, + @RequestParam String visitStartDate + ) throws ParseException, IOException { + if (patientId == null || patientId.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noPatientIdProvided()); + if (visitType == null || visitType.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noVisitTypeProvided()); + if (visitStartDate == null || visitStartDate.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noVisitTypeProvided()); + if (!validationService.isValidVisit(visitType)) + return ResponseEntity.badRequest().body(ClientError.invalidVisitType()); + if (!validationService.isValidPatient(patientId)) + return ResponseEntity.badRequest().body(ClientError.invalidPatientId()); + List prescriptionBundle = new ArrayList<>(); + if(isDateBetweenDateRange(visitStartDate,fromDate,toDate)) + prescriptionBundle = prescriptionService.getPrescriptions(patientId, visitType, parseDateTime(visitStartDate)); + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .body(mapper.writeValueAsString(new BundledPrescriptionResponse(prescriptionBundle))); + } + + @RequestMapping(method = RequestMethod.GET, value = "/program", produces = MediaType.APPLICATION_JSON_VALUE) + public @ResponseBody + ResponseEntity getPrescriptionForProgram( + @RequestParam String patientId, + @RequestParam String fromDate, + @RequestParam String toDate, + @RequestParam String programName, + @RequestParam String programEnrollmentId + ) throws ParseException, IOException { + programName = URLDecoder.decode(programName, "UTF-8"); + if (patientId == null || patientId.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noPatientIdProvided()); + if (programName == null || programName.isEmpty()) + return ResponseEntity.badRequest().body(ClientError.noProgramNameProvided()); + if (!validationService.isValidProgram(programName)) + return ResponseEntity.badRequest().body(ClientError.invalidProgramName()); + if (!validationService.isValidPatient(patientId)) + return ResponseEntity.badRequest().body(ClientError.invalidPatientId()); + List prescriptionBundle = + prescriptionService.getPrescriptionsForProgram(patientId, new DateRange(parseDate(fromDate), parseDate(toDate)), programName, programEnrollmentId); + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .body(mapper.writeValueAsString(new BundledPrescriptionResponse(prescriptionBundle))); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/exception/NoMedicationFoundException.java b/omod/src/main/java/org/bahmni/module/hip/web/exception/NoMedicationFoundException.java new file mode 100644 index 00000000..358d5e6b --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/exception/NoMedicationFoundException.java @@ -0,0 +1,8 @@ +package org.bahmni.module.hip.web.exception; + +public class NoMedicationFoundException extends RuntimeException { + + public NoMedicationFoundException(String patientId) { + super("No Medication found for Patient" + patientId); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/exception/RequestParameterMissingException.java b/omod/src/main/java/org/bahmni/module/hip/web/exception/RequestParameterMissingException.java new file mode 100644 index 00000000..ea9a0f29 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/exception/RequestParameterMissingException.java @@ -0,0 +1,15 @@ +package org.bahmni.module.hip.web.exception; + +public class RequestParameterMissingException extends RuntimeException { + + private String parameterName; + + public RequestParameterMissingException(String parameterName) { + this.parameterName = parameterName; + } + + @Override + public String getMessage() { + return parameterName + " is mandatory request parameter"; + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/BundledDiagnosticReportResponse.java b/omod/src/main/java/org/bahmni/module/hip/web/model/BundledDiagnosticReportResponse.java new file mode 100644 index 00000000..e870cdd2 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/BundledDiagnosticReportResponse.java @@ -0,0 +1,15 @@ +package org.bahmni.module.hip.web.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@AllArgsConstructor +@Getter +@Setter +public class BundledDiagnosticReportResponse { + private List diagnosticReports; +} + diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/BundledDischargeSummaryResponse.java b/omod/src/main/java/org/bahmni/module/hip/web/model/BundledDischargeSummaryResponse.java new file mode 100644 index 00000000..b2f35767 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/BundledDischargeSummaryResponse.java @@ -0,0 +1,14 @@ +package org.bahmni.module.hip.web.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@AllArgsConstructor +@Getter +@Setter +public class BundledDischargeSummaryResponse { + private List dischargeSummary; +} \ No newline at end of file diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/BundledOPConsultResponse.java b/omod/src/main/java/org/bahmni/module/hip/web/model/BundledOPConsultResponse.java new file mode 100644 index 00000000..344c2ed0 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/BundledOPConsultResponse.java @@ -0,0 +1,14 @@ +package org.bahmni.module.hip.web.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@AllArgsConstructor +@Getter +@Setter +public class BundledOPConsultResponse { + private List opConsults; +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/BundledPrescriptionResponse.java b/omod/src/main/java/org/bahmni/module/hip/web/model/BundledPrescriptionResponse.java new file mode 100644 index 00000000..ba1b4357 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/BundledPrescriptionResponse.java @@ -0,0 +1,14 @@ +package org.bahmni.module.hip.web.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@AllArgsConstructor +@Getter +@Setter +public class BundledPrescriptionResponse { + private List prescriptions; +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/CareContext.java b/omod/src/main/java/org/bahmni/module/hip/web/model/CareContext.java new file mode 100644 index 00000000..b45e208b --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/CareContext.java @@ -0,0 +1,11 @@ +package org.bahmni.module.hip.web.model; + +import lombok.Builder; +import lombok.Data; + +@Builder +@Data +public class CareContext { + String careContextReference; + String careContextType; +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/DateRange.java b/omod/src/main/java/org/bahmni/module/hip/web/model/DateRange.java new file mode 100644 index 00000000..8f89c134 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/DateRange.java @@ -0,0 +1,13 @@ +package org.bahmni.module.hip.web.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Date; + +@AllArgsConstructor +@Getter +public class DateRange { + Date from; + Date to; +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/DiagnosticReportBundle.java b/omod/src/main/java/org/bahmni/module/hip/web/model/DiagnosticReportBundle.java new file mode 100644 index 00000000..117fbb68 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/DiagnosticReportBundle.java @@ -0,0 +1,18 @@ +package org.bahmni.module.hip.web.model; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import org.bahmni.module.hip.web.model.serializers.FhirBundleSerializer; +import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.hl7.fhir.r4.model.Bundle; + +@Getter +@Setter +@Builder +public class DiagnosticReportBundle { + private CareContext careContext; + + @JsonSerialize(using = FhirBundleSerializer.class) + private Bundle bundle; +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/DischargeSummaryBundle.java b/omod/src/main/java/org/bahmni/module/hip/web/model/DischargeSummaryBundle.java new file mode 100644 index 00000000..9a2daec6 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/DischargeSummaryBundle.java @@ -0,0 +1,18 @@ +package org.bahmni.module.hip.web.model; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import org.bahmni.module.hip.web.model.serializers.FhirBundleSerializer; +import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.hl7.fhir.r4.model.Bundle; + +@Getter +@Setter +@Builder +public class DischargeSummaryBundle { + private CareContext careContext; + + @JsonSerialize(using = FhirBundleSerializer.class) + private Bundle bundle; +} \ No newline at end of file diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/DrugOrders.java b/omod/src/main/java/org/bahmni/module/hip/web/model/DrugOrders.java new file mode 100644 index 00000000..a87fdcef --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/DrugOrders.java @@ -0,0 +1,54 @@ +package org.bahmni.module.hip.web.model; + +import org.openmrs.DrugOrder; +import org.openmrs.Encounter; +import org.springframework.util.CollectionUtils; + +import javax.validation.constraints.NotNull; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class DrugOrders { + + private List openMRSDrugOrders; + + public DrugOrders(@NotNull List openMRSDrugOrders) { + this.openMRSDrugOrders = openMRSDrugOrders; + } + + public Boolean isEmpty(){ + return CollectionUtils.isEmpty(openMRSDrugOrders); + } + + public Map groupByEncounter(){ + return groupByEncounterUUID() + .values() + .stream() + .map(DrugOrders::new) + .collect(Collectors.toMap(DrugOrders::firstEncounter, drugOrders -> drugOrders)); + } + + public int size() { + return openMRSDrugOrders.size(); + } + + private Map> groupByEncounterUUID(){ + return openMRSDrugOrders + .stream() + .collect(Collectors.groupingBy(order -> order.getEncounter().getUuid())); + } + + private Encounter firstEncounter() { + return openMRSDrugOrders.get(0).getEncounter(); + } + + Stream stream(){ + return openMRSDrugOrders.stream(); + } + + public List getOpenMRSDrugOrders() { + return openMRSDrugOrders; + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/ErrorResponse.java b/omod/src/main/java/org/bahmni/module/hip/web/model/ErrorResponse.java new file mode 100644 index 00000000..f5b9ac71 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/ErrorResponse.java @@ -0,0 +1,27 @@ +package org.bahmni.module.hip.web.model; + +public class ErrorResponse { + private String errMessage; + + public ErrorResponse() { + } + + @Override + public String toString() { + return "ErrorResponse{" + + "errMessage='" + errMessage + '\'' + + '}'; + } + + public ErrorResponse(String errMessage) { + this.errMessage = errMessage; + } + + public String getErrMessage() { + return errMessage; + } + + public void setErrMessage(String errMessage) { + this.errMessage = errMessage; + } +} \ No newline at end of file diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/ExistingPatient.java b/omod/src/main/java/org/bahmni/module/hip/web/model/ExistingPatient.java new file mode 100644 index 00000000..a1fc4261 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/ExistingPatient.java @@ -0,0 +1,19 @@ +package org.bahmni.module.hip.web.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Builder +@Getter +@Setter +@AllArgsConstructor +public class ExistingPatient { + String name; + String dateOfBirth; + String address; + String gender; + String uuid; + String phoneNumber; +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/FhirDiagnosticReport.java b/omod/src/main/java/org/bahmni/module/hip/web/model/FhirDiagnosticReport.java new file mode 100644 index 00000000..26c05339 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/FhirDiagnosticReport.java @@ -0,0 +1,135 @@ +package org.bahmni.module.hip.web.model; + +import org.bahmni.module.hip.Config; +import org.bahmni.module.hip.web.service.FHIRResourceMapper; +import org.bahmni.module.hip.web.service.FHIRUtils; +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.Composition; +import org.hl7.fhir.r4.model.DiagnosticReport; +import org.hl7.fhir.r4.model.Encounter; +import org.hl7.fhir.r4.model.Observation; +import org.hl7.fhir.r4.model.Patient; +import org.hl7.fhir.r4.model.Practitioner; +import org.hl7.fhir.r4.model.Reference; +import org.openmrs.EncounterProvider; +import org.openmrs.Obs; + +import java.util.Date; +import java.util.List; +import java.util.UUID; +import java.util.Set; +import java.util.stream.Collectors; + + +public class FhirDiagnosticReport { + private final List diagnosticReports; + private final Date visitTimestamp; + private final Integer encounterID; + private final Encounter encounter; + private final List practitioners; + private final Patient patient; + private final Reference patientReference; + private final List obs; + + private FhirDiagnosticReport(Date visitDateTime, + List diagnosticReports, + Integer encounterID, + Encounter encounter, + List practitioners, + Patient patient, + Reference patientReference, + List obs) { + this.visitTimestamp = visitDateTime; + this.diagnosticReports = diagnosticReports; + this.encounterID = encounterID; + this.encounter = encounter; + this.practitioners = practitioners; + this.patient = patient; + this.patientReference = patientReference; + this.obs = obs; + } + + + public Bundle bundleDiagnosticReport(String webUrl) { + String bundleID = String.format("PR-%d", encounterID); + Bundle bundle = FHIRUtils.createBundle(visitTimestamp, bundleID, webUrl); + + FHIRUtils.addToBundleEntry(bundle, compositionFrom(webUrl), false); + FHIRUtils.addToBundleEntry(bundle, practitioners, false); + FHIRUtils.addToBundleEntry(bundle, patient, false); + FHIRUtils.addToBundleEntry(bundle, obs, false); + FHIRUtils.addToBundleEntry(bundle, encounter, false); + FHIRUtils.addToBundleEntry(bundle, diagnosticReports, false); + return bundle; + } + + public static FhirDiagnosticReport fromOpenMrsDiagnosticReport(OpenMrsDiagnosticReport openMrsDiagnosticReport, + FHIRResourceMapper fhirResourceMapper) { + + Patient patient = fhirResourceMapper.mapToPatient(openMrsDiagnosticReport.getPatient()); + Reference patientReference = FHIRUtils.getReferenceToResource(patient); + Encounter encounter = fhirResourceMapper.mapToEncounter(openMrsDiagnosticReport.getEncounter()); + Date visitDateTime = openMrsDiagnosticReport.getEncounter().getVisit().getStartDatetime(); + Integer encounterId = openMrsDiagnosticReport.getEncounter().getId(); + List practitioners = getPractitionersFrom(fhirResourceMapper, openMrsDiagnosticReport.getEncounterProviders()); + List observationNotDocumentType = openMrsDiagnosticReport.getEncounter().getAllObs().stream() + .filter(obs -> (!obs.getConcept().getName().getName().equals(Config.DOCUMENT_TYPE.getValue()))).collect(Collectors.toList()); + List observations = observationNotDocumentType.stream() + .map(fhirResourceMapper::mapToObs).collect(Collectors.toList()); + List diagnosticReports = observationNotDocumentType.stream() + .map(fhirResourceMapper::mapToDiagnosticReport).collect(Collectors.toList()); + List diagnosticReportList = diagnosticReports.stream() + .peek(diagnosticReport -> { + diagnosticReport.setResultsInterpreter(practitioners.stream().map(FHIRUtils::getReferenceToResource) + .collect(Collectors.toList())); + diagnosticReport.setSubject(FHIRUtils.getReferenceToResource(patient)); + diagnosticReport.setResult(observations.stream().map(FHIRUtils::getReferenceToResource) + .collect(Collectors.toList())); + }).collect(Collectors.toList()); + return new FhirDiagnosticReport(visitDateTime, diagnosticReportList, encounterId, encounter, practitioners, + patient, patientReference, observations); + } + + private Composition compositionFrom(String webURL) { + Composition composition = initializeComposition(visitTimestamp, webURL); + Composition.SectionComponent compositionSection = composition.addSection(); + + practitioners + .forEach(practitioner -> composition + .addAuthor().setResource(practitioner).setDisplay(FHIRUtils.getDisplay(practitioner))); + + composition + .setEncounter(FHIRUtils.getReferenceToResource(encounter)) + .setSubject(patientReference); + + compositionSection + .setTitle("Diagnostic Report") + .setCode(FHIRUtils.getDiagnosticReportType()); + + diagnosticReports + .stream() + .map(FHIRUtils::getReferenceToResource) + .forEach(compositionSection::addEntry); + + return composition; + } + + private Composition initializeComposition(Date encounterTimestamp, String webURL) { + Composition composition = new Composition(); + + composition.setId(UUID.randomUUID().toString()); + composition.setDate(encounterTimestamp); + composition.setIdentifier(FHIRUtils.getIdentifier(composition.getId(), webURL, "document")); + composition.setStatus(Composition.CompositionStatus.FINAL); + composition.setType(FHIRUtils.getDiagnosticReportType()); + composition.setTitle("Diagnostic Report"); + return composition; + } + + private static List getPractitionersFrom(FHIRResourceMapper fhirResourceMapper, Set encounterProviders) { + return encounterProviders + .stream() + .map(fhirResourceMapper::mapToPractitioner) + .collect(Collectors.toList()); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/FhirDischargeSummary.java b/omod/src/main/java/org/bahmni/module/hip/web/model/FhirDischargeSummary.java new file mode 100644 index 00000000..2554122e --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/FhirDischargeSummary.java @@ -0,0 +1,245 @@ +package org.bahmni.module.hip.web.model; + +import org.bahmni.module.hip.web.service.FHIRResourceMapper; +import org.bahmni.module.hip.web.service.FHIRUtils; +import org.hl7.fhir.r4.model.Encounter; +import org.hl7.fhir.r4.model.Practitioner; +import org.hl7.fhir.r4.model.Condition; +import org.hl7.fhir.r4.model.Patient; +import org.hl7.fhir.r4.model.MedicationRequest; +import org.hl7.fhir.r4.model.Medication; +import org.hl7.fhir.r4.model.Reference; +import org.hl7.fhir.r4.model.Observation; +import org.hl7.fhir.r4.model.CarePlan; +import org.hl7.fhir.r4.model.DocumentReference; +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.Composition; +import org.hl7.fhir.r4.model.Procedure; +import org.hl7.fhir.r4.model.ServiceRequest; +import org.openmrs.EncounterProvider; + +import java.util.Date; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.ArrayList; +import java.util.Objects; +import java.util.stream.Collectors; + +public class FhirDischargeSummary { + + private final Date visitTimestamp; + private final Integer encounterID; + private final Encounter encounter; + private final List practitioners; + private final List chiefComplaints; + private final Patient patient; + private final List medicationRequests; + private final List medications; + private final List medicalHistory; + private final Reference patientReference; + private final List observations; + private final List carePlan; + private final List patientDocuments; + private final Procedure procedures; + private final List serviceRequest; + + public FhirDischargeSummary(Integer encounterID, + Encounter encounter, + Date visitTimestamp, + List practitioners, + Reference patientReference, + List chiefComplaints, + List medicationRequests, + List medications, + List medicalHistory, + Patient patient, + List carePlan, + List observations, + List patientDocuments, + Procedure procedures, + List serviceRequest){ + this.visitTimestamp = visitTimestamp; + this.encounterID = encounterID; + this.encounter = encounter; + this.chiefComplaints = chiefComplaints; + this.practitioners = practitioners; + this.medicationRequests = medicationRequests; + this.medications = medications; + this.medicalHistory = medicalHistory; + this.patient = patient; + this.patientReference = patientReference; + this.carePlan = carePlan; + this.observations = observations; + this.patientDocuments = patientDocuments; + this.procedures = procedures; + this.serviceRequest = serviceRequest; + } + public static FhirDischargeSummary fromOpenMrsDischargeSummary(OpenMrsDischargeSummary openMrsDischargeSummary, FHIRResourceMapper fhirResourceMapper){ + Patient patient = fhirResourceMapper.mapToPatient(openMrsDischargeSummary.getPatient()); + Reference patientReference = FHIRUtils.getReferenceToResource(patient); + Encounter encounter = fhirResourceMapper.mapToEncounter(openMrsDischargeSummary.getEncounter()); + Date visitDatetime = openMrsDischargeSummary.getEncounter().getVisit().getStartDatetime(); + Integer encounterId = openMrsDischargeSummary.getEncounter().getId(); + List practitioners = getPractitionersFrom(fhirResourceMapper, openMrsDischargeSummary.getEncounter().getEncounterProviders()); + List carePlans = openMrsDischargeSummary.getCarePlanObs().stream(). + map(fhirResourceMapper::mapToCarePlan).collect(Collectors.toList()); + List chiefComplaints = new ArrayList<>(); + for(int i=0;i medicationRequestsList = openMrsDischargeSummary.getDrugOrders().stream(). + map(fhirResourceMapper::mapToMedicationRequest).collect(Collectors.toList()); + List medications = openMrsDischargeSummary.getDrugOrders().stream().map(fhirResourceMapper::mapToMedication). + filter(medication -> !Objects.isNull(medication)).collect(Collectors.toList()); + List fhirMedicalHistoryList = new ArrayList<>(); + for(int i=0;i physicalExaminations = openMrsDischargeSummary.getPhysicalExaminationObs().stream(). + map(fhirResourceMapper::mapToObs).collect(Collectors.toList()); + List patientDocuments = openMrsDischargeSummary.getPatientDocuments().stream(). + map(fhirResourceMapper::mapToDocumentDocumentReference).collect(Collectors.toList()); + Procedure procedures = openMrsDischargeSummary.getProcedure() != null ? + fhirResourceMapper.mapToProcedure(openMrsDischargeSummary.getProcedure()) : null; + List serviceRequest = openMrsDischargeSummary.getOrders().stream(). + map(fhirResourceMapper::mapToOrder).collect(Collectors.toList()); + + return new FhirDischargeSummary(encounterId, encounter, visitDatetime, practitioners, patientReference, chiefComplaints, medicationRequestsList, medications, fhirMedicalHistoryList, patient, carePlans, physicalExaminations, patientDocuments, procedures, serviceRequest); + } + + public Bundle bundleDischargeSummary(String webUrl){ + String bundleID = String.format("PR-%d", encounterID); + Bundle bundle = FHIRUtils.createBundle(visitTimestamp, bundleID, webUrl); + FHIRUtils.addToBundleEntry(bundle, compositionFrom(webUrl), false); + FHIRUtils.addToBundleEntry(bundle, practitioners, false); + FHIRUtils.addToBundleEntry(bundle, medicationRequests, false); + FHIRUtils.addToBundleEntry(bundle, chiefComplaints, false); + FHIRUtils.addToBundleEntry(bundle, medications, false); + FHIRUtils.addToBundleEntry(bundle, medicalHistory, false); + FHIRUtils.addToBundleEntry(bundle, patient, false); + FHIRUtils.addToBundleEntry(bundle, encounter, false); + FHIRUtils.addToBundleEntry(bundle, carePlan, false); + FHIRUtils.addToBundleEntry(bundle, observations, false); + if (procedures != null) FHIRUtils.addToBundleEntry(bundle, procedures, false); + FHIRUtils.addToBundleEntry(bundle, patientDocuments, false); + FHIRUtils.addToBundleEntry(bundle, serviceRequest, false); + return bundle; + } + + private Composition compositionFrom(String webURL) { + Composition composition = initializeComposition(visitTimestamp, webURL); + composition + .setEncounter(FHIRUtils.getReferenceToResource(encounter)) + .setSubject(patientReference); + + practitioners + .forEach(practitioner -> composition + .addAuthor().setResource(practitioner).setDisplay(FHIRUtils.getDisplay(practitioner))); + + if (carePlan.size() > 0) { + Composition.SectionComponent physicalExaminationsCompositionSection = composition.addSection(); + physicalExaminationsCompositionSection + .setTitle("Care Plan") + .setCode(FHIRUtils.getCarePlanType()); + carePlan + .stream() + .map(FHIRUtils::getReferenceToResource) + .forEach(physicalExaminationsCompositionSection::addEntry); + } + + if(medicationRequests.size() > 0){ + Composition.SectionComponent medicationRequestsCompositionSection = composition.addSection(); + medicationRequestsCompositionSection + .setTitle("Medication request") + .setCode(FHIRUtils.getPrescriptionType()); + medicationRequests + .stream() + .map(FHIRUtils::getReferenceToResource) + .forEach(medicationRequestsCompositionSection::addEntry); + } + + if (chiefComplaints.size() > 0){ + Composition.SectionComponent chiefComplaintsCompositionSection = composition.addSection(); + chiefComplaintsCompositionSection + .setTitle("Chief complaint") + .setCode(FHIRUtils.getChiefComplaintType()); + chiefComplaints + .stream() + .map(FHIRUtils::getReferenceToResource) + .forEach(chiefComplaintsCompositionSection::addEntry); + } + + if (medicalHistory.size() > 0) { + Composition.SectionComponent medicalHistoryCompositionSection = composition.addSection(); + medicalHistoryCompositionSection + .setTitle("Medical history") + .setCode(FHIRUtils.getMedicalHistoryType()); + medicalHistory + .stream() + .map(FHIRUtils::getReferenceToResource) + .forEach(medicalHistoryCompositionSection::addEntry); + } + + if (observations.size() > 0) { + Composition.SectionComponent physicalExaminationsCompositionSection = composition.addSection(); + physicalExaminationsCompositionSection + .setTitle("Physical examination") + .setCode(FHIRUtils.getPhysicalExaminationType()); + observations + .stream() + .map(FHIRUtils::getReferenceToResource) + .forEach(physicalExaminationsCompositionSection::addEntry); + } + + if (patientDocuments.size() > 0) { + Composition.SectionComponent patientDocumentsCompositionSection = composition.addSection(); + patientDocumentsCompositionSection + .setTitle("Patient Document") + .setCode(FHIRUtils.getPatientDocumentType()); + patientDocuments + .stream() + .map(FHIRUtils::getReferenceToResource) + .forEach(patientDocumentsCompositionSection::addEntry); + } + + if (procedures != null) { + Composition.SectionComponent procedureCompositionSection = composition.addSection(); + procedureCompositionSection + .setTitle("Procedure") + .setCode(FHIRUtils.getProcedureType()); + + procedureCompositionSection.addEntry(FHIRUtils.getReferenceToResource(procedures)); + } + + if (serviceRequest.size() > 0) { + Composition.SectionComponent serviceRequestCompositionSection = composition.addSection(); + serviceRequestCompositionSection + .setTitle("Order") + .setCode(FHIRUtils.getOrdersType()); + serviceRequest.stream() + .map(FHIRUtils::getReferenceToResource) + .forEach(serviceRequestCompositionSection::addEntry); + } + + return composition; + } + + private Composition initializeComposition(Date visitTimestamp, String webURL) { + Composition composition = new Composition(); + composition.setId(UUID.randomUUID().toString()); + composition.setDate(visitTimestamp); + composition.setIdentifier(FHIRUtils.getIdentifier(composition.getId(), webURL, "Composition")); + composition.setStatus(Composition.CompositionStatus.FINAL); + composition.setType(FHIRUtils.getOPConsultType()); + composition.setTitle("Discharge Summary Document"); + return composition; + } + + private static List getPractitionersFrom(FHIRResourceMapper fhirResourceMapper, Set encounterProviders) { + return encounterProviders + .stream() + .map(fhirResourceMapper::mapToPractitioner) + .collect(Collectors.toList()); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/FhirLabResult.java b/omod/src/main/java/org/bahmni/module/hip/web/model/FhirLabResult.java new file mode 100644 index 00000000..6d4dee14 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/FhirLabResult.java @@ -0,0 +1,170 @@ +package org.bahmni.module.hip.web.model; + +import org.bahmni.module.hip.Config; +import org.bahmni.module.hip.web.service.FHIRResourceMapper; +import org.bahmni.module.hip.web.service.FHIRUtils; +import org.hl7.fhir.r4.model.Attachment; +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.CodeableConcept; +import org.hl7.fhir.r4.model.Coding; +import org.hl7.fhir.r4.model.Composition; +import org.hl7.fhir.r4.model.DiagnosticReport; +import org.hl7.fhir.r4.model.Encounter; +import org.hl7.fhir.r4.model.Observation; +import org.hl7.fhir.r4.model.Patient; +import org.hl7.fhir.r4.model.Practitioner; +import org.hl7.fhir.r4.model.Quantity; +import org.hl7.fhir.r4.model.Reference; +import org.hl7.fhir.r4.model.StringType; +import org.openmrs.Obs; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResult; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; + + +public class FhirLabResult { + + private final Patient patient; + private final Encounter encounter; + private final Date visitTime; + private final List report; + private final List results; + private final List practitioners; + + public FhirLabResult(Patient patient, String panelName, Encounter encounter, Date visitTime, List report, List results, List practitioners) { + this.patient = patient; + this.encounter = encounter; + this.visitTime = visitTime; + this.report = report; + this.results = results; + this.practitioners = practitioners; + } + + public Bundle bundleLabResults (String webUrl, FHIRResourceMapper fhirResourceMapper) { + String bundleID = String.format("LR-%s", encounter.getId()); + + Bundle bundle = FHIRUtils.createBundle(visitTime, bundleID, webUrl); + + FHIRUtils.addToBundleEntry(bundle, compositionFrom(webUrl), false); + + FHIRUtils.addToBundleEntry(bundle, encounter, false); + FHIRUtils.addToBundleEntry(bundle, practitioners, false); + FHIRUtils.addToBundleEntry(bundle, patient, false); + FHIRUtils.addToBundleEntry(bundle, report, false); + FHIRUtils.addToBundleEntry(bundle, results, false); + return bundle; + + } + + public static FhirLabResult fromOpenMrsLabResults(OpenMrsLabResults labresult, FHIRResourceMapper fhirResourceMapper) { + List reportList = new ArrayList<>(); + List practitioners = labresult.getEncounterProviders().stream().map(fhirResourceMapper::mapToPractitioner).collect(Collectors.toList()); + + Patient patient = fhirResourceMapper.mapToPatient(labresult.getPatient()); + + for(Map.Entry> report : labresult.getLabOrderResults().entrySet()) { + DiagnosticReport reports = new DiagnosticReport(); + LabOrderResult firstresult = (report.getValue() != null && report.getValue().size() != 0) ? report.getValue().get(0) : new LabOrderResult(); + String testName = report.getKey().getObsGroup().getConcept().getName().getName(); + reports.setCode(new CodeableConcept().setText(testName).addCoding(new Coding().setDisplay(testName))); + try { + reports.setPresentedForm(getAttachments(report.getKey(),testName)); + } catch (IOException e) { + e.printStackTrace(); + } + + reports.setId(firstresult.getOrderUuid() != null ? firstresult.getOrderUuid() : UUID.randomUUID().toString()); + reports.setStatus(DiagnosticReport.DiagnosticReportStatus.FINAL); + reports.setSubject(FHIRUtils.getReferenceToResource(patient)); + reports.setResultsInterpreter(practitioners.stream().map(FHIRUtils::getReferenceToResource).collect(Collectors.toList())); + + List results = new ArrayList<>(); + + if(report.getValue() != null) report.getValue().stream().forEach(result -> FhirLabResult.mapToObsFromLabResult(result, patient, reports, results)); + reportList.add(reports); + + } + + FhirLabResult fhirLabResult = new FhirLabResult(fhirResourceMapper.mapToPatient( labresult.getPatient()), null, + fhirResourceMapper.mapToEncounter( labresult.getEncounter() ), + labresult.getEncounter().getVisit().getStartDatetime(), reportList, new ArrayList<>(), practitioners); + + return fhirLabResult; + } + + private static void mapToObsFromLabResult(LabOrderResult result, Patient patient, DiagnosticReport report, List observations) { + + Observation obs = new Observation(); + + obs.setId(result.getTestUuid()); + obs.setCode(new CodeableConcept().setText( result.getTestName( ))); + try { + float f = result.getResult()!=null? Float.parseFloat(result.getResult()): (float) 0; + obs.setValue(new Quantity().setValue(f).setUnit(result.getTestUnitOfMeasurement())); + } catch (NumberFormatException | NullPointerException ex) { + obs.setValue(new StringType().setValue(result.getResult())); + } + obs.setStatus(Observation.ObservationStatus.FINAL); + + report.addResult(FHIRUtils.getReferenceToResource(obs)); + + observations.add(obs); + } + + private Composition compositionFrom(String webURL) { + Composition composition = initializeComposition(visitTime, webURL); + Composition.SectionComponent compositionSection = composition.addSection(); + Reference patientReference = FHIRUtils.getReferenceToResource(patient); + + practitioners + .forEach(practitioner -> composition + .addAuthor().setResource(practitioner).setDisplay(FHIRUtils.getDisplay(practitioner))); + composition + .setEncounter(FHIRUtils.getReferenceToResource(encounter)) + .setSubject(patientReference); + + compositionSection + .setTitle("Diagnostic Report") + .setCode(FHIRUtils.getDiagnosticReportType()); + + report.stream() + .map(FHIRUtils::getReferenceToResource) + .forEach(compositionSection::addEntry); + + + return composition; + } + + private Composition initializeComposition(Date visitTimestamp, String webURL) { + Composition composition = new Composition(); + + composition.setId(UUID.randomUUID().toString()); + composition.setDate(visitTimestamp); + composition.setIdentifier(FHIRUtils.getIdentifier(composition.getId(), webURL, "document")); + composition.setStatus(Composition.CompositionStatus.FINAL); + composition.setType(FHIRUtils.getDiagnosticReportType()); + composition.setTitle("Diagnostic Report"); + return composition; + } + + private static List getAttachments(Obs obs,String testNmae) throws IOException { + List attachments = new ArrayList<>(); + + Attachment attachment = new Attachment(); + attachment.setContentType(FHIRUtils.getTypeOfTheObsDocument(obs.getValueText())); + byte[] fileContent = Files.readAllBytes(new File(Config.PATIENT_DOCUMENTS_PATH.getValue() + obs.getValueText()).toPath()); + attachment.setData(fileContent); + attachment.setTitle("LAB REPORT : " + testNmae); + attachments.add(attachment); + + return attachments; + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/FhirOPConsult.java b/omod/src/main/java/org/bahmni/module/hip/web/model/FhirOPConsult.java new file mode 100644 index 00000000..130d91ff --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/FhirOPConsult.java @@ -0,0 +1,228 @@ +package org.bahmni.module.hip.web.model; + +import org.bahmni.module.hip.web.service.FHIRResourceMapper; +import org.bahmni.module.hip.web.service.FHIRUtils; +import org.hl7.fhir.r4.model.Condition; +import org.hl7.fhir.r4.model.Encounter; +import org.hl7.fhir.r4.model.Practitioner; +import org.hl7.fhir.r4.model.Patient; +import org.hl7.fhir.r4.model.Reference; +import org.hl7.fhir.r4.model.Observation; +import org.hl7.fhir.r4.model.MedicationRequest; +import org.hl7.fhir.r4.model.Medication; +import org.hl7.fhir.r4.model.Procedure; +import org.hl7.fhir.r4.model.DocumentReference; +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.Composition; +import org.hl7.fhir.r4.model.ServiceRequest; + +import org.openmrs.EncounterProvider; +import java.util.List; +import java.util.Date; +import java.util.Objects; +import java.util.UUID; +import java.util.Set; +import java.util.ArrayList; +import java.util.stream.Collectors; + +public class FhirOPConsult { + private final List chiefComplaints; + private final List medicalHistory; + private final Date visitTimeStamp; + private final Integer encounterID; + private final Encounter encounter; + private final List practitioners; + private final Patient patient; + private final Reference patientReference; + private final List observations; + private final List medicationRequests; + private final List medications; + private final Procedure procedure; + private final List patientDocuments; + private final List serviceRequest; + + public FhirOPConsult(List chiefComplaints, + List medicalHistory, Date visitTimeStamp, + Integer encounterID, + Encounter encounter, + List practitioners, + Patient patient, + Reference patientReference, + List observations, + List medicationRequests, + List medications, + Procedure procedure, + List patientDocuments, + List serviceRequest) { + this.chiefComplaints = chiefComplaints; + this.medicalHistory = medicalHistory; + this.visitTimeStamp = visitTimeStamp; + this.encounterID = encounterID; + this.encounter = encounter; + this.practitioners = practitioners; + this.patient = patient; + this.patientReference = patientReference; + this.observations = observations; + this.medicationRequests = medicationRequests; + this.medications = medications; + this.procedure = procedure; + this.patientDocuments = patientDocuments; + this.serviceRequest = serviceRequest; + } + + public Bundle bundleOPConsult(String webUrl) { + String bundleID = String.format("PR-%d", encounterID); + Bundle bundle = FHIRUtils.createBundle(visitTimeStamp, bundleID, webUrl); + FHIRUtils.addToBundleEntry(bundle, compositionFrom(webUrl), false); + FHIRUtils.addToBundleEntry(bundle, practitioners, false); + FHIRUtils.addToBundleEntry(bundle, patient, false); + FHIRUtils.addToBundleEntry(bundle, encounter, false); + FHIRUtils.addToBundleEntry(bundle, chiefComplaints, false); + FHIRUtils.addToBundleEntry(bundle, medicalHistory, false); + FHIRUtils.addToBundleEntry(bundle, observations, false); + FHIRUtils.addToBundleEntry(bundle, medicationRequests, false); + FHIRUtils.addToBundleEntry(bundle, medications, false); + FHIRUtils.addToBundleEntry(bundle, serviceRequest, false); + if (procedure != null) FHIRUtils.addToBundleEntry(bundle, procedure, false); + FHIRUtils.addToBundleEntry(bundle, patientDocuments, false); + return bundle; + } + + public static FhirOPConsult fromOpenMrsOPConsult(OpenMrsOPConsult openMrsOPConsult, FHIRResourceMapper fhirResourceMapper) { + Patient patient = fhirResourceMapper.mapToPatient(openMrsOPConsult.getPatient()); + Reference patientReference = FHIRUtils.getReferenceToResource(patient); + Encounter encounter = fhirResourceMapper.mapToEncounter(openMrsOPConsult.getEncounter()); + Date visitDatetime = openMrsOPConsult.getEncounter().getVisit().getStartDatetime(); + Integer encounterId = openMrsOPConsult.getEncounter().getId(); + List medicationRequestsList = openMrsOPConsult.getDrugOrders().stream(). + map(fhirResourceMapper::mapToMedicationRequest).collect(Collectors.toList()); + List medications = openMrsOPConsult.getDrugOrders().stream().map(fhirResourceMapper::mapToMedication). + filter(medication -> !Objects.isNull(medication)).collect(Collectors.toList()); + List practitioners = getPractitionersFrom(fhirResourceMapper, openMrsOPConsult.getEncounter().getEncounterProviders()); + List fhirChiefComplaintConditionList = new ArrayList<>(); + for(int i=0;i fhirMedicalHistoryList = new ArrayList<>(); + for(int i=0;i fhirObservationList = openMrsOPConsult.getObservations().stream(). + map(fhirResourceMapper::mapToObs).collect(Collectors.toList()); + Procedure procedure = openMrsOPConsult.getProcedure() != null ? + fhirResourceMapper.mapToProcedure(openMrsOPConsult.getProcedure()) : null; + List patientDocuments = openMrsOPConsult.getPatientDocuments().stream(). + map(fhirResourceMapper::mapToDocumentDocumentReference).collect(Collectors.toList()); + List serviceRequest = openMrsOPConsult.getOrders().stream(). + map(fhirResourceMapper::mapToOrder).collect(Collectors.toList()); + + return new FhirOPConsult(fhirChiefComplaintConditionList, fhirMedicalHistoryList, visitDatetime, encounterId, encounter, practitioners, + patient, patientReference, fhirObservationList, medicationRequestsList, medications, procedure, patientDocuments, serviceRequest); + } + + private Composition compositionFrom(String webURL) { + Composition composition = initializeComposition(visitTimeStamp, webURL); + composition + .setEncounter(FHIRUtils.getReferenceToResource(encounter)) + .setSubject(patientReference); + + practitioners + .forEach(practitioner -> composition + .addAuthor().setResource(practitioner).setDisplay(FHIRUtils.getDisplay(practitioner))); + + if (patientDocuments.size() > 0) { + Composition.SectionComponent patientDocumentsCompositionSection = composition.addSection(); + patientDocumentsCompositionSection + .setTitle("Patient Document") + .setCode(FHIRUtils.getPatientDocumentType()); + patientDocuments + .stream() + .map(FHIRUtils::getReferenceToResource) + .forEach(patientDocumentsCompositionSection::addEntry); + } + + if (procedure != null) { + Composition.SectionComponent procedureCompositionSection = composition.addSection(); + procedureCompositionSection + .setTitle("Procedure") + .setCode(FHIRUtils.getProcedureType()); + + procedureCompositionSection.addEntry(FHIRUtils.getReferenceToResource(procedure)); + } + + if(medicationRequests.size() > 0){ + Composition.SectionComponent medicationRequestsCompositionSection = composition.addSection(); + medicationRequestsCompositionSection + .setTitle("Medication request") + .setCode(FHIRUtils.getPrescriptionType()); + medicationRequests + .stream() + .map(FHIRUtils::getReferenceToResource) + .forEach(medicationRequestsCompositionSection::addEntry); + } + + if (chiefComplaints.size() > 0){ + Composition.SectionComponent chiefComplaintsCompositionSection = composition.addSection(); + chiefComplaintsCompositionSection + .setTitle("Chief complaint") + .setCode(FHIRUtils.getChiefComplaintType()); + chiefComplaints + .stream() + .map(FHIRUtils::getReferenceToResource) + .forEach(chiefComplaintsCompositionSection::addEntry); + } + + if (serviceRequest.size() > 0) { + Composition.SectionComponent serviceRequestCompositionSection = composition.addSection(); + serviceRequestCompositionSection + .setTitle("Order") + .setCode(FHIRUtils.getOrdersType()); + serviceRequest.stream() + .map(FHIRUtils::getReferenceToResource) + .forEach(serviceRequestCompositionSection::addEntry); + } + + if (medicalHistory.size() > 0) { + Composition.SectionComponent medicalHistoryCompositionSection = composition.addSection(); + medicalHistoryCompositionSection + .setTitle("Medical history") + .setCode(FHIRUtils.getMedicalHistoryType()); + medicalHistory + .stream() + .map(FHIRUtils::getReferenceToResource) + .forEach(medicalHistoryCompositionSection::addEntry); + } + + if (observations.size() > 0) { + Composition.SectionComponent physicalExaminationsCompositionSection = composition.addSection(); + physicalExaminationsCompositionSection + .setTitle("Physical examination") + .setCode(FHIRUtils.getPhysicalExaminationType()); + observations + .stream() + .map(FHIRUtils::getReferenceToResource) + .forEach(physicalExaminationsCompositionSection::addEntry); + } + + return composition; + } + + private Composition initializeComposition(Date visitTimeStamp, String webURL) { + Composition composition = new Composition(); + composition.setId(UUID.randomUUID().toString()); + composition.setDate(visitTimeStamp); + composition.setIdentifier(FHIRUtils.getIdentifier(composition.getId(), webURL, "Composition")); + composition.setStatus(Composition.CompositionStatus.FINAL); + composition.setType(FHIRUtils.getOPConsultType()); + composition.setTitle("OP Consultation Document"); + return composition; + } + + private static List getPractitionersFrom(FHIRResourceMapper fhirResourceMapper, Set encounterProviders) { + return encounterProviders + .stream() + .map(fhirResourceMapper::mapToPractitioner) + .collect(Collectors.toList()); + } + +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/FhirPrescription.java b/omod/src/main/java/org/bahmni/module/hip/web/model/FhirPrescription.java new file mode 100644 index 00000000..8936a0cb --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/FhirPrescription.java @@ -0,0 +1,133 @@ +package org.bahmni.module.hip.web.model; + +import lombok.Getter; +import org.bahmni.module.hip.web.service.FHIRResourceMapper; +import org.bahmni.module.hip.web.service.FHIRUtils; +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.Composition; +import org.hl7.fhir.r4.model.Encounter; +import org.hl7.fhir.r4.model.Medication; +import org.hl7.fhir.r4.model.MedicationRequest; +import org.hl7.fhir.r4.model.Observation; +import org.hl7.fhir.r4.model.Patient; +import org.hl7.fhir.r4.model.Practitioner; +import org.hl7.fhir.r4.model.Reference; +import org.openmrs.EncounterProvider; + +import java.util.Date; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +@Getter +public class FhirPrescription { + private final Date visitTimeStamp; + private final Integer encounterID; + private final Encounter encounter; + private final List practitioners; + private final Patient patient; + private final Reference patientReference; + private final List medications; + private final List medicationRequests; + + private FhirPrescription(Date visitTimeStamp, Integer encounterID, Encounter encounter, + List practitioners, Patient patient, + Reference patientReference, List medications, + List medicationRequests) { + this.visitTimeStamp = visitTimeStamp; + this.encounterID = encounterID; + this.encounter = encounter; + this.practitioners = practitioners; + this.patient = patient; + this.patientReference = patientReference; + this.medications = medications; + this.medicationRequests = medicationRequests; + } + + public static FhirPrescription from(OpenMrsPrescription openMrsPrescription, FHIRResourceMapper fhirResourceMapper) { + + Date encounterDatetime = openMrsPrescription.getEncounter().getVisit().getStartDatetime(); + Integer encounterId = openMrsPrescription.getEncounter().getId(); + Patient patient = fhirResourceMapper.mapToPatient(openMrsPrescription.getPatient()); + Reference patientReference = FHIRUtils.getReferenceToResource(patient); + Encounter encounter = fhirResourceMapper.mapToEncounter(openMrsPrescription.getEncounter()); + List practitioners = getPractitionersFrom(fhirResourceMapper, openMrsPrescription.getEncounterProviders()); + List medicationRequests = medicationRequestsFor(fhirResourceMapper, openMrsPrescription.getDrugOrders()); + List medications = medicationsFor(fhirResourceMapper, openMrsPrescription.getDrugOrders()); + + return new FhirPrescription(encounterDatetime, encounterId, encounter, practitioners, patient, patientReference, medications, medicationRequests); + } + + public Bundle bundle(String webUrl){ + String bundleID = String.format("PR-%d", encounterID); + Bundle bundle = FHIRUtils.createBundle(visitTimeStamp, bundleID, webUrl); + + FHIRUtils.addToBundleEntry(bundle, compositionFrom(webUrl), false); + FHIRUtils.addToBundleEntry(bundle, practitioners, false); + FHIRUtils.addToBundleEntry(bundle, patient, false); + FHIRUtils.addToBundleEntry(bundle, encounter, false); + FHIRUtils.addToBundleEntry(bundle, medications, false); + FHIRUtils.addToBundleEntry(bundle, medicationRequests, false); + return bundle; + } + + private Composition compositionFrom(String webURL){ + Composition composition = initializeComposition(visitTimeStamp, webURL); + Composition.SectionComponent compositionSection = composition.addSection(); + + practitioners + .forEach(practitioner -> composition + .addAuthor().setResource(practitioner).setDisplay(FHIRUtils.getDisplay(practitioner))); + + composition + .setEncounter(FHIRUtils.getReferenceToResource(encounter)) + .setSubject(patientReference); + + compositionSection + .setTitle("OPD Prescription") + .setCode(FHIRUtils.getPrescriptionType()); + + medicationRequests + .stream() + .map(FHIRUtils::getReferenceToResource) + .forEach(compositionSection::addEntry); + + return composition; + } + + private Composition initializeComposition(Date visitTimeStamp, String webURL) { + Composition composition = new Composition(); + + composition.setId(UUID.randomUUID().toString()); + composition.setDate(visitTimeStamp); + composition.setIdentifier(FHIRUtils.getIdentifier(composition.getId(), webURL, "document")); + composition.setStatus(Composition.CompositionStatus.FINAL); + composition.setType(FHIRUtils.getPrescriptionType()); + composition.setTitle("Prescription"); + return composition; + } + + private static List medicationRequestsFor(FHIRResourceMapper fhirResourceMapper, DrugOrders drugOrders) { + return drugOrders + .stream() + .map(fhirResourceMapper::mapToMedicationRequest) + .collect(Collectors.toList()); + } + + private static List medicationsFor(FHIRResourceMapper fhirResourceMapper, DrugOrders drugOrders) { + return drugOrders + .stream() + .map(fhirResourceMapper::mapToMedication) + .filter(medication -> !Objects.isNull(medication)) + .collect(Collectors.toList()); + } + + private static List getPractitionersFrom(FHIRResourceMapper fhirResourceMapper, Set encounterProviders) { + return encounterProviders + .stream() + .map(fhirResourceMapper::mapToPractitioner) + .collect(Collectors.toList()); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/Location.java b/omod/src/main/java/org/bahmni/module/hip/web/model/Location.java new file mode 100644 index 00000000..050db214 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/Location.java @@ -0,0 +1,11 @@ +package org.bahmni.module.hip.web.model; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class Location { + String name; + String uuid; +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/OPConsultBundle.java b/omod/src/main/java/org/bahmni/module/hip/web/model/OPConsultBundle.java new file mode 100644 index 00000000..d198cbb0 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/OPConsultBundle.java @@ -0,0 +1,18 @@ +package org.bahmni.module.hip.web.model; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import org.bahmni.module.hip.web.model.serializers.FhirBundleSerializer; +import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.hl7.fhir.r4.model.Bundle; + +@Getter +@Setter +@Builder +public class OPConsultBundle { + private CareContext careContext; + + @JsonSerialize(using = FhirBundleSerializer.class) + private Bundle bundle; +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsCondition.java b/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsCondition.java new file mode 100644 index 00000000..bdf71dcb --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsCondition.java @@ -0,0 +1,27 @@ +package org.bahmni.module.hip.web.model; + +import lombok.Getter; + +import java.util.Date; + +@Getter +public class OpenMrsCondition { + private final String name; + private final String uuid; + private final Date recordedDate; + + public OpenMrsCondition(String uuid, String name, Date recordedDate) { + this.uuid = uuid; + this.name = name; + this.recordedDate = recordedDate; + } + + @Override + public String toString() { + return "OpenMrsCondition{" + + "name='" + name + '\'' + + ", uuid='" + uuid + '\'' + + ", recordedDate=" + recordedDate + + '}'; + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsDiagnosticReport.java b/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsDiagnosticReport.java new file mode 100644 index 00000000..7db92fb9 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsDiagnosticReport.java @@ -0,0 +1,36 @@ +package org.bahmni.module.hip.web.model; + +import lombok.Getter; +import org.hibernate.validator.constraints.NotEmpty; +import org.openmrs.Encounter; +import org.openmrs.EncounterProvider; +import org.openmrs.Obs; +import org.openmrs.Patient; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +@Getter +public class OpenMrsDiagnosticReport { + private final Encounter encounter; + private final List obs; + private final Patient patient; + private final Set encounterProviders; + + private OpenMrsDiagnosticReport(@NotEmpty Encounter encounter, List obs) { + this.encounter = encounter; + this.obs = obs; + this.patient = encounter.getPatient(); + this.encounterProviders = encounter.getEncounterProviders(); + } + + public static List fromDiagnosticReport(Map> encounterDrugOrdersMap) { + return encounterDrugOrdersMap + .entrySet() + .stream() + .map(entry -> new OpenMrsDiagnosticReport(entry.getKey(), entry.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsDischargeSummary.java b/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsDischargeSummary.java new file mode 100644 index 00000000..bc0ab666 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsDischargeSummary.java @@ -0,0 +1,282 @@ +package org.bahmni.module.hip.web.model; + +import lombok.Getter; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.EncounterProvider; +import org.openmrs.DrugOrder; +import org.openmrs.Order; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +@Getter +public class OpenMrsDischargeSummary { + + private final Encounter encounter; + private final List carePlanObs; + private final Patient patient; + private final Set encounterProviders; + private final List drugOrders; + private final List chiefComplaints; + private final List medicalHistory; + private final List physicalExaminationObs; + private final List patientDocuments; + private final Obs procedure; + private final List orders; + + public OpenMrsDischargeSummary(Encounter encounter, + List carePlanObs, + List drugOrders, + Patient patient, + Set encounterProviders, + List chiefComplaints, + List medicalHistory, + List patientDocuments, + List physicalExaminationObs, + Obs procedure, List orders){ + this.encounter = encounter; + this.carePlanObs = carePlanObs; + this.drugOrders = drugOrders; + this.patient = patient; + this.encounterProviders = encounterProviders; + this.chiefComplaints = chiefComplaints; + this.medicalHistory = medicalHistory; + this.physicalExaminationObs = physicalExaminationObs; + this.patientDocuments = patientDocuments; + this.procedure = procedure; + this.orders = orders; + } + public static List getOpenMrsDischargeSummaryList(Map> encounterCarePlanMap, + Map encounterDrugOrdersMap, + ConcurrentHashMap> encounterChiefComplaintsMap, + Map> encounterMedicalHistoryMap, + Map> encounterPhysicalExaminationMap, + Map> encounterPatientDocumentsMap, + Map encounterProcedureNotesMap, + Map> encounterOrdersMap, + Patient patient){ + List openMrsDischargeSummaryList = new ArrayList<>(); + + for(Map.Entry> encounterListEntry : encounterCarePlanMap.entrySet()){ + List carePlanList = encounterCarePlanMap.get(encounterListEntry.getKey()); + List drugOrdersList = new ArrayList<>(); + List chiefComplaintList = new ArrayList<>(); + List medicalHistoryList = new ArrayList<>(); + List physicalExaminationList = new ArrayList<>(); + List patientDocumentList = new ArrayList<>(); + List orderList = new ArrayList<>(); + Obs procedure = null; + if (encounterDrugOrdersMap.get(encounterListEntry.getKey()) != null){ + drugOrdersList = encounterDrugOrdersMap.get(encounterListEntry.getKey()).getOpenMRSDrugOrders(); + encounterDrugOrdersMap.remove(encounterListEntry.getKey()); + } + if (encounterChiefComplaintsMap.get(encounterListEntry.getKey()) != null) { + chiefComplaintList = getEncounterConditions(encounterChiefComplaintsMap, encounterListEntry.getKey()); + encounterChiefComplaintsMap.remove(encounterListEntry.getKey()); + } + if(encounterMedicalHistoryMap.get(encounterListEntry.getKey()) != null) { + medicalHistoryList = getEncounterConditions(encounterMedicalHistoryMap, encounterListEntry.getKey()); + encounterMedicalHistoryMap.remove(encounterListEntry.getKey()); + } + if(encounterPhysicalExaminationMap.get(encounterListEntry.getKey()) != null){ + physicalExaminationList = getEncounterObs(encounterPhysicalExaminationMap, encounterListEntry.getKey()); + encounterPhysicalExaminationMap.remove(encounterListEntry.getKey()); + } + if(encounterPatientDocumentsMap.get(encounterListEntry.getKey()) != null){ + patientDocumentList = getEncounterObs(encounterPatientDocumentsMap, encounterListEntry.getKey()); + encounterPatientDocumentsMap.remove(encounterListEntry.getKey()); + } + if(encounterProcedureNotesMap.get(encounterListEntry.getKey()) != null) { + procedure = getEncounterObsProcedure(encounterProcedureNotesMap, encounterListEntry.getKey()); + encounterProcedureNotesMap.remove(encounterListEntry.getKey()); + } + if(encounterOrdersMap.get(encounterListEntry.getKey()) != null) { + orderList = getEncounterOrders(encounterOrdersMap, encounterListEntry.getKey()); + encounterOrdersMap.remove(encounterListEntry.getKey()); + } + openMrsDischargeSummaryList.add(new OpenMrsDischargeSummary(encounterListEntry.getKey(), carePlanList, drugOrdersList, patient, encounterListEntry.getKey().getEncounterProviders(), chiefComplaintList, medicalHistoryList, patientDocumentList, physicalExaminationList, procedure, orderList)); + } + + for(Map.Entry encounterListEntry : encounterDrugOrdersMap.entrySet()){ + List drugOrdersList = encounterDrugOrdersMap.get(encounterListEntry.getKey()).getOpenMRSDrugOrders(); + List chiefComplaintList = new ArrayList<>(); + List medicalHistoryList = new ArrayList<>(); + List physicalExaminationList = new ArrayList<>(); + List patientDocumentList = new ArrayList<>(); + List orderList = new ArrayList<>(); + Obs procedure = null; + if (encounterChiefComplaintsMap.get(encounterListEntry.getKey()) != null) { + chiefComplaintList = getEncounterConditions(encounterChiefComplaintsMap, encounterListEntry.getKey()); + encounterChiefComplaintsMap.remove(encounterListEntry.getKey()); + } + if(encounterMedicalHistoryMap.get(encounterListEntry.getKey()) != null) { + medicalHistoryList = getEncounterConditions(encounterMedicalHistoryMap, encounterListEntry.getKey()); + encounterMedicalHistoryMap.remove(encounterListEntry.getKey()); + } + if(encounterPhysicalExaminationMap.get(encounterListEntry.getKey()) != null){ + physicalExaminationList = getEncounterObs(encounterPhysicalExaminationMap, encounterListEntry.getKey()); + encounterPhysicalExaminationMap.remove(encounterListEntry.getKey()); + } + if(encounterPatientDocumentsMap.get(encounterListEntry.getKey()) != null){ + patientDocumentList = getEncounterObs(encounterPatientDocumentsMap, encounterListEntry.getKey()); + encounterPatientDocumentsMap.remove(encounterListEntry.getKey()); + } + if(encounterProcedureNotesMap.get(encounterListEntry.getKey()) != null) { + procedure = getEncounterObsProcedure(encounterProcedureNotesMap, encounterListEntry.getKey()); + encounterProcedureNotesMap.remove(encounterListEntry.getKey()); + } + if(encounterOrdersMap.get(encounterListEntry.getKey()) != null) { + orderList = getEncounterOrders(encounterOrdersMap, encounterListEntry.getKey()); + encounterOrdersMap.remove(encounterListEntry.getKey()); + } + openMrsDischargeSummaryList.add(new OpenMrsDischargeSummary(encounterListEntry.getKey(), new ArrayList<>(), drugOrdersList, patient, encounterListEntry.getKey().getEncounterProviders(), chiefComplaintList, medicalHistoryList, patientDocumentList, physicalExaminationList, procedure, orderList)); + } + + for(Map.Entry> encounterListEntry : encounterChiefComplaintsMap.entrySet()){ + List medicalHistoryList = new ArrayList<>(); + List physicalExaminationList = new ArrayList<>(); + List patientDocumentList = new ArrayList<>(); + List orderList = new ArrayList<>(); + Obs procedure = null; + List chiefComplaintList = encounterChiefComplaintsMap.get(encounterListEntry.getKey()); + if(encounterMedicalHistoryMap.get(encounterListEntry.getKey()) != null) { + medicalHistoryList = getEncounterConditions(encounterMedicalHistoryMap, encounterListEntry.getKey()); + encounterMedicalHistoryMap.remove(encounterListEntry.getKey()); + } + if(encounterPhysicalExaminationMap.get(encounterListEntry.getKey()) != null){ + physicalExaminationList = getEncounterObs(encounterPhysicalExaminationMap, encounterListEntry.getKey()); + encounterPhysicalExaminationMap.remove(encounterListEntry.getKey()); + } + if(encounterPatientDocumentsMap.get(encounterListEntry.getKey()) != null){ + patientDocumentList = getEncounterObs(encounterPatientDocumentsMap, encounterListEntry.getKey()); + encounterPatientDocumentsMap.remove(encounterListEntry.getKey()); + } + if(encounterProcedureNotesMap.get(encounterListEntry.getKey()) != null) { + procedure = getEncounterObsProcedure(encounterProcedureNotesMap, encounterListEntry.getKey()); + encounterProcedureNotesMap.remove(encounterListEntry.getKey()); + } + if(encounterOrdersMap.get(encounterListEntry.getKey()) != null) { + orderList = getEncounterOrders(encounterOrdersMap, encounterListEntry.getKey()); + encounterOrdersMap.remove(encounterListEntry.getKey()); + } + openMrsDischargeSummaryList.add(new OpenMrsDischargeSummary(encounterListEntry.getKey(), new ArrayList<>(), new ArrayList<>(), patient, encounterListEntry.getKey().getEncounterProviders(), chiefComplaintList, medicalHistoryList, patientDocumentList, physicalExaminationList, procedure, orderList)); + } + + for(Map.Entry> medicalHistoryEntry : encounterMedicalHistoryMap.entrySet()){ + List encounterConditions = encounterMedicalHistoryMap.get(medicalHistoryEntry.getKey()); + List physicalExaminationList = new ArrayList<>(); + List patientDocumentList = new ArrayList<>(); + List orderList = new ArrayList<>(); + Obs procedure = null; + if(encounterPhysicalExaminationMap.get(medicalHistoryEntry.getKey()) != null){ + physicalExaminationList = getEncounterObs(encounterPhysicalExaminationMap, medicalHistoryEntry.getKey()); + encounterPhysicalExaminationMap.remove(medicalHistoryEntry.getKey()); + } + if(encounterPatientDocumentsMap.get(medicalHistoryEntry.getKey()) != null){ + patientDocumentList = getEncounterObs(encounterPatientDocumentsMap, medicalHistoryEntry.getKey()); + encounterPatientDocumentsMap.remove(medicalHistoryEntry.getKey()); + } + if(encounterProcedureNotesMap.get(medicalHistoryEntry.getKey()) != null) { + procedure = getEncounterObsProcedure(encounterProcedureNotesMap, medicalHistoryEntry.getKey()); + encounterProcedureNotesMap.remove(medicalHistoryEntry.getKey()); + } + if(encounterOrdersMap.get(medicalHistoryEntry.getKey()) != null) { + orderList = getEncounterOrders(encounterOrdersMap, medicalHistoryEntry.getKey()); + encounterOrdersMap.remove(medicalHistoryEntry.getKey()); + } + openMrsDischargeSummaryList.add(new OpenMrsDischargeSummary(medicalHistoryEntry.getKey(), new ArrayList<>(), new ArrayList<>(), patient, medicalHistoryEntry.getKey().getEncounterProviders(), new ArrayList<>(), encounterConditions, patientDocumentList, physicalExaminationList, procedure, orderList)); + } + + for(Map.Entry> physicalExaminationEntry : encounterPhysicalExaminationMap.entrySet()){ + List physicalExaminationList = encounterPhysicalExaminationMap.get(physicalExaminationEntry.getKey()); + List patientDocumentList = new ArrayList<>(); + List orderList = new ArrayList<>(); + Obs procedure = null; + if(encounterPatientDocumentsMap.get(physicalExaminationEntry.getKey()) != null){ + patientDocumentList = getEncounterObs(encounterPatientDocumentsMap, physicalExaminationEntry.getKey()); + encounterPatientDocumentsMap.remove(physicalExaminationEntry.getKey()); + } + if(encounterProcedureNotesMap.get(physicalExaminationEntry.getKey()) != null) { + procedure = getEncounterObsProcedure(encounterProcedureNotesMap, physicalExaminationEntry.getKey()); + encounterProcedureNotesMap.remove(physicalExaminationEntry.getKey()); + } + if(encounterOrdersMap.get(physicalExaminationEntry.getKey()) != null) { + orderList = getEncounterOrders(encounterOrdersMap, physicalExaminationEntry.getKey()); + encounterOrdersMap.remove(physicalExaminationEntry.getKey()); + } + openMrsDischargeSummaryList.add(new OpenMrsDischargeSummary(physicalExaminationEntry.getKey(), new ArrayList<>(), new ArrayList<>(), patient, physicalExaminationEntry.getKey().getEncounterProviders(), new ArrayList<>(), new ArrayList<>(), patientDocumentList, physicalExaminationList, procedure, orderList)); + } + + for(Map.Entry> patientDocumentEntry : encounterPatientDocumentsMap.entrySet()){ + List patientDocumentList = encounterPatientDocumentsMap.get(patientDocumentEntry.getKey()); + List orderList = new ArrayList<>(); + Obs procedure = null; + if(encounterProcedureNotesMap.get(patientDocumentEntry.getKey()) != null) { + procedure = getEncounterObsProcedure(encounterProcedureNotesMap, patientDocumentEntry.getKey()); + encounterProcedureNotesMap.remove(patientDocumentEntry.getKey()); + } + if(encounterOrdersMap.get(patientDocumentEntry.getKey()) != null) { + orderList = getEncounterOrders(encounterOrdersMap, patientDocumentEntry.getKey()); + encounterOrdersMap.remove(patientDocumentEntry.getKey()); + } + openMrsDischargeSummaryList.add(new OpenMrsDischargeSummary(patientDocumentEntry.getKey(), new ArrayList<>(), new ArrayList<>(), patient, patientDocumentEntry.getKey().getEncounterProviders(), new ArrayList<>(), new ArrayList<>(), patientDocumentList, new ArrayList<>(), procedure, orderList)); + } + + for(Map.Entry procedureMapEntry : encounterProcedureNotesMap.entrySet()){ + Obs procedure = encounterProcedureNotesMap.get(procedureMapEntry.getKey()); + List orderList = new ArrayList<>(); + if(encounterOrdersMap.get(procedureMapEntry.getKey()) != null) { + orderList = getEncounterOrders(encounterOrdersMap, procedureMapEntry.getKey()); + encounterOrdersMap.remove(procedureMapEntry.getKey()); + } + openMrsDischargeSummaryList.add(new OpenMrsDischargeSummary(procedureMapEntry.getKey(), new ArrayList<>(), new ArrayList<>(), patient, procedureMapEntry.getKey().getEncounterProviders(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), procedure, orderList)); + } + + for(Map.Entry> orderMapEntry : encounterOrdersMap.entrySet()){ + openMrsDischargeSummaryList.add(new OpenMrsDischargeSummary(orderMapEntry.getKey(), new ArrayList<>(), new ArrayList<>(), patient, orderMapEntry.getKey().getEncounterProviders(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), null, encounterOrdersMap.get(orderMapEntry.getKey()))); + } + + return openMrsDischargeSummaryList; + } + + private static List getEncounterConditions(Map> map, Encounter encounter) { + if (map.containsKey(encounter)) { + List conditionList = map.get(encounter); + map.remove(encounter); + return conditionList; + } + return null; + } + + private static List getEncounterOrders(Map> map, Encounter encounter){ + if (map.containsKey(encounter)) { + List orderList = map.get(encounter); + map.remove(encounter); + return orderList; + } + return null; + } + + private static List getEncounterObs(Map> map, Encounter encounter) { + if (map.containsKey(encounter)) { + List obsList = map.get(encounter); + map.remove(encounter); + return obsList; + } + return null; + } + + private static Obs getEncounterObsProcedure(Map map, Encounter encounter) { + if (map.containsKey(encounter)) { + Obs obs = map.get(encounter); + map.remove(encounter); + return obs; + } + return null; + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsLabResults.java b/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsLabResults.java new file mode 100644 index 00000000..0bf30850 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsLabResults.java @@ -0,0 +1,40 @@ +package org.bahmni.module.hip.web.model; + +import lombok.Getter; +import org.hibernate.validator.constraints.NotEmpty; +import org.openmrs.Encounter; +import org.openmrs.EncounterProvider; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Patient; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResult; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +@Getter +public class OpenMrsLabResults { + private Encounter encounter; + private Map> labOrderResults; + private Patient patient; + private final Set encounterProviders; + + + public OpenMrsLabResults(@NotEmpty Encounter encounter, Patient patient, Map> labOrderResults) { + this.encounter = encounter; + this.patient = patient; + this.labOrderResults = labOrderResults; + this.encounterProviders = encounter.getEncounterProviders(); + } + + + public static List from(Map> labOrderResultsMap, Map> labReportDocuments) { + return labOrderResultsMap + .entrySet() + .stream() + .map(entry -> new OpenMrsLabResults(entry.getKey().getEncounter(), entry.getKey().getPatient(),labReportDocuments)) + .collect(Collectors.toList()); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsOPConsult.java b/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsOPConsult.java new file mode 100644 index 00000000..af4a725a --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsOPConsult.java @@ -0,0 +1,166 @@ +package org.bahmni.module.hip.web.model; + +import lombok.Getter; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.EncounterProvider; +import org.openmrs.DrugOrder; +import org.openmrs.Order; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +@Getter +public class OpenMrsOPConsult { + private final Encounter encounter; + private final List chiefComplaintConditions; + private final List medicalHistoryConditions; + private final List observations; + private final Patient patient; + private final Set encounterProviders; + private final List drugOrders; + private final Obs procedure; + private final List patientDocuments; + private final List orders; + + public OpenMrsOPConsult(Encounter encounter, + List chiefComplaintConditions, + List medicalHistoryConditions, + List observations, + Patient patient, + Set encounterProviders, + List drugOrders, + Obs procedure, + List patientDocuments, + List orders) { + this.encounter = encounter; + this.chiefComplaintConditions = chiefComplaintConditions; + this.medicalHistoryConditions = medicalHistoryConditions; + this.observations = observations; + this.patient = patient; + this.encounterProviders = encounterProviders; + this.drugOrders = drugOrders; + this.procedure = procedure; + this.patientDocuments = patientDocuments; + this.orders = orders; + } + + public static List getOpenMrsOPConsultList(Map> encounterChiefComplaintsMap, + Map> encounterMedicalHistoryMap, + Map> encounterPhysicalExaminationMap, + Map encounteredDrugOrdersMap, + Map encounterProcedureMap, + Map> encounterPatientDocumentsMap, + Map> encounterOrdersMap, + Patient patient) { + List openMrsOPConsultList = new ArrayList<>(); + + for(Map.Entry entry : encounteredDrugOrdersMap.entrySet()){ + List drugOrdersList = encounteredDrugOrdersMap.get(entry.getKey()).getOpenMRSDrugOrders(); + + List patientDocumentsList = getEncounterObs(encounterPatientDocumentsMap, entry.getKey()); + patientDocumentsList = patientDocumentsList == null ? new ArrayList<>() : patientDocumentsList; + + List medicalHistoryList = getEncounterConditions(encounterMedicalHistoryMap, entry.getKey()); + medicalHistoryList = medicalHistoryList == null ? new ArrayList<>() : medicalHistoryList; + + List physicalExaminationList = getEncounterObs(encounterPhysicalExaminationMap, entry.getKey()); + physicalExaminationList = physicalExaminationList == null ? new ArrayList<>() : physicalExaminationList; + + List chiefComplaintList = getEncounterConditions(encounterChiefComplaintsMap, entry.getKey()); + chiefComplaintList = chiefComplaintList == null ? new ArrayList<>() : chiefComplaintList; + + Obs procedure = getEncounterObsProcedure(encounterProcedureMap, entry.getKey()); + + openMrsOPConsultList.add(new OpenMrsOPConsult(entry.getKey(), chiefComplaintList, medicalHistoryList, physicalExaminationList, patient, entry.getKey().getEncounterProviders(), drugOrdersList, procedure, patientDocumentsList, new ArrayList<>())); + } + + for (Map.Entry> entry : encounterChiefComplaintsMap.entrySet()) { + List chiefComplaintList = encounterChiefComplaintsMap.get(entry.getKey()); + + List patientDocumentsList = getEncounterObs(encounterPatientDocumentsMap, entry.getKey()); + patientDocumentsList = patientDocumentsList == null ? new ArrayList<>() : patientDocumentsList; + + List medicalHistoryList = getEncounterConditions(encounterMedicalHistoryMap, entry.getKey()); + medicalHistoryList = medicalHistoryList == null ? new ArrayList<>() : medicalHistoryList; + + List physicalExaminationList = getEncounterObs(encounterPhysicalExaminationMap, entry.getKey()); + physicalExaminationList = physicalExaminationList == null ? new ArrayList<>() : physicalExaminationList; + + Obs procedure = getEncounterObsProcedure(encounterProcedureMap, entry.getKey()); + + openMrsOPConsultList.add(new OpenMrsOPConsult(entry.getKey(), chiefComplaintList, medicalHistoryList, physicalExaminationList, patient, entry.getKey().getEncounterProviders(), new ArrayList<>(), procedure, patientDocumentsList, new ArrayList<>())); + } + + for (Map.Entry> entry : encounterMedicalHistoryMap.entrySet()) { + List medicalHistoryList = encounterMedicalHistoryMap.get(entry.getKey()); + + List patientDocumentsList = getEncounterObs(encounterPatientDocumentsMap, entry.getKey()); + patientDocumentsList = patientDocumentsList == null ? new ArrayList<>() : patientDocumentsList; + + List physicalExaminationList = getEncounterObs(encounterPhysicalExaminationMap, entry.getKey()); + physicalExaminationList = physicalExaminationList == null ? new ArrayList<>() : physicalExaminationList; + + Obs procedure = getEncounterObsProcedure(encounterProcedureMap, entry.getKey()); + openMrsOPConsultList.add(new OpenMrsOPConsult(entry.getKey(), new ArrayList<>(), medicalHistoryList, physicalExaminationList, patient, entry.getKey().getEncounterProviders(), new ArrayList<>(), procedure, patientDocumentsList, new ArrayList<>())); + } + + for (Map.Entry> entry : encounterPhysicalExaminationMap.entrySet()) { + List physicalExaminationList = encounterPhysicalExaminationMap.get(entry.getKey()); + + List patientDocumentsList = getEncounterObs(encounterPatientDocumentsMap, entry.getKey()); + patientDocumentsList = patientDocumentsList == null ? new ArrayList<>() : patientDocumentsList; + + Obs procedure = getEncounterObsProcedure(encounterProcedureMap, entry.getKey()); + + openMrsOPConsultList.add(new OpenMrsOPConsult(entry.getKey(), new ArrayList<>(), new ArrayList<>(), physicalExaminationList, patient, entry.getKey().getEncounterProviders(), new ArrayList<>(), procedure, patientDocumentsList, new ArrayList<>())); + } + + for (Map.Entry entry : encounterProcedureMap.entrySet()) { + List patientDocumentsList = getEncounterObs(encounterPatientDocumentsMap, entry.getKey()); + patientDocumentsList = patientDocumentsList == null ? new ArrayList<>() : patientDocumentsList; + + openMrsOPConsultList.add(new OpenMrsOPConsult(entry.getKey(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), patient, entry.getKey().getEncounterProviders(), new ArrayList<>(), entry.getValue(), patientDocumentsList, new ArrayList<>())); + } + + for (Map.Entry> entry : encounterPatientDocumentsMap.entrySet()) { + openMrsOPConsultList.add(new OpenMrsOPConsult(entry.getKey(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), patient, entry.getKey().getEncounterProviders(), new ArrayList<>(), null, encounterPatientDocumentsMap.get(entry.getKey()), new ArrayList<>())); + } + + for(Map.Entry> entry : encounterOrdersMap.entrySet()){ + openMrsOPConsultList.add(new OpenMrsOPConsult(entry.getKey(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), patient, entry.getKey().getEncounterProviders(), new ArrayList<>(), null, new ArrayList<>(), encounterOrdersMap.get(entry.getKey()))); + } + + return openMrsOPConsultList; + } + + public static List getEncounterObs(Map> map, Encounter encounter) { + if (map.containsKey(encounter)) { + List obsList = map.get(encounter); + map.remove(encounter); + return obsList; + } + return null; + } + + public static List getEncounterConditions(Map> map, Encounter encounter) { + if (map.containsKey(encounter)) { + List conditionList = map.get(encounter); + map.remove(encounter); + return conditionList; + } + return null; + } + + public static Obs getEncounterObsProcedure(Map map, Encounter encounter) { + if (map.containsKey(encounter)) { + Obs obs = map.get(encounter); + map.remove(encounter); + return obs; + } + return null; + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsPrescription.java b/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsPrescription.java new file mode 100644 index 00000000..c125a7a8 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/OpenMrsPrescription.java @@ -0,0 +1,37 @@ +package org.bahmni.module.hip.web.model; + +import lombok.Getter; +import org.hibernate.validator.constraints.NotEmpty; +import org.openmrs.Encounter; +import org.openmrs.EncounterProvider; +import org.openmrs.Obs; +import org.openmrs.Patient; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +@Getter +public class OpenMrsPrescription { + private final Encounter encounter; + private final Set encounterProviders; + private final DrugOrders drugOrders; + private final Patient patient; + + private OpenMrsPrescription(@NotEmpty Encounter encounter, DrugOrders drugOrders) { + this.encounter = encounter; + this.encounterProviders = encounter.getEncounterProviders(); + this.patient = encounter.getPatient(); + this.drugOrders = drugOrders; + } + + + public static List from(Map encounterDrugOrdersMap) { + return encounterDrugOrdersMap + .entrySet() + .stream() + .map(entry -> new OpenMrsPrescription(entry.getKey(), entry.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/OrganizationContext.java b/omod/src/main/java/org/bahmni/module/hip/web/model/OrganizationContext.java new file mode 100644 index 00000000..d98687f5 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/OrganizationContext.java @@ -0,0 +1,21 @@ +package org.bahmni.module.hip.web.model; + +import lombok.Builder; +import lombok.Getter; +import org.hl7.fhir.r4.model.Organization; +import org.openmrs.VisitType; + +@Builder +public class OrganizationContext { + private Organization organization; + private String webUrl; + + public Class careContextType() { + //Hardcoded right now. Should also deal with programType, visit or visitType. + return VisitType.class; + } + + public String webUrl() { + return webUrl; + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/PrescriptionBundle.java b/omod/src/main/java/org/bahmni/module/hip/web/model/PrescriptionBundle.java new file mode 100644 index 00000000..d6badb10 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/PrescriptionBundle.java @@ -0,0 +1,19 @@ +package org.bahmni.module.hip.web.model; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import org.bahmni.module.hip.web.model.serializers.FhirBundleSerializer; +import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.hl7.fhir.r4.model.Bundle; + +@Builder +@Getter +@Setter +public class PrescriptionBundle { + private CareContext careContext; + + @JsonSerialize(using = FhirBundleSerializer.class) + private Bundle bundle; + +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/serializers/BundleSerializer.java b/omod/src/main/java/org/bahmni/module/hip/web/model/serializers/BundleSerializer.java new file mode 100644 index 00000000..b5e005bc --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/serializers/BundleSerializer.java @@ -0,0 +1,13 @@ +package org.bahmni.module.hip.web.model.serializers; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.parser.IParser; +import org.hl7.fhir.r4.model.Bundle; + +public class BundleSerializer { + public static String serializeBundle(Bundle bundle) { + FhirContext ctx = FhirContext.forR4(); + IParser parser = ctx.newJsonParser(); + return parser.encodeResourceToString(bundle); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/serializers/FhirBundleSerializer.java b/omod/src/main/java/org/bahmni/module/hip/web/model/serializers/FhirBundleSerializer.java new file mode 100644 index 00000000..a4f08608 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/serializers/FhirBundleSerializer.java @@ -0,0 +1,18 @@ +package org.bahmni.module.hip.web.model.serializers; + +import org.codehaus.jackson.JsonGenerator; +import org.codehaus.jackson.map.JsonSerializer; +import org.codehaus.jackson.map.SerializerProvider; +import org.hl7.fhir.r4.model.Bundle; + +import java.io.IOException; + +import static org.bahmni.module.hip.web.model.serializers.BundleSerializer.serializeBundle; + +public class FhirBundleSerializer extends JsonSerializer { + @Override + public void serialize(Bundle bundle, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) + throws IOException { + jsonGenerator.writeRaw(":" + serializeBundle(bundle)); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/model/serializers/NewCareContext.java b/omod/src/main/java/org/bahmni/module/hip/web/model/serializers/NewCareContext.java new file mode 100644 index 00000000..0abece48 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/model/serializers/NewCareContext.java @@ -0,0 +1,20 @@ +package org.bahmni.module.hip.web.model.serializers; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import org.bahmni.module.hip.model.PatientCareContext; + +import java.util.List; + +@Builder +@Getter +@Setter +@AllArgsConstructor +public class NewCareContext { + String patientName; + String healthId; + String patientReferenceNumber; + List careContexts; +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/BundleMedicationRequestService.java b/omod/src/main/java/org/bahmni/module/hip/web/service/BundleMedicationRequestService.java new file mode 100644 index 00000000..b2b2ee91 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/BundleMedicationRequestService.java @@ -0,0 +1,28 @@ +package org.bahmni.module.hip.web.service; + +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.MedicationRequest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class BundleMedicationRequestService { + + private final MedicationRequestService medicationRequestService; + private final BundleService bundleService; + + @Autowired + public BundleMedicationRequestService(MedicationRequestService medicationRequestService, BundleService bundleService) { + this.medicationRequestService = medicationRequestService; + this.bundleService = bundleService; + } + + public Bundle bundleMedicationRequestsFor(String patientId, String byVisitType) { + + List medicationRequests = medicationRequestService.medicationRequestFor(patientId, byVisitType); + + return bundleService.bundleMedicationRequests(medicationRequests); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/BundleService.java b/omod/src/main/java/org/bahmni/module/hip/web/service/BundleService.java new file mode 100644 index 00000000..8ed9e977 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/BundleService.java @@ -0,0 +1,22 @@ +package org.bahmni.module.hip.web.service; + +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.MedicationRequest; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class BundleService { + + Bundle bundleMedicationRequests(List medicationRequests) { + Bundle bundle = new Bundle(); + + medicationRequests + .forEach(medicationRequest -> { + bundle.addEntry().setResource(medicationRequest); + }); + + return bundle; + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/CareContextService.java b/omod/src/main/java/org/bahmni/module/hip/web/service/CareContextService.java new file mode 100644 index 00000000..9fbe657b --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/CareContextService.java @@ -0,0 +1,67 @@ +package org.bahmni.module.hip.web.service; + +import org.bahmni.module.hip.api.dao.CareContextRepository; +import org.bahmni.module.hip.api.dao.ExistingPatientDao; +import org.bahmni.module.hip.model.PatientCareContext; +import org.bahmni.module.hip.web.model.CareContext; +import org.bahmni.module.hip.web.model.serializers.NewCareContext; +import org.openmrs.Encounter; +import org.openmrs.Patient; +import org.openmrs.api.PatientService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class CareContextService { + private final CareContextRepository careContextRepository; + private final PatientService patientService; + private final ValidationService validationService; + private final ExistingPatientDao existingPatientDao; + + @Autowired + public CareContextService(CareContextRepository careContextRepository, PatientService patientService, ValidationService validationService, ExistingPatientDao existingPatientDao) { + this.careContextRepository = careContextRepository; + this.patientService = patientService; + this.validationService = validationService; + this.existingPatientDao = existingPatientDao; + } + + CareContext careContextFor(Encounter emrEncounter, Class careContextType) { + if (careContextType.getName().equals("Visit")) { + return CareContext.builder() + .careContextReference(emrEncounter.getVisit().getUuid()) + .careContextType("Visit").build(); + } else { + return CareContext.builder() + .careContextReference(emrEncounter.getVisit().getVisitType().getName()) + .careContextType("VisitType").build(); + } + } + + public Type careContextForPatient(String patientUuid) { + return (Type) careContextRepository.getPatientCareContext(patientUuid); + } + + public NewCareContext newCareContextsForPatient(String patientUuid) { + Patient patient = patientService.getPatientByUuid(patientUuid); + return new NewCareContext(patient.getGivenName() + (patient.getMiddleName() == null ? " " : patient.getMiddleName()) + patient.getFamilyName(), + existingPatientDao.getPatientHealthIdWithPatientId(patient.getId()), + patient.getPatientIdentifier("Patient Identifier").getIdentifier(), + getCareContexts(patient)); + } + + private List getCareContexts(Patient patient) { + List patientCareContexts = careContextRepository.getNewPatientCareContext(patient); + if (patientCareContexts.size() > 1) { + List result = new ArrayList<>(); + for (PatientCareContext careContext : patientCareContexts) { + if (!validationService.isValidVisit(careContext.getCareContextName())) result.add(careContext); + } + return result; + } + return patientCareContexts; + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/Constants.java b/omod/src/main/java/org/bahmni/module/hip/web/service/Constants.java new file mode 100644 index 00000000..9dc6818d --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/Constants.java @@ -0,0 +1,20 @@ +package org.bahmni.module.hip.web.service; + +public class Constants { + static final String FHIR_SCT_SYSTEM = "http://snomed.info/sct"; + static final String FHIR_CONDITION_CLINICAL_STATUS_SYSTEM = "http://terminology.hl7.org/CodeSystem/condition-clinical"; + + static final String MIMETYPE_IMAGE_JPEG = "image/jpeg"; + static final String IMAGE = "image/"; + static final String JPEG = "jpeg"; + static final String JPG = "jpg"; + static final String PNG = "png"; + static final String GIF = "gif"; + static final String PDF = "pdf"; + static final String MIMETYPE_PDF = "application/pdf"; + static final String MIMETYPE_VIDEO_MPEG = "video/mpeg"; + static final String MIMETYPE_VIDEO_MP4 = "video/mp4"; + static final String MP4 = "mp4"; + static final String MPEG = "mpeg"; + +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/ConsultationService.java b/omod/src/main/java/org/bahmni/module/hip/web/service/ConsultationService.java new file mode 100644 index 00000000..e51112f9 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/ConsultationService.java @@ -0,0 +1,178 @@ +package org.bahmni.module.hip.web.service; + +import org.bahmni.module.hip.Config; +import org.bahmni.module.hip.api.dao.ConsultationDao; +import org.bahmni.module.hip.api.dao.OPConsultDao; +import org.bahmni.module.hip.web.model.OpenMrsCondition; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.module.emrapi.conditionslist.Condition; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +@Service +public class ConsultationService { + + private final ConsultationDao consultationDao; + private final OPConsultDao opConsultDao; + private final DiagnosticReportService diagnosticReportService; + + public static Set conceptNames = new HashSet<>(Arrays.asList("Image","Tuberculosis, Treatment Plan","Tuberculosis, Next Followup Visit","Tuberculosis, Plan for next visit","Tuberculosis, Patient Category","Current Followup Visit After", + "Tuberculosis, Plan for next visit","Malaria, Parents Name","Malaria, Death Date", "Childhood Illness, Vitamin A Capsules Provided","Childhood Illness, Albendazole Given","Childhood Illness, Referred out", + "Childhood Illness, Vitamin A Capsules Provided","Childhood Illness, Albendazole Given","Nutrition, Bal Vita Provided by FCHV","Bal Vita Provided by FCHV","ART, Condoms given","HIVTC, Marital Status","Malaria, Contact number", + "HIVTC, Transferred out", "HIVTC, Regimen when transferred out", "HIVTC, Date of transferred out", "HIVTC, Transferred out to", "HIVTC, Chief Complaint")); + + @Autowired + public ConsultationService(ConsultationDao consultationDao, OPConsultDao opConsultDao, DiagnosticReportService diagnosticReportService) { + this.consultationDao = consultationDao; + this.opConsultDao = opConsultDao; + this.diagnosticReportService = diagnosticReportService; + } + + public ConcurrentHashMap> getEncounterChiefComplaintsMap(Visit visit) { + List chiefComplaints = consultationDao.getChiefComplaints(visit); + return getEncounterListConcurrentHashMapForChiefComplaint(chiefComplaints); + } + + public ConcurrentHashMap> getEncounterChiefComplaintsMapForProgram(String programName, Date fromDate, Date toDate, Patient patient) { + List chiefComplaints = consultationDao.getChiefComplaintForProgram(programName,fromDate, toDate,patient); + return getEncounterListConcurrentHashMapForChiefComplaint(chiefComplaints); + } + + public Map> getEncounterPhysicalExaminationMap(Visit visit) { + List physicalExaminations = consultationDao.getPhysicalExamination(visit); + return getEncounterListMapForPhysicalExamination(physicalExaminations); + } + + public Map> getEncounterPhysicalExaminationMapForProgram(String programName, Date fromDate, Date toDate, Patient patient) { + List physicalExaminations = consultationDao.getPhysicalExaminationForProgram(programName,fromDate,toDate,patient); + return getEncounterListMapForPhysicalExamination(physicalExaminations); + } + + public Map> getEncounterMedicalHistoryConditionsMap(Visit visit) { + Map> medicalHistoryConditionsMap = opConsultDao.getMedicalHistoryConditions(visit); + List medicalHistoryDiagnosisMap = opConsultDao.getMedicalHistoryDiagnosis(visit); + return getEncounterListMapForMedicalHistory(medicalHistoryConditionsMap, medicalHistoryDiagnosisMap); + } + + public Map> getEncounterMedicalHistoryConditionsMapForProgram(String programName, Date fromDate, Date toDate, Patient patient) { + Map> medicalHistoryConditionsMap = opConsultDao.getMedicalHistoryConditionsForProgram(programName,fromDate,toDate,patient); + List medicalHistoryDiagnosisMap = opConsultDao.getMedicalHistoryDiagnosisForProgram(programName,fromDate,toDate,patient); + return getEncounterListMapForMedicalHistory(medicalHistoryConditionsMap, medicalHistoryDiagnosisMap); + } + + public Map> getEncounterPatientDocumentsMap(Visit visit) { + return opConsultDao.getPatientDocumentsForVisit(visit); + } + + public Map> getEncounterPatientDocumentsMapForProgram(String programName, Date fromDate, Date toDate, Patient patient,String programEnrollmentId) { + final int patientDocumentEncounterType = 9; + Map> encounterDiagnosticReportsMap = diagnosticReportService.getAllObservationsForPrograms(fromDate,toDate,patient, programName, programEnrollmentId) ; + return getEncounterListMapForPatientDocument(patientDocumentEncounterType, encounterDiagnosticReportsMap); + } + + public Map> getEncounterOrdersMap(Visit visit) { + List orders = consultationDao.getOrders(visit); + return getEncounterListMapForOrders(orders); + } + + public Map> getEncounterOrdersMapForProgram(String programName, Date fromDate, Date toDate, Patient patient) { + List orders = consultationDao.getOrdersForProgram(programName,fromDate, toDate,patient); + return getEncounterListMapForOrders(orders); + } + + private ConcurrentHashMap> getEncounterListConcurrentHashMapForChiefComplaint(List chiefComplaints) { + ConcurrentHashMap> encounterChiefComplaintsMap = new ConcurrentHashMap<>(); + + for (Obs o : chiefComplaints) { + if(!encounterChiefComplaintsMap.containsKey(o.getEncounter())){ + encounterChiefComplaintsMap.put(o.getEncounter(), new ArrayList<>()); + } + encounterChiefComplaintsMap.get(o.getEncounter()).add(new OpenMrsCondition(o.getUuid(), o.getValueCoded().getDisplayString(), o.getDateCreated())); + } + return encounterChiefComplaintsMap; + } + + private Map> getEncounterListMapForPhysicalExamination(List physicalExaminations) { + Map> encounterPhysicalExaminationMap = new HashMap<>(); + for (Obs physicalExamination : physicalExaminations) { + Encounter encounter = physicalExamination.getEncounter(); + List groupMembers = new ArrayList<>(); + getGroupMembersOfObs(physicalExamination, groupMembers); + if (!encounterPhysicalExaminationMap.containsKey(encounter)) { + encounterPhysicalExaminationMap.put(encounter, new ArrayList<>()); + } + encounterPhysicalExaminationMap.get(encounter).addAll(groupMembers); + } + return encounterPhysicalExaminationMap; + } + + private Map> getEncounterListMapForMedicalHistory(Map> medicalHistoryConditionsMap, List medicalHistoryDiagnosisMap) { + Map> encounterMedicalHistoryMap = new HashMap<>(); + + for(Map.Entry> medicalHistory : medicalHistoryConditionsMap.entrySet()){ + if (!encounterMedicalHistoryMap.containsKey(medicalHistory.getKey())){ + encounterMedicalHistoryMap.put(medicalHistory.getKey(), new ArrayList<>()); + } + for(Condition condition : medicalHistory.getValue()){ + encounterMedicalHistoryMap.get(medicalHistory.getKey()).add(new OpenMrsCondition(condition.getUuid(), condition.getConditionNonCoded() != null ? condition.getConditionNonCoded() : condition.getConcept().getDisplayString(), condition.getDateCreated())); + } + } + for(Obs obs : medicalHistoryDiagnosisMap){ + if (!encounterMedicalHistoryMap.containsKey(obs.getEncounter())){ + encounterMedicalHistoryMap.put(obs.getEncounter(), new ArrayList<>()); + } + encounterMedicalHistoryMap.get(obs.getEncounter()).add(new OpenMrsCondition(obs.getUuid(), obs.getValueText() != null ? obs.getValueText() : obs.getValueCoded().getDisplayString(), obs.getDateCreated())); + } + return encounterMedicalHistoryMap; + } + + private Map> getEncounterListMapForPatientDocument(int patientDocumentEncounterType, Map> encounterDiagnosticReportsMap) { + Map> encounterPatientDocumentsMap = new HashMap<>(); + for (Encounter e : encounterDiagnosticReportsMap.keySet()) { + List patientDocuments = e.getAllObs().stream(). + filter(o -> (o.getEncounter().getEncounterType().getEncounterTypeId() == patientDocumentEncounterType && o.getValueText() == null)) + .collect(Collectors.toList()); + if (patientDocuments.size() > 0) { + encounterPatientDocumentsMap.put(e, patientDocuments); + } + } + return encounterPatientDocumentsMap; + } + + private Map> getEncounterListMapForOrders(List orders) { + Map> encounterOrdersMap = new HashMap<>(); + for(Order order : orders){ + if (!encounterOrdersMap.containsKey(order.getEncounter())) { + encounterOrdersMap.put(order.getEncounter(), new ArrayList<>()); + } + encounterOrdersMap.get(order.getEncounter()).add(order); + } + return encounterOrdersMap; + } + + private void getGroupMembersOfObs(Obs physicalExamination, List groupMembers) { + if (physicalExamination.getGroupMembers().size() > 0 && !Config.CONCEPT_DETAILS_CONCEPT_CLASS.getValue().equals(physicalExamination.getConcept().getConceptClass().getName())) { + for (Obs groupMember : physicalExamination.getGroupMembers()) { + if (conceptNames.contains(groupMember.getConcept().getDisplayString())) continue; + getGroupMembersOfObs(groupMember, groupMembers); + } + } else { + groupMembers.add(physicalExamination); + } + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/DiagnosticReportService.java b/omod/src/main/java/org/bahmni/module/hip/web/service/DiagnosticReportService.java new file mode 100644 index 00000000..28d69d43 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/DiagnosticReportService.java @@ -0,0 +1,184 @@ +package org.bahmni.module.hip.web.service; + +import org.bahmni.module.bahmnicore.dao.OrderDao; +import org.bahmni.module.hip.Config; +import org.bahmni.module.hip.api.dao.DiagnosticReportDao; +import org.bahmni.module.hip.api.dao.EncounterDao; +import org.bahmni.module.hip.api.dao.HipVisitDao; +import org.bahmni.module.hip.web.model.DateRange; +import org.bahmni.module.hip.web.model.DiagnosticReportBundle; +import org.bahmni.module.hip.web.model.OpenMrsDiagnosticReport; +import org.bahmni.module.hip.web.model.OpenMrsLabResults; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.EncounterService; +import org.openmrs.api.PatientService; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResult; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResults; +import org.openmrs.module.bahmniemrapi.laborder.service.LabOrderResultsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class DiagnosticReportService { + private final FhirBundledDiagnosticReportBuilder fhirBundledDiagnosticReportBuilder; + private final PatientService patientService; + private final EncounterService encounterService; + private final EncounterDao encounterDao; + private HipVisitDao hipVisitDao; + private OrderDao orderDao; + private final DiagnosticReportDao diagnosticReportDao; + + + private LabOrderResultsService labOrderResultsService; + + + @Autowired + public DiagnosticReportService(FhirBundledDiagnosticReportBuilder fhirBundledDiagnosticReportBuilder, + PatientService patientService, + EncounterService encounterService, + LabOrderResultsService labOrderResultsService, + EncounterDao encounterDao, + HipVisitDao hipVisitDao, + OrderDao orderDao, + DiagnosticReportDao diagnosticReportDao) { + this.fhirBundledDiagnosticReportBuilder = fhirBundledDiagnosticReportBuilder; + this.patientService = patientService; + this.encounterService = encounterService; + this.encounterDao = encounterDao; + this.hipVisitDao = hipVisitDao; + this.labOrderResultsService = labOrderResultsService; + this.orderDao = orderDao; + this.diagnosticReportDao = diagnosticReportDao; + } + + public List getDiagnosticReportsForVisit(String patientUuid, String visitType, Date visitStartDate) { + Patient patient = patientService.getPatientByUuid(patientUuid); + Visit visit = hipVisitDao.getPatientVisit(patient,visitType,visitStartDate); + HashMap> encounterListMap = getAllObservationsForVisits(visit); + List openMrsDiagnosticReports = OpenMrsDiagnosticReport.fromDiagnosticReport(encounterListMap); + + return openMrsDiagnosticReports + .stream() + .map(fhirBundledDiagnosticReportBuilder::fhirBundleResponseFor) + .collect(Collectors.toList()); + } + + public HashMap> getAllObservationsForVisits(Visit visit) { + List patientObs = encounterDao.GetAllObsForVisit(visit, Config.RADIOLOGY_TYPE.getValue(), Config.DOCUMENT_TYPE.getValue()); + patientObs.addAll(encounterDao.GetAllObsForVisit(visit, Config.PATIENT_DOCUMENT.getValue(), Config.DOCUMENT_TYPE.getValue())); + HashMap> encounterListMap = new HashMap<>(); + for (Obs obs: patientObs) { + Encounter encounter = obs.getEncounter(); + if(!encounterListMap.containsKey(encounter)) + encounterListMap.put(encounter, new ArrayList(){{ add(obs); }}); + encounterListMap.get(encounter).add(obs); + } + return encounterListMap; + + } + + public List getDiagnosticReportsForProgram(String patientUuid, DateRange dateRange, String programName, String programEnrollmentId) { + Date fromDate = dateRange.getFrom(); + Date toDate = dateRange.getTo(); + Patient patient = patientService.getPatientByUuid(patientUuid); + HashMap> encounterListMap = getAllObservationsForPrograms(fromDate, toDate, patient, programName, programEnrollmentId); + List openMrsDiagnosticReports = OpenMrsDiagnosticReport.fromDiagnosticReport(encounterListMap); + + return openMrsDiagnosticReports + .stream() + .map(fhirBundledDiagnosticReportBuilder::fhirBundleResponseFor) + .collect(Collectors.toList()); + + } + + public HashMap> getAllObservationsForPrograms(Date fromDate, Date toDate, + Patient patient, + String programName, + String programEnrollmentId) { + HashMap> encounterListMap = new HashMap<>(); + List encounterIds = encounterDao.GetEncounterIdsForProgramForDiagnosticReport(patient.getUuid(), programName, + programEnrollmentId, fromDate, toDate); + List finalList = new ArrayList<>(); + for(Integer encounterId : encounterIds){ + finalList.add(encounterService.getEncounter(encounterId)); + } + for (Encounter e : finalList) { + encounterListMap.put(e, new ArrayList<>(e.getAllObs())); + } + return encounterListMap; + } + + + private void putAllUnOrderedObsUploadsIntoMap(List observations, Map> labRecordsMap) { + for (Obs obs: observations) { + labRecordsMap.put(obs,new ArrayList<>()); + } + } + + private List getLabResults(Patient patient, List visitList) { + + Map> orderedTestUploads = diagnosticReportDao.getAllOrderedTestUploads(patient.getUuid(), visitList.size() != 0 ? visitList.get(0) : null); + Map> unorderedUploads = diagnosticReportDao.getAllUnorderedUploadsForVisit(patient.getUuid(), visitList.size() != 0 ? visitList.get(0) : null); + + LabOrderResults results = labOrderResultsService.getAll(patient, visitList, Integer.MAX_VALUE); + Map> groupedByOrderUUID = results.getResults().stream().collect(Collectors.groupingBy(LabOrderResult::getOrderUuid)); + + List labResults = new ArrayList<>(); + Map> labRecordsMap; + + for (Map.Entry> map : orderedTestUploads.entrySet()) { + labRecordsMap = new HashMap<>(); + for (Obs obs: map.getValue()) { + labRecordsMap.put(obs,groupedByOrderUUID.get(obs.getOrder().getUuid())); + } + if(unorderedUploads.containsKey(map.getKey())) + { + putAllUnOrderedObsUploadsIntoMap(unorderedUploads.get(map.getKey()),labRecordsMap); + unorderedUploads.remove(map.getKey()); + } + labResults.add(new OpenMrsLabResults(map.getKey(),map.getKey().getPatient(),labRecordsMap)); + } + + for (Map.Entry> map : unorderedUploads.entrySet()) { + labRecordsMap = new HashMap<>(); + putAllUnOrderedObsUploadsIntoMap(unorderedUploads.get(map.getKey()),labRecordsMap); + labResults.add(new OpenMrsLabResults(map.getKey(),map.getKey().getPatient(),labRecordsMap)); + } + + List bundles = labResults.stream().map(fhirBundledDiagnosticReportBuilder::fhirBundleResponseFor).collect(Collectors.toList()); + return bundles; + } + + public List getLabResultsForVisits(String patientUuid, String visittype, Date visitStartDate) + { + Patient patient = patientService.getPatientByUuid(patientUuid); + Visit visit = hipVisitDao.getPatientVisit(patient,visittype,visitStartDate); + List visits = new ArrayList<>(); + + visits.add(visit); + return getLabResults(patient, visits); + } + + public List getLabResultsForPrograms(String patientUuid, DateRange dateRange, String programName, String programEnrollmentId) + { + List visitsForProgram = hipVisitDao.GetVisitIdsForProgramForLabResults(patientUuid, programName, programEnrollmentId, dateRange.getFrom(), dateRange.getTo() ); + Patient patient = patientService.getPatientByUuid(patientUuid); + + List visits, visitsWithOrdersForProgram ; + + visits = orderDao.getVisitsWithAllOrders(patient, Config.ORDER_TYPE.getValue(), null, null ); + visitsWithOrdersForProgram = visits.stream().filter( visit -> visitsForProgram.contains(visit.getVisitId()) ).collect(Collectors.toList());; + return getLabResults(patient, visitsWithOrdersForProgram); + } + +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/DischargeSummaryService.java b/omod/src/main/java/org/bahmni/module/hip/web/service/DischargeSummaryService.java new file mode 100644 index 00000000..7f311d97 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/DischargeSummaryService.java @@ -0,0 +1,123 @@ +package org.bahmni.module.hip.web.service; + +import org.bahmni.module.hip.api.dao.DischargeSummaryDao; +import org.bahmni.module.hip.api.dao.HipVisitDao; +import org.bahmni.module.hip.web.model.OpenMrsCondition; +import org.bahmni.module.hip.web.model.DateRange; +import org.bahmni.module.hip.web.model.DischargeSummaryBundle; +import org.bahmni.module.hip.web.model.DrugOrders; +import org.bahmni.module.hip.web.model.OpenMrsDischargeSummary; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.PatientService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +@Service +public class DischargeSummaryService { + + private final PatientService patientService; + private final DischargeSummaryDao dischargeSummaryDao; + private final FhirBundledDischargeSummaryBuilder fhirBundledDischargeSummaryBuilder; + private final OpenMRSDrugOrderClient openMRSDrugOrderClient; + private final ConsultationService consultationService; + private final HipVisitDao hipVisitDao; + + @Autowired + public DischargeSummaryService(PatientService patientService, DischargeSummaryDao dischargeSummaryDao, FhirBundledDischargeSummaryBuilder fhirBundledDischargeSummaryBuilder, OpenMRSDrugOrderClient openMRSDrugOrderClient, ConsultationService consultationService, HipVisitDao hipVisitDao) { + this.patientService = patientService; + this.dischargeSummaryDao = dischargeSummaryDao; + this.fhirBundledDischargeSummaryBuilder = fhirBundledDischargeSummaryBuilder; + this.openMRSDrugOrderClient = openMRSDrugOrderClient; + this.consultationService = consultationService; + this.hipVisitDao = hipVisitDao; + } + + public List getDischargeSummaryForVisit(String patientUuid, String visitType, Date visitStartDate) { + Patient patient = patientService.getPatientByUuid(patientUuid); + Visit visit = hipVisitDao.getPatientVisit(patient,visitType,visitStartDate); + DrugOrders drugOrders = new DrugOrders(openMRSDrugOrderClient.getDrugOrdersByDateAndVisitTypeFor(visit)); + Map encounteredDrugOrdersMap = drugOrders.groupByEncounter(); + Map> encounterDischargeSummaryMap = getEncounterCarePlanMap(visit); + ConcurrentHashMap> encounterChiefComplaintsMap = consultationService.getEncounterChiefComplaintsMap(visit); + Map> encounterMedicalHistoryMap = consultationService.getEncounterMedicalHistoryConditionsMap( visit); + Map> encounterPhysicalExaminationMap = consultationService.getEncounterPhysicalExaminationMap(visit); + Map> encounterPatientDocumentsMap = consultationService.getEncounterPatientDocumentsMap(visit); + Map encounterProcedureMap = getEncounterProcedureMap(visit); + Map> encounterOrdersMap = consultationService.getEncounterOrdersMap(visit); + + List openMrsDischargeSummaryList = OpenMrsDischargeSummary.getOpenMrsDischargeSummaryList(encounterDischargeSummaryMap, encounteredDrugOrdersMap, encounterChiefComplaintsMap, encounterMedicalHistoryMap, encounterPhysicalExaminationMap, encounterPatientDocumentsMap, encounterProcedureMap, encounterOrdersMap, patient); + return openMrsDischargeSummaryList.stream().map(fhirBundledDischargeSummaryBuilder::fhirBundleResponseFor).collect(Collectors.toList()); + } + + public List getDischargeSummaryForProgram(String patientUuid, DateRange dateRange, String programName,String programEnrollmentId){ + Date fromDate = dateRange.getFrom(); + Date toDate = dateRange.getTo(); + Patient patient = patientService.getPatientByUuid(patientUuid); + DrugOrders drugOrders = new DrugOrders(openMRSDrugOrderClient.getDrugOrdersByDateAndProgramFor(patientUuid, dateRange, programName,programEnrollmentId)); + Map encounteredDrugOrdersMap = drugOrders.groupByEncounter(); + ConcurrentHashMap> encounterChiefComplaintsMap = consultationService.getEncounterChiefComplaintsMapForProgram(programName,fromDate, toDate,patient); + Map> encounterDischargeSummaryMap = getEncounterCarePlanMapForProgram(programName,fromDate,toDate,patient); + Map> encounterMedicalHistoryMap = consultationService.getEncounterMedicalHistoryConditionsMapForProgram(programName,fromDate, toDate,patient); + Map> encounterPhysicalExaminationMap = consultationService.getEncounterPhysicalExaminationMapForProgram(programName,fromDate, toDate,patient); + Map> encounterPatientDocumentsMap = consultationService.getEncounterPatientDocumentsMapForProgram(programName,fromDate,toDate,patient,programEnrollmentId); + Map encounterProcedureMap = getEncounterProcedureMapForProgram(programName,fromDate,toDate,patient); + Map> encounterOrdersMap = consultationService.getEncounterOrdersMapForProgram(programName,fromDate,toDate,patient); + List openMrsDischargeSummaryList = OpenMrsDischargeSummary.getOpenMrsDischargeSummaryList(encounterDischargeSummaryMap, encounteredDrugOrdersMap, encounterChiefComplaintsMap, encounterMedicalHistoryMap, encounterPhysicalExaminationMap, encounterPatientDocumentsMap, encounterProcedureMap, encounterOrdersMap, patient); + return openMrsDischargeSummaryList.stream().map(fhirBundledDischargeSummaryBuilder::fhirBundleResponseFor).collect(Collectors.toList()); + } + + + private Map> getEncounterCarePlanMap(Visit visit) { + List carePlanObs = dischargeSummaryDao.getCarePlan(visit); + return getEncounterListMapForCarePlan(carePlanObs); + } + + private Map> getEncounterListMapForCarePlan(List carePlanObs) { + Map> encounterCarePlanMap = new HashMap<>(); + for(Obs obs : carePlanObs){ + Encounter encounter = obs.getEncounter(); + if(!encounterCarePlanMap.containsKey(encounter)){ + encounterCarePlanMap.put(encounter, new ArrayList<>()); + } + encounterCarePlanMap.get(encounter).add(obs); + } + return encounterCarePlanMap; + } + + private Map> getEncounterCarePlanMapForProgram(String programName, Date fromDate, Date toDate, Patient patient) { + List carePlanObs = dischargeSummaryDao.getCarePlanForProgram(programName,fromDate, toDate,patient); + return getEncounterListMapForCarePlan(carePlanObs); + } + + private Map getEncounterProcedureMap(Visit visit) { + List obsProcedures = dischargeSummaryDao.getProcedures(visit); + Map encounterProcedureMap = new HashMap<>(); + for(Obs o: obsProcedures){ + encounterProcedureMap.put(o.getEncounter(), o); + } + return encounterProcedureMap; + } + + private Map getEncounterProcedureMapForProgram(String programName, Date fromDate, Date toDate, Patient patient) { + List obsProcedures = dischargeSummaryDao.getProceduresForProgram(programName,fromDate, toDate,patient); + Map encounterProcedureMap = new HashMap<>(); + for(Obs o: obsProcedures){ + encounterProcedureMap.put(o.getEncounter(), o); + } + return encounterProcedureMap; + } + + +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/DrugOrderService.java b/omod/src/main/java/org/bahmni/module/hip/web/service/DrugOrderService.java new file mode 100644 index 00000000..d48c717b --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/DrugOrderService.java @@ -0,0 +1,40 @@ +package org.bahmni.module.hip.web.service; + +import org.openmrs.DrugOrder; +import org.openmrs.Order; +import org.openmrs.OrderType; +import org.openmrs.Patient; +import org.openmrs.api.OrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +class DrugOrderService { + + private OrderService orderService; + + @Autowired + public DrugOrderService(OrderService orderService) { + this.orderService = orderService; + } + + List getAllDrugOrderFor(Patient patient, String visitType) { + + return orderService.getAllOrdersByPatient(patient).stream() + .filter(order -> matchesVisitType(visitType, order)) + .filter(this::isDrugOrder) + .map(order -> (DrugOrder) order) + .collect(Collectors.toList()); + } + + private boolean isDrugOrder(Order order) { + return order.getOrderType().getUuid().equals(OrderType.DRUG_ORDER_TYPE_UUID); + } + + private boolean matchesVisitType(String visitType, Order order) { + return order.getEncounter().getVisit().getVisitType().getName().equals(visitType); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/ExistingPatientService.java b/omod/src/main/java/org/bahmni/module/hip/web/service/ExistingPatientService.java new file mode 100644 index 00000000..74337b5a --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/ExistingPatientService.java @@ -0,0 +1,267 @@ +package org.bahmni.module.hip.web.service; + +import org.apache.commons.lang3.StringUtils; +import org.bahmni.module.bahmnicommons.api.contract.patient.PatientSearchParameters; +import org.bahmni.module.bahmnicommons.api.contract.patient.response.PatientResponse; +import org.bahmni.module.bahmnicommons.api.dao.PatientDao; +import org.bahmni.module.bahmnicommons.api.visitlocation.BahmniVisitLocationServiceImpl; +import org.bahmni.module.hip.Config; +import org.bahmni.module.hip.api.dao.ExistingPatientDao; +import org.bahmni.module.hip.web.client.model.Status; +import org.bahmni.module.hip.web.model.ExistingPatient; +import org.openmrs.Location; +import org.openmrs.Patient; +import org.openmrs.PatientIdentifier; +import org.openmrs.api.LocationService; +import org.openmrs.api.PatientService; +import org.openmrs.api.context.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Supplier; + + +@Service +public class ExistingPatientService { + private final ExistingPatientDao existingPatientDao; + static final int MATCHING_CRITERIA_CONSTANT = 2; + private final PatientDao patientDao; + private final PatientService patientService; + private final LocationService locationService; + static final int PHONE_NUMBER_LENGTH = 10; + + @Autowired + public ExistingPatientService(PatientDao patientDao, PatientService patientService, ExistingPatientDao existingPatientDao, LocationService locationService) { + this.patientDao = patientDao; + this.patientService = patientService; + this.existingPatientDao = existingPatientDao; + this.locationService = locationService; + } + + public Set getMatchingPatients(String locationUuid,String phoneNumber, String patientName, int patientYearOfBirth, String patientGender) { + Set matchingPatients = new HashSet<>(); + matchingPatients.addAll(getMatchingPatients(phoneNumber)); + matchingPatients.addAll(getMatchingPatients(locationUuid,patientName, patientYearOfBirth, patientGender)); + matchingPatients.removeIf(patient -> !getHealthId(patient).equals("")); + return matchingPatients; + } + + public String getHealthId(Patient patient) { + String healthId = ""; + try { + healthId = patient.getPatientIdentifier(Config.ABHA_ADDRESS.getValue()).getIdentifier(); + } catch (NullPointerException ignored) { + + } + return healthId; + } + + public void perform(String healthId, String action) { + Patient patient = patientService.getPatientByUuid(getPatientWithHealthId(healthId)); + PatientIdentifier patientIdentifierPhr = patient.getPatientIdentifier(Config.ABHA_ADDRESS.getValue()); + PatientIdentifier patientIdentifierHealthId = patient.getPatientIdentifier(Config.ABHA_NUMBER.getValue()); + if (action.equals(Status.DELETED.toString())) { + removeHealthId(patient,patientIdentifierPhr,patientIdentifierHealthId); + } + if (action.equals(Status.DEACTIVATED.toString())) { + voidHealthId(patientIdentifierPhr,patientIdentifierHealthId); + } + if (action.equals(Status.REACTIVATED.toString())) { + unVoidHealthId(patient); + } + } + + private void voidHealthId(PatientIdentifier patientIdentifierPHR, PatientIdentifier patientIdentifierHealthId) { + try { + if (!patientIdentifierPHR.getVoided()) { + patientService.voidPatientIdentifier(patientIdentifierPHR, Status.DEACTIVATED.toString()); + } + if (!patientIdentifierHealthId.getVoided()) { + patientService.voidPatientIdentifier(patientIdentifierHealthId, Status.DEACTIVATED.toString()); + } + } catch (NullPointerException ignored) { + } + } + + private void unVoidHealthId(Patient patient) { + Set patientIdentifiers = patient.getIdentifiers(); + try { + for (PatientIdentifier patientIdentifier : patientIdentifiers) { + if (patientIdentifier.getIdentifierType().getName().equals(Config.ABHA_ADDRESS.getValue()) || + patientIdentifier.getIdentifierType().getName().equals(Config.ABHA_NUMBER.getValue())) { + if(patientIdentifier.getVoided()){ + patientIdentifier.setVoided(false); + patientService.savePatientIdentifier(patientIdentifier); + } + } + } + } catch (NullPointerException ignored) { + } + } + + private void removeHealthId(Patient patient,PatientIdentifier patientIdentifierPHR,PatientIdentifier patientIdentifierHealthId) { + try { + if(patientIdentifierPHR != null) + patient.removeIdentifier(patientIdentifierPHR); + if (patientIdentifierHealthId != null) + patient.removeIdentifier(patientIdentifierHealthId); + patientService.savePatient(patient); + } catch (NullPointerException ignored) { + } + } + + public List getMatchingPatients(String phoneNumber) { + if(!phoneNumber.equals("undefined")) + return existingPatientDao.getPatientsWithPhoneNumber(phoneNumber.substring(phoneNumber.length() - PHONE_NUMBER_LENGTH)); + return new ArrayList<>(); + } + + public List getMatchingPatients(String locationUuid, String patientName, int patientYearOfBirth, String patientGender) { + List patients = getPatients(locationUuid,patientName, patientYearOfBirth, patientGender); + List existingPatients = new ArrayList<>(); + for (PatientResponse patient : patients) { + existingPatients.add(patientService.getPatientByUuid(patient.getUuid())); + } + return existingPatients; + } + + private List getPatients(String locationUuid, String patientName, int patientYearOfBirth, String patientGender) { + List patientsMatchedWithName = filterPatientsByName(locationUuid,patientName); + if (patientsMatchedWithName.size() != 1) { + List patientsMatchedWithNameAndAge = filterPatientsByAge(patientYearOfBirth, patientsMatchedWithName); + if (patientsMatchedWithNameAndAge.size() != 1) + return filterPatientsByGender(patientGender, patientsMatchedWithNameAndAge); + return patientsMatchedWithNameAndAge; + } + return patientsMatchedWithName; + } + + private List filterPatientsByName(String locationUuid,String patientName) { + PatientSearchParameters searchParameters = getPatientSearchParameters(locationUuid,patientName); + Supplier visitLocation = () -> getVisitLocation(locationUuid); + Supplier> configuredAddressFields = () -> patientDao.getConfiguredPatientAddressFields(); + + return patientDao.getPatients(searchParameters, visitLocation, configuredAddressFields); + } + + + private List filterPatientsByAge(int patientYearOfBirth, List patientsMatchedWithNameAndGender) { + List patients = new ArrayList<>(); + for (PatientResponse patient : patientsMatchedWithNameAndGender) { + if (verifyYearOfBirth(getYearOfBirth(patient.getBirthDate()), patientYearOfBirth)) { + patients.add(patient); + } + } + return patients; + } + + private Integer getYearOfBirth(Date birthDate) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(birthDate); + return calendar.get(Calendar.YEAR); + } + + private boolean verifyYearOfBirth(int yearOfBirth, int patientYearOfBirth) { + return yearOfBirth == patientYearOfBirth || Math.abs(yearOfBirth - patientYearOfBirth) <= MATCHING_CRITERIA_CONSTANT; + } + + private List filterPatientsByGender(String patientGender, List patientMatchedWithName) { + List patients = new ArrayList<>(); + for (PatientResponse patient : patientMatchedWithName) { + if (patient.getGender().equals(patientGender)) + patients.add(patient); + } + return patients; + } + + public List getMatchingPatientDetails(Set matchingPatients) { + List existingPatients = new ArrayList<>(); + for (Patient patient : matchingPatients) { + if (!isHealthIdVoided(patient.getUuid())) { + existingPatients.add( + new ExistingPatient( + patient.getGivenName() + " " + patient.getMiddleName() + " " + patient.getFamilyName(), + patient.getBirthdate().toString(), + getAddress(patient), + patient.getGender(), + patient.getUuid(), + getPhoneNumber(patient)) + ); + } + } + return existingPatients; + } + + private String getPhoneNumber(Patient patient) { + String phoneNumber = " "; + try { + phoneNumber = patient.getAttribute(Config.PHONE_NUMBER.getValue()).getValue(); + } catch (NullPointerException ignored) { + + } + return phoneNumber; + } + + private String getAddress(Patient patient) { + if (patient.getPersonAddress() != null) { + return patient.getPersonAddress().getAddress1() + + "," + patient.getPersonAddress().getCountyDistrict() + + "," + patient.getPersonAddress().getStateProvince(); + } + return ""; + } + + public String getPatientWithHealthId(String healthId) { + return existingPatientDao.getPatientUuidWithHealthId(healthId); + } + + public boolean isHealthIdVoided(String uuid){ + Patient patient = patientService.getPatientByUuid(uuid); + Set patientIdentifiers = patient.getIdentifiers(); + try { + for (PatientIdentifier patientIdentifier:patientIdentifiers) { + if(patientIdentifier.getIdentifierType().getName().equals(Config.ABHA_ADDRESS.getValue())){ + return patientIdentifier.getVoided(); + } + } + } catch (NullPointerException ignored) { + } + return false; + } + + private PatientSearchParameters getPatientSearchParameters(String locationUuid,String patientName) { + PatientSearchParameters searchParameters = new PatientSearchParameters(); + searchParameters.setIdentifier(""); + searchParameters.setName(patientName); + searchParameters.setCustomAttribute(null); + + searchParameters.setAddressFieldName(null); + searchParameters.setAddressFieldValue(""); + searchParameters.setLength(100); + searchParameters.setStart(0); + + searchParameters.setPatientAttributes(null); + searchParameters.setProgramAttributeFieldName(""); + searchParameters.setProgramAttributeFieldValue(null); + searchParameters.setAddressSearchResultFields(null); + searchParameters.setPatientSearchResultFields(null); + + searchParameters.setLoginLocationUuid(locationUuid); + searchParameters.setFilterPatientsByLocation(false); + searchParameters.setFilterOnAllIdentifiers(false); + return searchParameters; + } + private Location getVisitLocation(String loginLocationUuid) { + if (StringUtils.isBlank(loginLocationUuid)) { + return null; + } + BahmniVisitLocationServiceImpl bahmniVisitLocationService = new BahmniVisitLocationServiceImpl(Context.getLocationService()); + return bahmniVisitLocationService.getVisitLocation(loginLocationUuid); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/FHIRResourceMapper.java b/omod/src/main/java/org/bahmni/module/hip/web/service/FHIRResourceMapper.java new file mode 100644 index 00000000..69ab197f --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/FHIRResourceMapper.java @@ -0,0 +1,313 @@ +package org.bahmni.module.hip.web.service; + +import org.bahmni.module.hip.Config; +import org.bahmni.module.hip.web.model.OpenMrsCondition; +import org.hibernate.Hibernate; +import org.hibernate.proxy.HibernateProxy; +import org.hl7.fhir.r4.model.DiagnosticReport; +import org.hl7.fhir.r4.model.Encounter; +import org.hl7.fhir.r4.model.CarePlan; +import org.hl7.fhir.r4.model.DocumentReference; +import org.hl7.fhir.r4.model.Attachment; +import org.hl7.fhir.r4.model.Condition; +import org.hl7.fhir.r4.model.CodeableConcept; +import org.hl7.fhir.r4.model.Coding; +import org.hl7.fhir.r4.model.Reference; +import org.hl7.fhir.r4.model.Observation; +import org.hl7.fhir.r4.model.ServiceRequest; +import org.hl7.fhir.r4.model.Procedure; +import org.hl7.fhir.r4.model.Patient; +import org.hl7.fhir.r4.model.Practitioner; +import org.hl7.fhir.r4.model.MedicationRequest; +import org.hl7.fhir.r4.model.Dosage; +import org.hl7.fhir.r4.model.Medication; +import org.hl7.fhir.r4.model.Enumerations; +import org.hl7.fhir.r4.model.Annotation; +import org.hl7.fhir.r4.model.MarkdownType; +import org.hl7.fhir.r4.model.StringType; + +import org.openmrs.DrugOrder; +import org.openmrs.EncounterProvider; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Concept; +import org.openmrs.module.fhir2.api.translators.MedicationRequestTranslator; +import org.openmrs.module.fhir2.api.translators.MedicationTranslator; +import org.openmrs.module.fhir2.api.translators.PatientTranslator; +import org.openmrs.module.fhir2.api.translators.impl.EncounterTranslatorImpl; +import org.openmrs.module.fhir2.api.translators.impl.ObservationTranslatorImpl; +import org.openmrs.module.fhir2.api.translators.impl.PractitionerTranslatorProviderImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +@Service +public class FHIRResourceMapper { + + private final PatientTranslator patientTranslator; + private final PractitionerTranslatorProviderImpl practitionerTranslatorProvider; + private final MedicationRequestTranslator medicationRequestTranslator; + private final MedicationTranslator medicationTranslator; + private final EncounterTranslatorImpl encounterTranslator; + private final ObservationTranslatorImpl observationTranslator; + public static Set conceptNames = new HashSet<>(Arrays.asList("Follow up Date", "Additional Advice on Discharge", "Discharge Summary, Plan for follow up")); + + @Autowired + public FHIRResourceMapper(PatientTranslator patientTranslator, PractitionerTranslatorProviderImpl practitionerTranslatorProvider, MedicationRequestTranslator medicationRequestTranslator, MedicationTranslator medicationTranslator, EncounterTranslatorImpl encounterTranslator, ObservationTranslatorImpl observationTranslator) { + this.patientTranslator = patientTranslator; + this.practitionerTranslatorProvider = practitionerTranslatorProvider; + this.medicationRequestTranslator = medicationRequestTranslator; + this.medicationTranslator = medicationTranslator; + this.encounterTranslator = encounterTranslator; + this.observationTranslator = observationTranslator; + } + + public Encounter mapToEncounter(org.openmrs.Encounter emrEncounter) { + return encounterTranslator.toFhirResource(emrEncounter); + } + + public DiagnosticReport mapToDiagnosticReport(Obs obs) { + DiagnosticReport diagnosticReport = new DiagnosticReport(); + try { + diagnosticReport.setId(obs.getUuid()); + diagnosticReport.setStatus(DiagnosticReport.DiagnosticReportStatus.FINAL); + diagnosticReport.setPresentedForm(getAttachments(obs)); + return diagnosticReport; + } catch (IOException exception) { + return diagnosticReport; + } + } + + public Procedure mapToProcedure(Obs obs) { + Procedure procedure = new Procedure(); + procedure.setId(obs.getUuid()); + procedure = obs.getGroupMembers().size() > 0 ? mapGroupMembersToProcedure(obs.getGroupMembers(), procedure) + : mapObsToProcedure(obs, procedure); + return procedure; + } + + public Procedure mapGroupMembersToProcedure(Set obsGroupMembers, Procedure procedure){ + procedure.setStatus(Procedure.ProcedureStatus.COMPLETED); + StringBuilder title = new StringBuilder(); + StringBuilder description = new StringBuilder(""); + CodeableConcept concept = new CodeableConcept(); + for(Obs o : obsGroupMembers){ + if(Objects.equals(o.getConcept().getName().getName(), "Procedure Notes, Procedure")){ + title.append(o.getValueCoded().getDisplayString()); + } else { + description.append(description.toString().equals("") ? "" : ", "); + if(o.getValueCoded() != null){ + description.append(o.getValueCoded().getName().getName()); + }else if(o.getValueText() != null){ + description.append(o.getValueText()); + } else if(o.getValueNumeric() != null){ + description.append(o.getValueNumeric()); + } + } + } + concept.setText(title + ", " + description); + procedure.setCode(concept); + return procedure; + } + + public Procedure mapObsToProcedure(Obs obs, Procedure procedure){ + procedure.setStatus(Procedure.ProcedureStatus.COMPLETED); + CodeableConcept concept = new CodeableConcept(); + concept.setText(obs.getValueCoded().getDisplayString()); + procedure.setCode(concept); + return procedure; + } + + public CarePlan mapToCarePlan(Obs obs){ + List groupMembers = new ArrayList<>(); + getGroupMembersOfObs(obs, groupMembers); + CarePlan carePlan = new CarePlan(); + carePlan.setId(obs.getUuid()); + String description = ""; + for(Obs o : groupMembers){ + if(o.getValueDatetime() != null) { + description += description != "" ? ", " : ""; + description += o.getValueDatetime(); + } else if(o.getValueText() != null && Objects.equals(o.getConcept().getName().getName(), "Additional Advice on Discharge")){ + description += description != "" ? ", " : ""; + description += o.getValueText(); + } + if(o.getValueText() != null && Objects.equals(o.getConcept().getName().getName(), "Discharge Summary, Plan for follow up")){ + carePlan.setTitle(o.getValueText()); + carePlan.setUserData("Discharge Summary, Plan for follow up", o.getValueText()); + } + } + if(!description.isEmpty()){ + carePlan.setDescription(description); + } + return carePlan; + } + + private void getGroupMembersOfObs(Obs obs, List groupMembers) { + if (obs.getGroupMembers().size() > 0) { + for (Obs groupMember : obs.getGroupMembers()) { + if (conceptNames.contains(groupMember.getConcept().getDisplayString())){ + groupMembers.add(groupMember); + } + } + } + } + + public DocumentReference mapToDocumentDocumentReference(Obs obs) { + DocumentReference documentReference = new DocumentReference(); + documentReference.setId(obs.getUuid()); + documentReference.setStatus(Enumerations.DocumentReferenceStatus.CURRENT); + documentReference.setDescription(obs.getComment()); + List contents = new ArrayList<>(); + try { + List attachments = getAttachments(obs); + for (Attachment attachment : attachments) { + DocumentReference.DocumentReferenceContentComponent documentReferenceContentComponent + = new DocumentReference.DocumentReferenceContentComponent(); + documentReferenceContentComponent.setAttachment(attachment); + contents.add(documentReferenceContentComponent); + } + documentReference.setContent(contents); + return documentReference; + } catch (IOException exception) { + return documentReference; + } + } + + private List getAttachments(Obs obs) throws IOException { + List attachments = new ArrayList<>(); + Attachment attachment = new Attachment(); + StringBuilder valueText = new StringBuilder(); + Set obsList = obs.getGroupMembers(); + StringBuilder contentType = new StringBuilder(); + for(Obs obs1 : obsList) { + if (obs1.getConcept().getName().getName().equals(Config.DOCUMENT_TYPE.getValue())) { + valueText.append(obs1.getValueText()); + contentType.append(FHIRUtils.getTypeOfTheObsDocument(obs1.getValueText())); + } + } + if(obs.getConcept().getName().getName().equals(Config.IMAGE.getValue()) || obs.getConcept().getName().getName().equals(Config.PATIENT_VIDEO.getValue())){ + valueText.append(obs.getValueComplex()); + contentType.append(FHIRUtils.getTypeOfTheObsDocument(obs.getValueComplex())); + } + attachment.setContentType(contentType.toString()); + byte[] fileContent = Files.readAllBytes(new File(Config.PATIENT_DOCUMENTS_PATH.getValue() + valueText).toPath()); + attachment.setData(fileContent); + StringBuilder title = new StringBuilder(); + String encounterId = obs.getEncounter().getEncounterType().getName(); + if(encounterId.equals(Config.PATIENT_DOCUMENT.getValue())) + title.append(Config.PATIENT_DOCUMENT.getValue()); + else if(encounterId.equals(Config.RADIOLOGY_TYPE.getValue())) + title.append(Config.RADIOLOGY_REPORT.getValue()); + else if(encounterId.equals(Config.CONSULTATION.getValue())) + title.append("Consultation"); + title.append(": ").append(obs.getConcept().getName().getName()); + attachment.setTitle(title.toString()); + attachments.add(attachment); + return attachments; + } + + public Condition mapToCondition(OpenMrsCondition openMrsCondition, Patient patient) { + Condition condition = new Condition(); + CodeableConcept concept = new CodeableConcept(); + concept.setText(openMrsCondition.getName()); + condition.setCode(concept); + condition.setSubject(new Reference("Patient/" + patient.getId())); + condition.setId(openMrsCondition.getUuid()); + condition.setRecordedDate(openMrsCondition.getRecordedDate()); + condition.setClinicalStatus(new CodeableConcept(new Coding().setCode("active").setSystem(Constants.FHIR_CONDITION_CLINICAL_STATUS_SYSTEM))); + return condition; + } + + public Observation mapToObs(Obs obs) { + Concept concept = initializeEntityAndUnproxy(obs.getConcept()); + obs.setConcept(concept); + Observation observation = observationTranslator.toFhirResource(obs); + if (obs.getGroupMembers().size() > 0 && Config.CONCEPT_DETAILS_CONCEPT_CLASS.getValue().equals(obs.getConcept().getConceptClass().getName()) && obs.getFormFieldNamespace() != null) { + observation.setValue(new StringType(getCustomDisplayStringForChiefComplaint(obs.getGroupMembers()))); + } + observation.addNote(new Annotation(new MarkdownType(obs.getComment()))); + return observation; + } + + public ServiceRequest mapToOrder(Order order){ + ServiceRequest serviceRequest = new ServiceRequest(); + CodeableConcept concept = new CodeableConcept(); + concept.setText(order.getConcept().getDisplayString()); + serviceRequest.setIntent(ServiceRequest.ServiceRequestIntent.ORDER); + serviceRequest.setStatus(ServiceRequest.ServiceRequestStatus.ACTIVE); + serviceRequest.setSubject(new Reference("Patient/"+ order.getPatient().getUuid())); + serviceRequest.setCode(concept); + serviceRequest.setId(order.getUuid()); + return serviceRequest; + } + + public Patient mapToPatient(org.openmrs.Patient emrPatient) { + return patientTranslator.toFhirResource(emrPatient); + } + + public Practitioner mapToPractitioner(EncounterProvider encounterProvider) { + return practitionerTranslatorProvider.toFhirResource(encounterProvider.getProvider()); + } + + private String displayName(Object object) { + if (object == null) + return ""; + return object.toString() + " "; + + } + + public MedicationRequest mapToMedicationRequest(DrugOrder order) { + String dosingInstrutions = displayName(order.getDose()) + + displayName(order.getDoseUnits() == null ? "" : order.getDoseUnits().getName()) + + displayName(order.getFrequency()) + + displayName(order.getRoute() == null ? "" : order.getRoute().getName()) + + displayName(order.getDuration()) + + displayName(order.getDurationUnits() == null ? "" : order.getDurationUnits().getName()); + MedicationRequest medicationRequest = medicationRequestTranslator.toFhirResource(order); + medicationRequest.setSubject(new Reference("Patient/"+ order.getPatient().getUuid())); + Dosage dosage = medicationRequest.getDosageInstruction().get(0); + dosage.setText(dosingInstrutions.trim()); + return medicationRequest; + } + + public Medication mapToMedication(DrugOrder order) { + if (order.getDrug() == null) { + return null; + } + return medicationTranslator.toFhirResource(order.getDrug()); + } + + public static T initializeEntityAndUnproxy(T entity) { + if (entity == null) { + throw new NullPointerException("Entity passed for initialization is null"); + } + Hibernate.initialize(entity); + if (entity instanceof HibernateProxy) { + entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation(); + } + return entity; + } + + public String getCustomDisplayStringForChiefComplaint(Set groupMembers) { + String chiefComplaintCoded = null, signOrSymptomDuration = null, chiefComplaintDuration = null; + for (Obs childObs : groupMembers) { + if(childObs.getConcept().getName().getName().equals(Config.CHIEF_COMPLAINT_CODED.getValue())) + chiefComplaintCoded = childObs.getValueCoded().getDisplayString(); + if(childObs.getConcept().getName().getName().equals(Config.SIGN_SYMPTOM_DURATION.getValue())) + signOrSymptomDuration = String.valueOf(Math.round(childObs.getValueNumeric())); + if(childObs.getConcept().getName().getName().equals(Config.CHIEF_COMPLAINT_DURATION.getValue())) + chiefComplaintDuration = childObs.getValueCoded().getDisplayString(); + } + return (chiefComplaintCoded + " " + "since" + " " + signOrSymptomDuration + " " + chiefComplaintDuration); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/FHIRUtils.java b/omod/src/main/java/org/bahmni/module/hip/web/service/FHIRUtils.java new file mode 100644 index 00000000..37d66a13 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/FHIRUtils.java @@ -0,0 +1,216 @@ +package org.bahmni.module.hip.web.service; + +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.CodeableConcept; +import org.hl7.fhir.r4.model.Coding; +import org.hl7.fhir.r4.model.Enumerations; +import org.hl7.fhir.r4.model.Identifier; +import org.hl7.fhir.r4.model.Meta; +import org.hl7.fhir.r4.model.Organization; +import org.hl7.fhir.r4.model.Practitioner; +import org.hl7.fhir.r4.model.Reference; +import org.hl7.fhir.r4.model.Resource; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.bahmni.module.hip.web.service.Constants.GIF; +import static org.bahmni.module.hip.web.service.Constants.IMAGE; +import static org.bahmni.module.hip.web.service.Constants.JPEG; +import static org.bahmni.module.hip.web.service.Constants.JPG; +import static org.bahmni.module.hip.web.service.Constants.MIMETYPE_IMAGE_JPEG; +import static org.bahmni.module.hip.web.service.Constants.MIMETYPE_PDF; +import static org.bahmni.module.hip.web.service.Constants.MIMETYPE_VIDEO_MP4; +import static org.bahmni.module.hip.web.service.Constants.MIMETYPE_VIDEO_MPEG; +import static org.bahmni.module.hip.web.service.Constants.MP4; +import static org.bahmni.module.hip.web.service.Constants.MPEG; +import static org.bahmni.module.hip.web.service.Constants.PDF; +import static org.bahmni.module.hip.web.service.Constants.PNG; + +public class FHIRUtils { + private static Map genderMap = new HashMap() {{ + put("M", Enumerations.AdministrativeGender.MALE); + put("F", Enumerations.AdministrativeGender.FEMALE); + put("O", Enumerations.AdministrativeGender.OTHER); + put("U", Enumerations.AdministrativeGender.UNKNOWN); + }}; + + public static Bundle createBundle(Date forDate, String bundleId, String webURL) { + Bundle bundle = new Bundle(); + bundle.setId(bundleId); + bundle.setTimestamp(forDate); + + Identifier identifier = new Identifier(); + identifier.setSystem(Utils.ensureTrailingSlash(webURL.trim()) + "/bundle"); + identifier.setValue(bundleId); + bundle.setIdentifier(identifier); + + Meta bundleMeta = getMeta(forDate); + bundle.setMeta(bundleMeta); + bundle.setType(Bundle.BundleType.DOCUMENT); + return bundle; + } + + public static Meta getMeta(Date forDate) { + Meta meta = new Meta(); + meta.setLastUpdated(forDate); + meta.setVersionId("1.0"); //TODO + return meta; + } + + public static Identifier getIdentifier(String id, String domain, String resType) { + Identifier identifier = new Identifier(); + identifier.setSystem(Utils.ensureTrailingSlash(domain) + resType); + identifier.setValue(id); + return identifier; + } + + public static CodeableConcept getPrescriptionType() { + CodeableConcept type = new CodeableConcept(); + Coding coding = type.addCoding(); + coding.setSystem(Constants.FHIR_SCT_SYSTEM); + coding.setCode("440545006"); + coding.setDisplay("Prescription record"); + return type; + } + + public static CodeableConcept getDiagnosticReportType() { + CodeableConcept type = new CodeableConcept(); + Coding coding = type.addCoding(); + coding.setSystem(Constants.FHIR_SCT_SYSTEM); + coding.setCode("721981007"); + coding.setDisplay("Diagnostic Report"); + return type; + } + + public static CodeableConcept getPatientDocumentType() { + CodeableConcept type = new CodeableConcept(); + Coding coding = type.addCoding(); + coding.setSystem(Constants.FHIR_SCT_SYSTEM); + coding.setCode("371530004"); + coding.setDisplay("Clinical consultation report"); + return type; + } + + public static CodeableConcept getOPConsultType() { + CodeableConcept type = new CodeableConcept(); + Coding coding = type.addCoding(); + coding.setSystem(Constants.FHIR_SCT_SYSTEM); + coding.setCode("371530004"); + coding.setDisplay("Clinical consultation report"); + return type; + } + + public static CodeableConcept getChiefComplaintType() { + CodeableConcept type = new CodeableConcept(); + Coding coding = type.addCoding(); + coding.setSystem(Constants.FHIR_SCT_SYSTEM); + coding.setCode("422843007"); + coding.setDisplay("Chief complaint section"); + return type; + } + + public static CodeableConcept getMedicalHistoryType() { + CodeableConcept type = new CodeableConcept(); + Coding coding = type.addCoding(); + coding.setSystem(Constants.FHIR_SCT_SYSTEM); + coding.setCode("422843008"); // don't know + coding.setDisplay("Medical history"); + return type; + } + + public static CodeableConcept getPhysicalExaminationType() { + CodeableConcept type = new CodeableConcept(); + Coding coding = type.addCoding(); + coding.setSystem(Constants.FHIR_SCT_SYSTEM); + coding.setCode("425044008"); // don't know + coding.setDisplay("Physical examination"); + return type; + } + + public static CodeableConcept getCarePlanType() { + CodeableConcept type = new CodeableConcept(); + Coding coding = type.addCoding(); + coding.setSystem(Constants.FHIR_SCT_SYSTEM); + coding.setCode("736368003"); // don't know + coding.setDisplay("Care Plan"); + return type; + } + + public static CodeableConcept getProcedureType() { + CodeableConcept type = new CodeableConcept(); + Coding coding = type.addCoding(); + coding.setSystem(Constants.FHIR_SCT_SYSTEM); + coding.setCode("36969009"); + coding.setDisplay("Procedure"); + return type; + } + + public static CodeableConcept getOrdersType(){ + CodeableConcept type = new CodeableConcept(); + Coding coding = type.addCoding(); + coding.setSystem(Constants.FHIR_SCT_SYSTEM); + coding.setCode("721963009"); + coding.setDisplay("Order"); + return type; + } + + public static void addToBundleEntry(Bundle bundle, Resource resource, boolean useIdPart) { + String resourceType = resource.getResourceType().toString(); + String id = useIdPart ? resource.getIdElement().getIdPart() : resource.getId(); + bundle.addEntry() + .setFullUrl(resourceType + "/" + id) + .setResource(resource); + } + + public static void addToBundleEntry(Bundle bundle, List resources, boolean useIdPart) { + resources.forEach(resource -> FHIRUtils.addToBundleEntry(bundle, resource, useIdPart)); + } + + public static Organization createOrgInstance(String hfrId, String hfrName, String hfrSystem) { + Organization organization = new Organization(); + organization.setId(hfrId); + organization.setName(hfrName); + Identifier identifier = organization.addIdentifier(); + identifier.setSystem(hfrSystem); + identifier.setValue(hfrId); + identifier.setUse(Identifier.IdentifierUse.OFFICIAL); + return organization; + } + + public static Reference getReferenceToResource(Resource res) { + Reference ref = new Reference(); + ref.setResource(res); + return ref; + } + + public static String getDisplay(Practitioner author) { + String prefixAsSingleString = author.getNameFirstRep().getPrefixAsSingleString(); + if ("".equals(prefixAsSingleString)) { + return author.getNameFirstRep().getText(); + } else { + return prefixAsSingleString.concat(" ").concat(author.getNameFirstRep().getText()); + } + } + + public static String getTypeOfTheObsDocument(String valueText) { + if (valueText == null) return ""; + String extension = valueText.substring(valueText.indexOf('.') + 1); + if (extension.compareTo(JPEG) == 0 || extension.compareTo(JPG) == 0) { + return MIMETYPE_IMAGE_JPEG; + } else if (extension.compareTo(PNG) == 0 || extension.compareTo(GIF) == 0) { + return IMAGE + extension; + } else if (extension.compareTo(PDF) == 0) { + return MIMETYPE_PDF; + } else if (extension.compareTo(MP4) == 0) { + return MIMETYPE_VIDEO_MP4; + } else if (extension.compareTo(MPEG) == 0) { + return MIMETYPE_VIDEO_MPEG; + } else { + return ""; + } + } + +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/FhirBundledDiagnosticReportBuilder.java b/omod/src/main/java/org/bahmni/module/hip/web/service/FhirBundledDiagnosticReportBuilder.java new file mode 100644 index 00000000..e2721bcf --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/FhirBundledDiagnosticReportBuilder.java @@ -0,0 +1,59 @@ +package org.bahmni.module.hip.web.service; + +import org.bahmni.module.hip.web.model.CareContext; +import org.bahmni.module.hip.web.model.DiagnosticReportBundle; +import org.bahmni.module.hip.web.model.FhirDiagnosticReport; +import org.bahmni.module.hip.web.model.FhirLabResult; +import org.bahmni.module.hip.web.model.OpenMrsDiagnosticReport; +import org.bahmni.module.hip.web.model.OpenMrsLabResults; +import org.bahmni.module.hip.web.model.OrganizationContext; +import org.hl7.fhir.r4.model.Bundle; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class FhirBundledDiagnosticReportBuilder { + private final CareContextService careContextService; + private final OrganizationContextService organizationContextService; + private final FHIRResourceMapper fhirResourceMapper; + + @Autowired + public FhirBundledDiagnosticReportBuilder(CareContextService careContextService, OrganizationContextService organizationContextService, FHIRResourceMapper fhirResourceMapper) { + this.careContextService = careContextService; + this.organizationContextService = organizationContextService; + this.fhirResourceMapper = fhirResourceMapper; + } + + public DiagnosticReportBundle fhirBundleResponseFor(OpenMrsDiagnosticReport openMrsDiagnosticReport) { + OrganizationContext organizationContext = organizationContextService.buildContext(); + + Bundle diagnosticReportBundle = FhirDiagnosticReport + .fromOpenMrsDiagnosticReport(openMrsDiagnosticReport, fhirResourceMapper) + .bundleDiagnosticReport(organizationContext.webUrl()); + + CareContext careContext = careContextService.careContextFor( + openMrsDiagnosticReport.getEncounter(), + organizationContext.careContextType()); + + return DiagnosticReportBundle.builder() + .bundle(diagnosticReportBundle) + .careContext(careContext) + .build(); + } + + public DiagnosticReportBundle fhirBundleResponseFor(OpenMrsLabResults results) { + OrganizationContext organizationContext = organizationContextService.buildContext(); + + Bundle diagnosticReportBundle = FhirLabResult.fromOpenMrsLabResults(results, fhirResourceMapper) + .bundleLabResults(organizationContext.webUrl(), fhirResourceMapper); + + CareContext careContext = careContextService.careContextFor( + results.getEncounter(), + organizationContext.careContextType()); + + return DiagnosticReportBundle.builder() + .bundle(diagnosticReportBundle) + .careContext(careContext) + .build(); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/FhirBundledDischargeSummaryBuilder.java b/omod/src/main/java/org/bahmni/module/hip/web/service/FhirBundledDischargeSummaryBuilder.java new file mode 100644 index 00000000..04af4260 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/FhirBundledDischargeSummaryBuilder.java @@ -0,0 +1,37 @@ +package org.bahmni.module.hip.web.service; + +import org.bahmni.module.hip.web.model.*; +import org.hl7.fhir.r4.model.Bundle; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class FhirBundledDischargeSummaryBuilder { + private final CareContextService careContextService; + private final OrganizationContextService organizationContextService; + private final FHIRResourceMapper fhirResourceMapper; + + @Autowired + public FhirBundledDischargeSummaryBuilder(CareContextService careContextService, OrganizationContextService organizationContextService, FHIRResourceMapper fhirResourceMapper) { + this.careContextService = careContextService; + this.organizationContextService = organizationContextService; + this.fhirResourceMapper = fhirResourceMapper; + } + + public DischargeSummaryBundle fhirBundleResponseFor (OpenMrsDischargeSummary openMrsDischargeSummary) { + + OrganizationContext organizationContext = organizationContextService.buildContext(); + + Bundle dischargeSummaryBundle = FhirDischargeSummary.fromOpenMrsDischargeSummary(openMrsDischargeSummary, fhirResourceMapper). + bundleDischargeSummary(organizationContext.webUrl()); + + CareContext careContext = careContextService.careContextFor( + openMrsDischargeSummary.getEncounter(), + organizationContext.careContextType()); + + return DischargeSummaryBundle.builder() + .bundle(dischargeSummaryBundle) + .careContext(careContext) + .build(); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/FhirBundledOPConsultBuilder.java b/omod/src/main/java/org/bahmni/module/hip/web/service/FhirBundledOPConsultBuilder.java new file mode 100644 index 00000000..1512ae35 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/FhirBundledOPConsultBuilder.java @@ -0,0 +1,37 @@ +package org.bahmni.module.hip.web.service; + +import org.bahmni.module.hip.web.model.*; +import org.hl7.fhir.r4.model.Bundle; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class FhirBundledOPConsultBuilder { + private final CareContextService careContextService; + private final OrganizationContextService organizationContextService; + private final FHIRResourceMapper fhirResourceMapper; + + @Autowired + public FhirBundledOPConsultBuilder(CareContextService careContextService, OrganizationContextService organizationContextService, FHIRResourceMapper fhirResourceMapper) { + this.careContextService = careContextService; + this.organizationContextService = organizationContextService; + this.fhirResourceMapper = fhirResourceMapper; + } + + public OPConsultBundle fhirBundleResponseFor (OpenMrsOPConsult openMrsOPConsult) { + + OrganizationContext organizationContext = organizationContextService.buildContext(); + + Bundle opConsultBundle = FhirOPConsult.fromOpenMrsOPConsult(openMrsOPConsult, fhirResourceMapper). + bundleOPConsult(organizationContext.webUrl()); + + CareContext careContext = careContextService.careContextFor( + openMrsOPConsult.getEncounter(), + organizationContext.careContextType()); + + return OPConsultBundle.builder() + .bundle(opConsultBundle) + .careContext(careContext) + .build(); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/FhirBundledPrescriptionBuilder.java b/omod/src/main/java/org/bahmni/module/hip/web/service/FhirBundledPrescriptionBuilder.java new file mode 100644 index 00000000..65961930 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/FhirBundledPrescriptionBuilder.java @@ -0,0 +1,42 @@ +package org.bahmni.module.hip.web.service; + +import org.bahmni.module.hip.web.model.CareContext; +import org.bahmni.module.hip.web.model.FhirPrescription; +import org.bahmni.module.hip.web.model.OpenMrsPrescription; +import org.bahmni.module.hip.web.model.OrganizationContext; +import org.bahmni.module.hip.web.model.PrescriptionBundle; +import org.hl7.fhir.r4.model.Bundle; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class FhirBundledPrescriptionBuilder { + private final CareContextService careContextService; + private final OrganizationContextService organizationContextService; + private final FHIRResourceMapper fhirResourceMapper; + + @Autowired + public FhirBundledPrescriptionBuilder(CareContextService careContextService, OrganizationContextService organizationContextService, FHIRResourceMapper fhirResourceMapper) { + this.careContextService = careContextService; + this.organizationContextService = organizationContextService; + this.fhirResourceMapper = fhirResourceMapper; + } + + PrescriptionBundle fhirBundleResponseFor(OpenMrsPrescription openMrsPrescription) { + + OrganizationContext organizationContext = organizationContextService.buildContext(); + + Bundle prescriptionBundle = FhirPrescription + .from(openMrsPrescription, fhirResourceMapper) + .bundle(organizationContext.webUrl()); + + CareContext careContext = careContextService.careContextFor( + openMrsPrescription.getEncounter(), + organizationContext.careContextType()); + + return PrescriptionBundle.builder() + .bundle(prescriptionBundle) + .careContext(careContext) + .build(); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/MedicationRequestService.java b/omod/src/main/java/org/bahmni/module/hip/web/service/MedicationRequestService.java new file mode 100644 index 00000000..6168d625 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/MedicationRequestService.java @@ -0,0 +1,39 @@ +package org.bahmni.module.hip.web.service; + +import org.hl7.fhir.r4.model.MedicationRequest; +import org.openmrs.DrugOrder; +import org.openmrs.module.fhir2.api.translators.MedicationRequestTranslator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class MedicationRequestService { + + private OpenMRSDrugOrderClient openMRSDrugOrderClient; + private MedicationRequestTranslator medicationRequestTranslator; + + @Autowired + public MedicationRequestService(OpenMRSDrugOrderClient openMRSDrugOrderClient, + MedicationRequestTranslator medicationRequestTranslator) { + + this.openMRSDrugOrderClient = openMRSDrugOrderClient; + this.medicationRequestTranslator = medicationRequestTranslator; + } + + List medicationRequestFor(String patientId, String byVisitType) { + + List drugOrders = openMRSDrugOrderClient.drugOrdersFor(patientId, byVisitType); + + return translateToMedicationRequest(drugOrders); + } + + private List translateToMedicationRequest(List drugOrders) { + return drugOrders + .stream() + .map(medicationRequestTranslator::toFhirResource) + .collect(Collectors.toList()); + } +} \ No newline at end of file diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/OPConsultService.java b/omod/src/main/java/org/bahmni/module/hip/web/service/OPConsultService.java new file mode 100644 index 00000000..6094fc06 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/OPConsultService.java @@ -0,0 +1,108 @@ +package org.bahmni.module.hip.web.service; +import org.bahmni.module.hip.api.dao.HipVisitDao; +import org.bahmni.module.hip.api.dao.OPConsultDao; +import org.bahmni.module.hip.web.model.OPConsultBundle; +import org.bahmni.module.hip.web.model.DateRange; +import org.bahmni.module.hip.web.model.OpenMrsCondition; +import org.bahmni.module.hip.web.model.DrugOrders; +import org.bahmni.module.hip.web.model.OpenMrsOPConsult; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.PatientService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import java.util.List; +import java.util.Date; +import java.util.Map; +import java.util.HashMap; +import java.util.stream.Collectors; + +@Service +public class OPConsultService { + + private final FhirBundledOPConsultBuilder fhirBundledOPConsultBuilder; + private final OPConsultDao opConsultDao; + private final PatientService patientService; + private final OpenMRSDrugOrderClient openMRSDrugOrderClient; + private final ConsultationService consultationService; + private final HipVisitDao hipVisitDao; + + + @Autowired + public OPConsultService(FhirBundledOPConsultBuilder fhirBundledOPConsultBuilder, + OPConsultDao opConsultDao, + PatientService patientService, + OpenMRSDrugOrderClient openMRSDrugOrderClient, + ConsultationService consultationService, HipVisitDao hipVisitDao) { + this.fhirBundledOPConsultBuilder = fhirBundledOPConsultBuilder; + this.opConsultDao = opConsultDao; + this.patientService = patientService; + this.openMRSDrugOrderClient = openMRSDrugOrderClient; + this.consultationService = consultationService; + this.hipVisitDao = hipVisitDao; + } + + public List getOpConsultsForVisit(String patientUuid, String visitType, Date visitStartDate) { + Patient patient = patientService.getPatientByUuid(patientUuid); + Visit visit = hipVisitDao.getPatientVisit(patient,visitType,visitStartDate); + + DrugOrders drugOrders = new DrugOrders(openMRSDrugOrderClient.getDrugOrdersByDateAndVisitTypeFor(visit)); + Map encounteredDrugOrdersMap = drugOrders.groupByEncounter(); + Map> encounterChiefComplaintsMap = consultationService.getEncounterChiefComplaintsMap(visit); + Map> encounterMedicalHistoryMap = consultationService.getEncounterMedicalHistoryConditionsMap( visit); + Map> encounterPhysicalExaminationMap = consultationService.getEncounterPhysicalExaminationMap(visit); + Map encounterProcedureMap = getEncounterProcedureMap(visit); + Map> encounterPatientDocumentsMap = consultationService.getEncounterPatientDocumentsMap(visit); + Map> encounterOrdersMap = consultationService.getEncounterOrdersMap(visit); + + List openMrsOPConsultList = OpenMrsOPConsult.getOpenMrsOPConsultList(encounterChiefComplaintsMap, + encounterMedicalHistoryMap, encounterPhysicalExaminationMap, encounteredDrugOrdersMap, encounterProcedureMap, + encounterPatientDocumentsMap, encounterOrdersMap, patient); + + return openMrsOPConsultList.stream(). + map(fhirBundledOPConsultBuilder::fhirBundleResponseFor).collect(Collectors.toList()); + } + + public List getOpConsultsForProgram(String patientUuid, DateRange dateRange, String programName,String programEnrollmentId) { + Date fromDate = dateRange.getFrom(); + Date toDate = dateRange.getTo(); + Patient patient = patientService.getPatientByUuid(patientUuid); + + Map> encounterChiefComplaintsMap = consultationService. getEncounterChiefComplaintsMapForProgram(programName,fromDate,toDate,patient); + Map> encounterMedicalHistoryMap = consultationService.getEncounterMedicalHistoryConditionsMapForProgram(programName,fromDate,toDate,patient); + Map> encounterPhysicalExaminationMap = consultationService.getEncounterPhysicalExaminationMapForProgram(programName,fromDate,toDate,patient); + DrugOrders drugOrders = new DrugOrders(openMRSDrugOrderClient.getDrugOrdersByDateAndProgramFor(patientUuid, dateRange,programName,programEnrollmentId)); + Map encounteredDrugOrdersMap = drugOrders.groupByEncounter(); + Map encounterProcedureMap = getEncounterProcedureMapForProgram(programName,fromDate,toDate,patient); + Map> encounterPatientDocumentsMap = consultationService.getEncounterPatientDocumentsMapForProgram(programName,fromDate,toDate,patient,programEnrollmentId); + Map> encounterOrdersMap = consultationService.getEncounterOrdersMapForProgram(programName,fromDate,toDate,patient); + + List openMrsOPConsultList = OpenMrsOPConsult.getOpenMrsOPConsultList(encounterChiefComplaintsMap, + encounterMedicalHistoryMap, encounterPhysicalExaminationMap, encounteredDrugOrdersMap, encounterProcedureMap, + encounterPatientDocumentsMap, encounterOrdersMap, patient); + + return openMrsOPConsultList.stream(). + map(fhirBundledOPConsultBuilder::fhirBundleResponseFor).collect(Collectors.toList()); + } + + private Map getEncounterProcedureMap(Visit visit) { + List obsProcedures = opConsultDao.getProcedures(visit); + Map encounterProcedureMap = new HashMap<>(); + for(Obs o: obsProcedures){ + encounterProcedureMap.put(o.getEncounter(), o); + } + return encounterProcedureMap; + } + + private Map getEncounterProcedureMapForProgram(String programName, Date fromDate, Date toDate, Patient patient) { + List obsProcedures = opConsultDao.getProceduresForProgram(programName,fromDate, toDate,patient); + Map encounterProcedureMap = new HashMap<>(); + for(Obs o: obsProcedures){ + encounterProcedureMap.put(o.getEncounter(), o); + } + return encounterProcedureMap; + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/OpenMRSDrugOrderClient.java b/omod/src/main/java/org/bahmni/module/hip/web/service/OpenMRSDrugOrderClient.java new file mode 100644 index 00000000..a2b118d3 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/OpenMRSDrugOrderClient.java @@ -0,0 +1,63 @@ +package org.bahmni.module.hip.web.service; + +import org.bahmni.module.hip.api.dao.PrescriptionOrderDao; +import org.bahmni.module.hip.web.model.DateRange; +import org.openmrs.DrugOrder; +import org.openmrs.Order; +import org.openmrs.OrderType; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.OrderService; +import org.openmrs.api.PatientService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + + +@Service +class OpenMRSDrugOrderClient { + + private final PatientService patientService; + private final OrderService orderService; + private final PrescriptionOrderDao prescriptionOrderDao; + + @Autowired + public OpenMRSDrugOrderClient(PatientService patientService, OrderService orderService, PrescriptionOrderDao prescriptionOrderDao) { + this.patientService = patientService; + this.orderService = orderService; + this.prescriptionOrderDao = prescriptionOrderDao; + } + + List drugOrdersFor(String patientUUID, String visitType) { + + Patient patient = patientService.getPatientByUuid(patientUUID); + + return orderService.getAllOrdersByPatient(patient).stream() + .filter(order -> matchesVisitType(visitType, order)) + .filter(this::isDrugOrder) + .map(order -> (DrugOrder) order) + .collect(Collectors.toList()); + } + + private boolean isDrugOrder(Order order) { + return order.getOrderType().getUuid().equals(OrderType.DRUG_ORDER_TYPE_UUID); + } + + private boolean matchesVisitType(String visitType, Order order) { + return order.getEncounter().getVisit().getVisitType().getName().equals(visitType); + } + + List getDrugOrdersByDateAndVisitTypeFor(Visit visit) { + return prescriptionOrderDao + .getDrugOrders(visit); + } + + List getDrugOrdersByDateAndProgramFor(String forPatientUUID, DateRange dateRange, String programName, String programEnrolmentId) { + Patient patient = patientService.getPatientByUuid(forPatientUUID); + OrderType drugOrderType = orderService.getOrderTypeByUuid(OrderType.DRUG_ORDER_TYPE_UUID); + return prescriptionOrderDao + .getDrugOrdersForProgram(patient, dateRange.getFrom(), dateRange.getTo(), drugOrderType, programName, programEnrolmentId); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/OrganizationContextService.java b/omod/src/main/java/org/bahmni/module/hip/web/service/OrganizationContextService.java new file mode 100644 index 00000000..bb3e1655 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/OrganizationContextService.java @@ -0,0 +1,33 @@ +package org.bahmni.module.hip.web.service; + +import org.bahmni.module.hip.Config; +import org.bahmni.module.hip.web.model.OrganizationContext; +import org.hl7.fhir.r4.model.Organization; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; +import org.springframework.stereotype.Service; + +@Service +class OrganizationContextService { + + OrganizationContext buildContext() { + Organization organization = createOrganizationInstance(); + return OrganizationContext.builder() + .organization(organization) + .webUrl(webURL()) + .build(); + } + + private String webURL() { + AdministrationService administrationService = Context.getAdministrationService(); + return administrationService.getGlobalProperty(Config.PROP_HFR_URL.getValue()); + } + + private Organization createOrganizationInstance() { + AdministrationService administrationService = Context.getAdministrationService(); + String hfrId = administrationService.getGlobalProperty(Config.PROP_HFR_ID.getValue()); + String hfrName = administrationService.getGlobalProperty(Config.PROP_HFR_NAME.getValue()); + String hfrSystem = administrationService.getGlobalProperty(Config.PROP_HFR_SYSTEM.getValue()); + return FHIRUtils.createOrgInstance(hfrId, hfrName, hfrSystem); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/PrescriptionService.java b/omod/src/main/java/org/bahmni/module/hip/web/service/PrescriptionService.java new file mode 100644 index 00000000..e268f76f --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/PrescriptionService.java @@ -0,0 +1,71 @@ +package org.bahmni.module.hip.web.service; + + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.hip.api.dao.HipVisitDao; +import org.bahmni.module.hip.web.model.PrescriptionBundle; +import org.bahmni.module.hip.web.model.DateRange; +import org.bahmni.module.hip.web.model.DrugOrders; +import org.bahmni.module.hip.web.model.OpenMrsPrescription; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.PatientService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class PrescriptionService { + private static Logger logger = LogManager.getLogger(PrescriptionService.class); + + private final OpenMRSDrugOrderClient openMRSDrugOrderClient; + private final FhirBundledPrescriptionBuilder fhirBundledPrescriptionBuilder; + private final PatientService patientService; + private final HipVisitDao hipVisitDao; + + @Autowired + public PrescriptionService(OpenMRSDrugOrderClient openMRSDrugOrderClient, FhirBundledPrescriptionBuilder fhirBundledPrescriptionBuilder, PatientService patientService, HipVisitDao hipVisitDao) { + this.openMRSDrugOrderClient = openMRSDrugOrderClient; + this.fhirBundledPrescriptionBuilder = fhirBundledPrescriptionBuilder; + this.patientService = patientService; + this.hipVisitDao = hipVisitDao; + } + + + public List getPrescriptions(String patientUuid,String visitType, Date visitStartDate) { + Patient patient = patientService.getPatientByUuid(patientUuid); + Visit visit = hipVisitDao.getPatientVisit(patient,visitType,visitStartDate); + DrugOrders drugOrders = new DrugOrders(openMRSDrugOrderClient.getDrugOrdersByDateAndVisitTypeFor(visit)); + + if (drugOrders.isEmpty()) + return new ArrayList<>(); + + List openMrsPrescriptions = OpenMrsPrescription + .from(drugOrders.groupByEncounter()); + + return openMrsPrescriptions + .stream() + .map(fhirBundledPrescriptionBuilder::fhirBundleResponseFor) + .collect(Collectors.toList()); + } + + public List getPrescriptionsForProgram(String patientIdUuid, DateRange dateRange, String programName, String programEnrolmentId) { + DrugOrders drugOrders = new DrugOrders(openMRSDrugOrderClient.getDrugOrdersByDateAndProgramFor(patientIdUuid, dateRange, programName, programEnrolmentId)); + + if (drugOrders.isEmpty()) + return new ArrayList<>(); + + List openMrsPrescriptions = OpenMrsPrescription + .from(drugOrders.groupByEncounter()); + + return openMrsPrescriptions + .stream() + .map(fhirBundledPrescriptionBuilder::fhirBundleResponseFor) + .collect(Collectors.toList()); + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/Utils.java b/omod/src/main/java/org/bahmni/module/hip/web/service/Utils.java new file mode 100644 index 00000000..148901f3 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/Utils.java @@ -0,0 +1,19 @@ +package org.bahmni.module.hip.web.service; + +public class Utils { + public static String ensureTrailingSlash(String url) { + return url.endsWith("/") ? url : url + "/"; + } + + public static boolean isBlank(String value) { + if (value == null) { + return true; + } + + if ("".equals(value.trim())) { + return true; + } + + return false; + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/service/ValidationService.java b/omod/src/main/java/org/bahmni/module/hip/web/service/ValidationService.java new file mode 100644 index 00000000..d2821925 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/service/ValidationService.java @@ -0,0 +1,62 @@ +package org.bahmni.module.hip.web.service; + +import org.openmrs.Patient; +import org.openmrs.Program; +import org.openmrs.VisitType; +import org.openmrs.api.PatientService; +import org.openmrs.api.ProgramWorkflowService; +import org.openmrs.api.VisitService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +import java.util.List; +@Service +@Qualifier("validationService") +public class ValidationService { + private final VisitService visitService; + private final PatientService patientService; + private final ProgramWorkflowService programWorkflowService; + private final ExistingPatientService existingPatientService; + + @Autowired + public ValidationService(VisitService visitService, PatientService patientService, ProgramWorkflowService programWorkflowService, ExistingPatientService existingPatientService) { + this.patientService = patientService; + this.visitService = visitService; + this.programWorkflowService = programWorkflowService; + this.existingPatientService = existingPatientService; + } + + public boolean isValidVisit(String visitType) { + List visitTypes = visitService.getAllVisitTypes(); + for (VisitType vType : visitTypes) { + if (vType.getName().toLowerCase().equals(visitType.toLowerCase())) { + return true; + } + } + return false; + } + + public boolean isValidPatient(String pid) { + Patient patient = patientService.getPatientByUuid(pid); + return patient != null; + } + + public boolean isValidProgram(String programName) { + Program program = programWorkflowService.getProgramByName(programName); + if(program != null) + return true; + return false; + } + + public boolean isValidHealthId(String healthId){ + Patient patient = null; + try { + patient = patientService.getPatientByUuid(existingPatientService.getPatientWithHealthId(healthId)); + } + catch (NullPointerException ignored){ + + } + return patient != null; + } +} diff --git a/omod/src/main/java/org/bahmni/module/hip/web/utils/DateUtils.java b/omod/src/main/java/org/bahmni/module/hip/web/utils/DateUtils.java new file mode 100644 index 00000000..da7b9967 --- /dev/null +++ b/omod/src/main/java/org/bahmni/module/hip/web/utils/DateUtils.java @@ -0,0 +1,21 @@ +package org.bahmni.module.hip.web.utils; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class DateUtils { + public static Date parseDate(String date) throws ParseException { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + return dateFormat.parse(date); + } + + public static Date parseDateTime(String date) throws ParseException { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return dateFormat.parse(date); + } + + public static boolean isDateBetweenDateRange(String date, String fromDate, String toDate) throws ParseException { + return parseDate(date).compareTo(parseDate(fromDate)) >= 0 && parseDate(date).compareTo(parseDate(toDate)) < 0; + } +} diff --git a/omod/src/main/java/org/openmrs/module/basicmodule/extension/html/AdminList.java b/omod/src/main/java/org/openmrs/module/basicmodule/extension/html/AdminList.java deleted file mode 100644 index 8974905f..00000000 --- a/omod/src/main/java/org/openmrs/module/basicmodule/extension/html/AdminList.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * The contents of this file are subject to the OpenMRS Public License - * Version 1.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://license.openmrs.org - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the - * License for the specific language governing rights and limitations - * under the License. - * - * Copyright (C) OpenMRS, LLC. All Rights Reserved. - */ -package org.openmrs.module.basicmodule.extension.html; - -import java.util.HashMap; -import java.util.Map; - -import org.openmrs.module.Extension; -import org.openmrs.module.web.extension.AdministrationSectionExt; - -/** - * This class defines the links that will appear on the administration page under the - * "basicmodule.title" heading. This extension is enabled by defining (uncommenting) it in the - * /metadata/config.xml file. - */ -public class AdminList extends AdministrationSectionExt { - - /** - * @see org.openmrs.module.web.extension.AdministrationSectionExt#getMediaType() - */ - public Extension.MEDIA_TYPE getMediaType() { - return Extension.MEDIA_TYPE.html; - } - - /** - * @see org.openmrs.module.web.extension.AdministrationSectionExt#getTitle() - */ - public String getTitle() { - return "basicmodule.title"; - } - - /** - * @see org.openmrs.module.web.extension.AdministrationSectionExt#getLinks() - */ - public Map getLinks() { - - Map map = new HashMap(); - - map.put("module/basicmodule/basicmoduleLink.form", "basicmodule.replace.this.link.name"); - - return map; - } - -} diff --git a/omod/src/main/java/org/openmrs/module/basicmodule/web/controller/BasicModuleFormController.java b/omod/src/main/java/org/openmrs/module/basicmodule/web/controller/BasicModuleFormController.java deleted file mode 100644 index 5f9eaca0..00000000 --- a/omod/src/main/java/org/openmrs/module/basicmodule/web/controller/BasicModuleFormController.java +++ /dev/null @@ -1,91 +0,0 @@ -/** - * The contents of this file are subject to the OpenMRS Public License - * Version 1.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://license.openmrs.org - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the - * License for the specific language governing rights and limitations - * under the License. - * - * Copyright (C) OpenMRS, LLC. All Rights Reserved. - */ -package org.openmrs.module.basicmodule.web.controller; - -import java.util.Collection; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.openmrs.Patient; -import org.openmrs.api.context.Context; -import org.springframework.stereotype.Controller; -import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -/** - * This class configured as controller using annotation and mapped with the URL of - * 'module/basicmodule/basicmoduleLink.form'. - */ -@Controller -@RequestMapping(value = "module/basicmodule/basicmoduleLink.form") -public class BasicModuleFormController { - - /** Logger for this class and subclasses */ - protected final Log log = LogFactory.getLog(getClass()); - - /** Success form view name */ - private final String SUCCESS_FORM_VIEW = "/module/basicmodule/basicmoduleForm"; - - /** - * Initially called after the formBackingObject method to get the landing form name - * - * @return String form view name - */ - @RequestMapping(method = RequestMethod.GET) - public String showForm() { - return SUCCESS_FORM_VIEW; - } - - /** - * All the parameters are optional based on the necessity - * - * @param httpSession - * @param anyRequestObject - * @param errors - * @return - */ - @RequestMapping(method = RequestMethod.POST) - public String onSubmit(HttpSession httpSession, @ModelAttribute("anyRequestObject") Object anyRequestObject, - BindingResult errors) { - - if (errors.hasErrors()) { - // return error view - } - - return SUCCESS_FORM_VIEW; - } - - /** - * This class returns the form backing object. This can be a string, a boolean, or a normal java - * pojo. The bean name defined in the ModelAttribute annotation and the type can be just defined - * by the return type of this method - */ - @ModelAttribute("thePatientList") - protected Collection formBackingObject(HttpServletRequest request) throws Exception { - // get all patients that have an identifier "101" (from the demo sample data) - // see http://resources.openmrs.org/doc/index.html?org/openmrs/api/PatientService.html for - // a list of all PatientService methods - Collection patients = Context.getPatientService().findPatients("101", false); - - // this object will be made available to the jsp page under the variable name - // that is defined in the @ModuleAttribute tag - return patients; - } - -} diff --git a/omod/src/main/resources/config.xml b/omod/src/main/resources/config.xml index 076e6d33..1645d068 100644 --- a/omod/src/main/resources/config.xml +++ b/omod/src/main/resources/config.xml @@ -3,28 +3,30 @@ - ${project.parent.artifactId} - ${project.parent.name} - ${project.parent.version} - ${MODULE_PACKAGE} - Ben Wolfe + hipmodule + HIP Module OMOD + 0.1-SNAPSHOT + org.bahmni.module.hip + + Stream 1 - ${project.parent.description} + Hip module omod - ${MODULE_PACKAGE}.BasicModuleActivator + org.bahmni.module.hip.BasicModuleActivator ${openmrs.platform.version} - - - - org.openmrs.admin.list - ${MODULE_PACKAGE}.extension.html.AdminList - - + + + org.openmrs.module.webservices.rest + org.openmrs.module.fhir2 + org.openmrs.module.emrapi + org.bahmni.module.bahmnicore + org.bahmni.module.bahmnicommons + - - + + bahmniHip.healthFacilityRegistryId + HFR_ID + + Unique identifier from the Health Facility Registry + + + + bahmniHip.healthFacilityName + HFR_NAME + + Name of the facility as in Health Facility Registry + + + + bahmniHip.healthFacilitySystem + http://affinitydomain.com/hfr + + The system URL where Health Facility Registry is registered + + + + bahmniHip.practitionerSystem + http://affinitydomain.com/practitioner + + The system URL where Practitioners are registered + + - @MODULE_ID@.someProperty - + bahmniHip.healthFacilityUrl + http://www.myorg.com/ - A description of the global property goes here. The description - should explain enough for administrators to understand the purpose - and possible values for the global property. + Website URL of the organization/hip - /Required Global Properties --> + - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/omod/src/test/java/org/bahmni/module/hip/web/TestConfiguration.java b/omod/src/test/java/org/bahmni/module/hip/web/TestConfiguration.java new file mode 100644 index 00000000..e505fae7 --- /dev/null +++ b/omod/src/test/java/org/bahmni/module/hip/web/TestConfiguration.java @@ -0,0 +1,51 @@ +package org.bahmni.module.hip.web; + +import org.bahmni.module.hip.web.service.ExistingPatientService; +import org.bahmni.module.hip.web.service.PrescriptionService; +import org.bahmni.module.hip.web.service.ValidationService; +import org.bahmni.module.hip.web.service.CareContextService; +import org.bahmni.module.hip.web.service.BundleMedicationRequestService; +import org.bahmni.module.hip.web.service.DiagnosticReportService; +import org.bahmni.module.hip.web.service.OPConsultService; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +import static org.mockito.Mockito.mock; + +@Configuration +@EnableWebMvc +public class TestConfiguration { + @Bean + public BundleMedicationRequestService bundleMedicationRequestService() { + return mock(BundleMedicationRequestService.class); + } + + @Bean + public PrescriptionService prescriptionService() { + return mock(PrescriptionService.class); + } + + @Bean + public CareContextService careContextService() { + return mock(CareContextService.class); + } + + @Bean + public ValidationService validationService() { + return mock(ValidationService.class); + } + + @Bean + public DiagnosticReportService diagnosticReportService() { + return mock(DiagnosticReportService.class); + } + + @Bean + public ExistingPatientService existingPatientService() { + return mock(ExistingPatientService.class); + } + + @Bean + public OPConsultService opConsultService() {return mock(OPConsultService.class);} +} \ No newline at end of file diff --git a/omod/src/test/java/org/bahmni/module/hip/web/builders/DrugOrderBuilder.java b/omod/src/test/java/org/bahmni/module/hip/web/builders/DrugOrderBuilder.java new file mode 100644 index 00000000..35e72a58 --- /dev/null +++ b/omod/src/test/java/org/bahmni/module/hip/web/builders/DrugOrderBuilder.java @@ -0,0 +1,30 @@ +package org.bahmni.module.hip.web.builders; + +import org.openmrs.DrugOrder; +import org.openmrs.Encounter; + +public class DrugOrderBuilder { + private String drugOrderUUID; + private Encounter encounter; + + public DrugOrderBuilder(String drugOrderUUID) { + this.drugOrderUUID = drugOrderUUID; + } + + public DrugOrderBuilder withEncounter(Encounter encounter) { + this.encounter = encounter; + return this; + } + + public static DrugOrderBuilder getBuilder(String drugOrderUUID) { + return new DrugOrderBuilder(drugOrderUUID); + } + + public DrugOrder build() { + DrugOrder drugOrder = new DrugOrder(); + drugOrder.setUuid(drugOrderUUID); + drugOrder.setEncounter(this.encounter); + + return drugOrder; + } +} diff --git a/omod/src/test/java/org/bahmni/module/hip/web/builders/EncounterBuilder.java b/omod/src/test/java/org/bahmni/module/hip/web/builders/EncounterBuilder.java new file mode 100644 index 00000000..39d1aa84 --- /dev/null +++ b/omod/src/test/java/org/bahmni/module/hip/web/builders/EncounterBuilder.java @@ -0,0 +1,21 @@ +package org.bahmni.module.hip.web.builders; + +import lombok.AllArgsConstructor; +import org.openmrs.Encounter; + +@AllArgsConstructor +public class EncounterBuilder { + private String encounterUUID; + + public static EncounterBuilder getBuilder(String encounterUUID) { + return new EncounterBuilder(encounterUUID); + } + + public Encounter build() { + Encounter encounter = new Encounter(); + encounter.setUuid(encounterUUID); + + return encounter; + } + +} diff --git a/omod/src/test/java/org/bahmni/module/hip/web/controller/BundledMedicationRequestControllerIntegrationTest.java b/omod/src/test/java/org/bahmni/module/hip/web/controller/BundledMedicationRequestControllerIntegrationTest.java new file mode 100644 index 00000000..10209787 --- /dev/null +++ b/omod/src/test/java/org/bahmni/module/hip/web/controller/BundledMedicationRequestControllerIntegrationTest.java @@ -0,0 +1,148 @@ +package org.bahmni.module.hip.web.controller; + +import org.bahmni.module.hip.web.TestConfiguration; +import org.bahmni.module.hip.web.service.BundleMedicationRequestService; +import org.bahmni.module.hip.web.service.ValidationService; +import org.hl7.fhir.r4.model.Bundle; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {BundledMedicationRequestController.class, TestConfiguration.class}) +@WebAppConfiguration +public class BundledMedicationRequestControllerIntegrationTest { + + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext wac; + + @Autowired + private BundleMedicationRequestService bundledMedicationRequestService; + + @Autowired + private ValidationService validationService; + + @Before + public void setup() { + DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.wac); + this.mockMvc = builder.build(); + } + + @Test + public void shouldReturn200OkOnSuccess() throws Exception { + when(validationService.isValidVisit("OPD")).thenReturn(true); + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745bd")).thenReturn(true); + when(bundledMedicationRequestService.bundleMedicationRequestsFor(anyString(), anyString())) + .thenReturn(new Bundle()); + + mockMvc.perform(get("/rest/" + RestConstants.VERSION_1 + "/hip/medication?patientId=0f90531a-285c-438b-b265-bb3abb4745bd" + + "&visitType=OPD") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + @Test + public void shouldReturn400OkOnInvalidVisitType() throws Exception { + when(validationService.isValidVisit("OP")).thenReturn(false); + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745bd")).thenReturn(true); + when(bundledMedicationRequestService.bundleMedicationRequestsFor(anyString(), anyString())) + .thenReturn(new Bundle()); + + mockMvc.perform(get("/rest/" + RestConstants.VERSION_1 + "/hip/medication?patientId=0f90531a-285c-438b-b265-bb3abb4745bd" + + "&visitType=OP") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()); + verify(validationService, times(1)).isValidVisit("OP"); + } + + @Test + public void shouldReturn400OkOnInvalidPatientId() throws Exception { + when(validationService.isValidVisit("OPD")).thenReturn(true); + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745")).thenReturn(false); + when(bundledMedicationRequestService.bundleMedicationRequestsFor(anyString(), anyString())) + .thenReturn(new Bundle()); + + mockMvc.perform(get("/rest/" + RestConstants.VERSION_1 + "/hip/medication?patientId=0f90531a-285c-438b-b265-bb3abb4745" + + "&visitType=OPD") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()); + verify(validationService, times(1)).isValidVisit("OPD"); + verify(validationService, times(1)).isValidPatient("0f90531a-285c-438b-b265-bb3abb4745"); + + } + + @Test + public void shouldReturnHttpBadRequestWhenPatientIdIsMissing() throws Exception { + + when(bundledMedicationRequestService.bundleMedicationRequestsFor(anyString(), anyString())) + .thenReturn(new Bundle()); + + MvcResult mvcResult = mockMvc.perform(get("/rest/" + RestConstants.VERSION_1 + "/hip/medication") + .contentType(MediaType.APPLICATION_JSON)) + .andReturn(); + + assertEquals(400, mvcResult.getResponse().getStatus()); + } + + @Test + public void shouldReturnHttpInternalServerErrorWhenPatientIdIsEmpty() throws Exception { + + when(bundledMedicationRequestService.bundleMedicationRequestsFor(anyString(), anyString())) + .thenReturn(new Bundle()); + + MvcResult mvcResult = mockMvc.perform(get("/rest/" + RestConstants.VERSION_1 + "/hip/medication?patient=&visitType='OPD'") + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + + assertEquals(400, mvcResult.getResponse().getStatus()); + } + + @Test + public void shouldReturnHttpBadRequestWhenVisitTypeIsEmpty() throws Exception { + + when(bundledMedicationRequestService.bundleMedicationRequestsFor(anyString(), anyString())) + .thenReturn(new Bundle()); + + MvcResult mvcResult = mockMvc.perform(get("/rest/" + RestConstants.VERSION_1 + + "/hip/medication?patient='0f90531a-285c-438b-b265-bb3abb4745bd'&visitType=") + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + + assertEquals(400, mvcResult.getResponse().getStatus()); + } + + @Test + public void shouldReturnHttpBadRequestWhenPatientIdIsInvalid() throws Exception { + + when(bundledMedicationRequestService.bundleMedicationRequestsFor(anyString(), anyString())) + .thenReturn(new Bundle()); + + MvcResult mvcResult = mockMvc.perform(get("/rest/" + RestConstants.VERSION_1 + + "/hip/medication?patient='0f90531a-285c-4'&visitType=") + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + + assertEquals(400, mvcResult.getResponse().getStatus()); + } +} diff --git a/omod/src/test/java/org/bahmni/module/hip/web/controller/CareContextControllerTest.java b/omod/src/test/java/org/bahmni/module/hip/web/controller/CareContextControllerTest.java new file mode 100644 index 00000000..96b5c8ad --- /dev/null +++ b/omod/src/test/java/org/bahmni/module/hip/web/controller/CareContextControllerTest.java @@ -0,0 +1,158 @@ +package org.bahmni.module.hip.web.controller; + +import org.bahmni.module.hip.model.PatientCareContext; +import org.bahmni.module.hip.web.TestConfiguration; +import org.bahmni.module.hip.web.client.ClientError; +import org.bahmni.module.hip.web.model.serializers.NewCareContext; +import org.bahmni.module.hip.web.service.CareContextService; +import org.bahmni.module.hip.web.service.ValidationService; +import org.codehaus.jackson.map.ObjectMapper; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {CareContextController.class, TestConfiguration.class}) +@WebAppConfiguration +public class CareContextControllerTest { + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext wac; + + @Autowired + private CareContextService careContextService; + + @Autowired + private ValidationService validationService; + + @Before + public void setup() { + DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.wac); + this.mockMvc = builder.build(); + } + + @Test + public void shouldReturn200OkWhenPatientIdIsGiven() throws Exception { + List patientCareContextList = new ArrayList<>(); + patientCareContextList.add(PatientCareContext.builder() + .careContextName("TB Program") + .careContextType("PROGRAM") + .careContextReference("SUPER MAN") + .build()); + when(careContextService.careContextForPatient(anyString())) + .thenReturn(patientCareContextList); + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745bd")).thenReturn(true); + + mockMvc.perform(get(String.format("/rest/%s/hip/careContext", RestConstants.VERSION_1)) + .param("patientUuid", "0f90531a-285c-438b-b265-bb3abb4745bd") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + @Test + public void shouldReturn400BadRequestWhenPatientIdContainsCharacters() throws Exception { + List patientCareContextList = new ArrayList<>(); + patientCareContextList.add(PatientCareContext.builder() + .careContextName("TB Program") + .careContextType("PROGRAM") + .careContextReference("SUPER MAN") + .build()); + when(careContextService.careContextForPatient(anyString())) + .thenReturn(patientCareContextList); + + + MvcResult mvcResult = mockMvc.perform(get(String.format("/rest/%s/hip/careContext", RestConstants.VERSION_1)) + .param("patientUuid", "72aa") + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + + String content = mvcResult.getResponse().getContentAsString(); + String responseBody = new ObjectMapper().writeValueAsString(ClientError.invalidPatientId()); + assertEquals(responseBody, content); + } + + @Test + public void shouldReturn400BadRequestWhenNoPatientIdProvided() throws Exception { + List patientCareContextList = new ArrayList<>(); + patientCareContextList.add(PatientCareContext.builder() + .careContextName("TB Program") + .careContextType("PROGRAM") + .careContextReference("SUPER MAN") + .build()); + when(careContextService.careContextForPatient(anyString())) + .thenReturn(patientCareContextList); + + + MvcResult mvcResult = mockMvc.perform(get(String.format("/rest/%s/hip/careContext", RestConstants.VERSION_1)) + .param("patientUuid", " ") + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + + String content = mvcResult.getResponse().getContentAsString(); + String responseBody = new ObjectMapper().writeValueAsString(ClientError.noPatientIdProvided()); + assertEquals(responseBody, content); + } + + @Test + public void shouldReturn400BadRequestWhenNoPatientIdProvidedForNewContext() throws Exception { + + MvcResult mvcResult = mockMvc.perform(get(String.format("/rest/%s/hip/careContext/new", RestConstants.VERSION_1)) + .param("patientUuid", " ") + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + + String content = mvcResult.getResponse().getContentAsString(); + String responseBody = new ObjectMapper().writeValueAsString(ClientError.noPatientIdProvided()); + assertEquals(responseBody, content); + } + + @Test + public void shouldReturn400BadRequestForInvalidPatientUUID() throws Exception { + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745bd")).thenReturn(false); + + MvcResult mvcResult = mockMvc.perform(get(String.format("/rest/%s/hip/careContext/new", RestConstants.VERSION_1)) + .param("patientUuid", "0f90531a-285c-438b-b265-bb3abb4745bd") + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + + String content = mvcResult.getResponse().getContentAsString(); + String responseBody = new ObjectMapper().writeValueAsString(ClientError.invalidPatientId()); + assertEquals(responseBody, content); + } + + @Test + public void shouldReturn200OKForValidPatientUUID() throws Exception { + NewCareContext newCareContext = new NewCareContext("abc", "abc@sbc", "12gvx", new ArrayList<>()); + + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745bd")).thenReturn(true); + when(careContextService.newCareContextsForPatient(anyString())) + .thenReturn(newCareContext); + + mockMvc.perform(get(String.format("/rest/%s/hip/careContext/new", RestConstants.VERSION_1)) + .param("patientUuid", "0f90531a-285c-438b-b265-bb3abb4745bd") + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + + } +} diff --git a/omod/src/test/java/org/bahmni/module/hip/web/controller/DiagnosticReportControllerTest.java b/omod/src/test/java/org/bahmni/module/hip/web/controller/DiagnosticReportControllerTest.java new file mode 100644 index 00000000..c026c6f1 --- /dev/null +++ b/omod/src/test/java/org/bahmni/module/hip/web/controller/DiagnosticReportControllerTest.java @@ -0,0 +1,157 @@ +package org.bahmni.module.hip.web.controller; + +import junit.framework.TestCase; +import org.bahmni.module.hip.web.TestConfiguration; +import org.bahmni.module.hip.web.service.DiagnosticReportService; +import org.bahmni.module.hip.web.service.ValidationService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static java.util.Collections.EMPTY_LIST; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {DiagnosticReportController.class, TestConfiguration.class}) +@WebAppConfiguration +public class DiagnosticReportControllerTest extends TestCase { + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext wac; + + @Autowired + private DiagnosticReportService diagnosticReportService; + + @Autowired + private ValidationService validationService; + + @Before + public void setup() { + DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.wac); + this.mockMvc = builder.build(); + } + + @Test + public void shouldReturn200ForVisits() throws Exception { + when(validationService.isValidVisit("IPD")).thenReturn(true); + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745bd")).thenReturn(true); + when(diagnosticReportService.getDiagnosticReportsForVisit(anyString(), anyString(),any())) + .thenReturn(EMPTY_LIST); + + mockMvc.perform(get(String.format("/rest/%s/hip/diagnosticReports/visit", RestConstants.VERSION_1)) + .param("visitType", "IPD") + .param("visitStartDate", "2020-01-01 12:00:00") + .param("patientId", "0f90531a-285c-438b-b265-bb3abb4745bd") + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + @Test + public void shouldReturn400OnInvalidVisitType() throws Exception { + when(validationService.isValidVisit("OP")).thenReturn(false); + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745bd")).thenReturn(true); + when(diagnosticReportService.getDiagnosticReportsForVisit(anyString(), anyString(),any())) + .thenReturn(EMPTY_LIST); + + mockMvc.perform(get(String.format("/rest/%s/hip/diagnosticReports/visit", RestConstants.VERSION_1)) + .param("visitType", "OP") + .param("visitStartDate", "2020-01-01 12:00:00") + .param("patientId", "0f90531a-285c-438b-b265-bb3abb4745bd") + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()); + } + + @Test + public void shouldReturn400OnInvalidPatientId() throws Exception { + when(validationService.isValidVisit("IPD")).thenReturn(true); + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745")).thenReturn(false); + when(diagnosticReportService.getDiagnosticReportsForVisit(anyString(), anyString(),any())) + .thenReturn(EMPTY_LIST); + + mockMvc.perform(get(String.format("/rest/%s/hip/diagnosticReports/visit", RestConstants.VERSION_1)) + .param("visitType", "IPD") + .param("visitStartDate", "2020-01-01 12:00:00") + .param("patientId", "0f90531a-285c-438b-b265-bb3abb4745") + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()); + } + + @Test + public void shouldReturn500ForMissingFieldForVisit() throws Exception { + MvcResult mvcResult = mockMvc.perform(get(String.format("/rest/%s/hip/diagnosticReports/visit", RestConstants.VERSION_1)) + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + + assertEquals(500, mvcResult.getResponse().getStatus()); + } + + @Test + public void shouldReturn200ForForPrograms() throws Exception { + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745bd")).thenReturn(true); + when(validationService.isValidProgram("HIV Program")).thenReturn(true); + when(diagnosticReportService.getDiagnosticReportsForProgram(anyString(), any(), anyString(), anyString())) + .thenReturn(EMPTY_LIST); + + mockMvc.perform(get(String.format("/rest/%s/hip/diagnosticReports/program", RestConstants.VERSION_1)) + .param("programName", "HIV Program") + .param("programEnrollmentId", "123") + .param("patientId", "0f90531a-285c-438b-b265-bb3abb4745bd") + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + @Test + public void shouldReturn400OnInvalidProgram() throws Exception { + when(validationService.isValidVisit("TB")).thenReturn(false); + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745bd")).thenReturn(true); + when(diagnosticReportService.getDiagnosticReportsForProgram(anyString(), any(), anyString(), anyString())) + .thenReturn(EMPTY_LIST); + + mockMvc.perform(get(String.format("/rest/%s/hip/diagnosticReports/program", RestConstants.VERSION_1)) + .param("programName", "TB") + .param("programEnrollmentId", "123") + .param("patientId", "0f90531a-285c-438b-b265-bb3abb4745bd") + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()); + } + + @Test + public void shouldReturn500ForMissingFieldForPrograms() throws Exception { + MvcResult mvcResult = mockMvc.perform(get(String.format("/rest/%s/hip/diagnosticReports/program", RestConstants.VERSION_1)) + .param("programName", "IPD") + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + + assertEquals(500, mvcResult.getResponse().getStatus()); + } +} \ No newline at end of file diff --git a/omod/src/test/java/org/bahmni/module/hip/web/controller/OPConsultControllerTest.java b/omod/src/test/java/org/bahmni/module/hip/web/controller/OPConsultControllerTest.java new file mode 100644 index 00000000..b720b7b9 --- /dev/null +++ b/omod/src/test/java/org/bahmni/module/hip/web/controller/OPConsultControllerTest.java @@ -0,0 +1,111 @@ +package org.bahmni.module.hip.web.controller; + +import org.bahmni.module.hip.web.TestConfiguration; +import org.bahmni.module.hip.web.service.OPConsultService; +import org.bahmni.module.hip.web.service.ValidationService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static java.util.Collections.EMPTY_LIST; +import static org.junit.Assert.*; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {OPConsultController.class, TestConfiguration.class}) +@WebAppConfiguration +public class OPConsultControllerTest { + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext wac; + + @Autowired + private OPConsultService opConsultService; + + @Autowired + private ValidationService validationService; + + @Before + public void setup() { + DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.wac); + this.mockMvc = builder.build(); + } + + @Test + public void shouldReturn200ForVisits() throws Exception { + when(validationService.isValidVisit("IPD")).thenReturn(true); + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745bd")).thenReturn(true); + when(opConsultService.getOpConsultsForVisit(anyString(), anyString(),any())) + .thenReturn(EMPTY_LIST); + + mockMvc.perform(get(String.format("/rest/%s/hip/opConsults/visit", RestConstants.VERSION_1)) + .param("visitType", "IPD") + .param("visitStartDate", "2020-01-01 12:00:00") + .param("patientId", "0f90531a-285c-438b-b265-bb3abb4745bd") + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + @Test + public void shouldReturn400OnInvalidVisitType() throws Exception { + when(validationService.isValidVisit("OP")).thenReturn(false); + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745bd")).thenReturn(true); + when(opConsultService.getOpConsultsForVisit(anyString(), anyString(),any())) + .thenReturn(EMPTY_LIST); + + mockMvc.perform(get(String.format("/rest/%s/hip/opConsults/visit", RestConstants.VERSION_1)) + .param("visitType", "OP") + .param("visitStartDate", "2020-01-01") + .param("patientId", "0f90531a-285c-438b-b265-bb3abb4745bd") + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()); + } + + @Test + public void shouldReturn400OnInvalidPatientId() throws Exception { + when(validationService.isValidVisit("IPD")).thenReturn(true); + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745")).thenReturn(false); + when(opConsultService.getOpConsultsForVisit(anyString(), anyString(),any())) + .thenReturn(EMPTY_LIST); + + mockMvc.perform(get(String.format("/rest/%s/hip/opConsults/visit", RestConstants.VERSION_1)) + .param("visitType", "IPD") + .param("visitStartDate", "2020-01-01") + .param("patientId", "0f90531a-285c-438b-b265-bb3abb4745") + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()); + } + + @Test + public void shouldReturn500ForMissingFieldForVisit() throws Exception { + MvcResult mvcResult = mockMvc.perform(get(String.format("/rest/%s/hip/opConsults/visit", RestConstants.VERSION_1)) + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + + assertEquals(500, mvcResult.getResponse().getStatus()); + } +} \ No newline at end of file diff --git a/omod/src/test/java/org/bahmni/module/hip/web/controller/PatientControllerTest.java b/omod/src/test/java/org/bahmni/module/hip/web/controller/PatientControllerTest.java new file mode 100644 index 00000000..94198501 --- /dev/null +++ b/omod/src/test/java/org/bahmni/module/hip/web/controller/PatientControllerTest.java @@ -0,0 +1,188 @@ +package org.bahmni.module.hip.web.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import junit.framework.TestCase; +import org.bahmni.module.hip.web.TestConfiguration; +import org.bahmni.module.hip.web.client.ClientError; +import org.bahmni.module.hip.web.client.model.Error; +import org.bahmni.module.hip.web.client.model.ErrorCode; +import org.bahmni.module.hip.web.client.model.ErrorRepresentation; +import org.bahmni.module.hip.web.model.ExistingPatient; +import org.bahmni.module.hip.web.service.ExistingPatientService; +import org.bahmni.module.hip.web.service.ValidationService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openmrs.Patient; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import javax.servlet.http.Cookie; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; + +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {PatientController.class, TestConfiguration.class}) +@WebAppConfiguration +public class PatientControllerTest extends TestCase { + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext wac; + + @Autowired + private ExistingPatientService existingPatientService; + + @Autowired + private ValidationService validationService; + + @Before + public void setup() { + DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.wac); + this.mockMvc = builder.build(); + } + + @Test + public void shouldReturn200OKWhenMatchingPatientFound() throws Exception { + Patient patient = mock(Patient.class); + List patients = new ArrayList<>(); + patients.add(patient); + ExistingPatient existingPatient = new ExistingPatient("sam tom", "35", "null, null", "M", "3f81c3b4-04fc-4311-9b50-b863fbe023dc", "9123456780"); + when(existingPatientService.getMatchingPatients("+91-9876543210")) + .thenReturn(new ArrayList<>()); + when(existingPatientService.getMatchingPatients(anyString(),anyString(), anyInt(), anyString())) + .thenReturn(patients); + when(existingPatientService.getMatchingPatientDetails(new HashSet<>(patients))) + .thenReturn(Collections.singletonList(existingPatient)); + + mockMvc.perform(get(String.format("/rest/%s/hip/existingPatients", RestConstants.VERSION_1)) + .param("patientName", "sam tom") + .param("patientYearOfBirth", "1985") + .param("patientGender", "M") + .param("phoneNumber", "+91-9876543210") + .cookie(new Cookie("bahmni.user.location", "{\"name\":\"General Ward\",\"uuid\":\"baf7bd38-d225-11e4-9c67-080027b662ec\"}")) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + @Test + public void shouldReturnNoRecordsWhenNoMatchingPatientFound() throws Exception { + List patients = new ArrayList<>(); + when(existingPatientService.getMatchingPatients("+91-9876543210")) + .thenReturn(new ArrayList<>()); + when(existingPatientService.getMatchingPatients(anyString(),anyString(), anyInt(), anyString())) + .thenReturn(patients); + + MvcResult mvcResult = mockMvc.perform(get(String.format("/rest/%s/hip/existingPatients", RestConstants.VERSION_1)) + .param("patientName", "sam tom") + .param("patientYearOfBirth", "1985") + .param("patientGender", "M") + .param("phoneNumber", "+91-9876543210") + .cookie(new Cookie("bahmni.user.location", "{\"name\":\"General Ward\",\"uuid\":\"baf7bd38-d225-11e4-9c67-080027b662ec\"}")) + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + + ObjectMapper objectMapper = new ObjectMapper(); + String value = objectMapper.writeValueAsString(new ErrorRepresentation + (new Error(ErrorCode.PATIENT_ID_NOT_FOUND, "No patient found"))); + assertEquals(value, + mvcResult.getResponse().getContentAsString()); + } + + @Test + public void shouldReturnPatientUuidWhenTheHealthIdIsLinkedToAPatient() throws Exception { + when(existingPatientService.getPatientWithHealthId("abc.xyz@sbx")).thenReturn("bd27cbfd-b395-4a8a-af71-b27535b85e31"); + mockMvc.perform(get(String.format("/rest/%s/hip/existingPatients/" + "abc.xyz@sbx", RestConstants.VERSION_1)) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + @Test + public void shouldReturnNoPatientFoundAsResponseWhenTheHealthIdIsNotLinkedToAnyPatient() throws Exception { + when(existingPatientService.getPatientWithHealthId("def.xyz@sbx")).thenReturn(null); + + MvcResult mvcResult = mockMvc.perform(get(String.format("/rest/%s/hip/existingPatients/" + "def.xyz@sbx", RestConstants.VERSION_1)) + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + + ObjectMapper objectMapper = new ObjectMapper(); + String value = objectMapper.writeValueAsString(new ErrorRepresentation + (new Error(ErrorCode.PATIENT_ID_NOT_FOUND, "No patient found"))); + assertEquals(value, + mvcResult.getResponse().getContentAsString()); + } + + @Test + public void shouldReturnNoPatientIdentifierFoundIfHealthIsNotPresent() throws Exception { + when(validationService.isValidHealthId("test@sbx")).thenReturn(false); + + MvcResult mvcResult = mockMvc.perform(get(String.format("/rest/%s/hip/existingPatients/status", RestConstants.VERSION_1)) + .param("healthId", "test@sbx") + .param("action", "DELETED") + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + ObjectMapper objectMapper = new ObjectMapper(); + String value = objectMapper.writeValueAsString(ClientError.patientIdentifierNotFound()); + assertEquals(value, + mvcResult.getResponse().getContentAsString()); + } + + @Test + public void shouldReturnNoPatientIdentifierFoundIfHealthIsNotPresentInDeactivation() throws Exception { + when(validationService.isValidHealthId("test@sbx")).thenReturn(false); + + MvcResult mvcResult = mockMvc.perform(get(String.format("/rest/%s/hip/existingPatients/status", RestConstants.VERSION_1)) + .param("healthId", "test@sbx") + .param("action", "DEACTIVATED") + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + ObjectMapper objectMapper = new ObjectMapper(); + String value = objectMapper.writeValueAsString(ClientError.patientIdentifierNotFound()); + assertEquals(value, + mvcResult.getResponse().getContentAsString()); + } + + @Test + public void shouldNotReturnErrorWhenHealthIdIsRemoved() throws Exception { + when(validationService.isValidHealthId("test@sbx")).thenReturn(true); + + MvcResult mvcResult = mockMvc.perform(get(String.format("/rest/%s/hip/existingPatients/status", RestConstants.VERSION_1)) + .param("healthId", "test@sbx") + .param("action", "DELETED") + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + assertEquals("", + mvcResult.getResponse().getContentAsString()); + } + + @Test + public void shouldNotReturnErrorWhenHealthIdIsDeactivated() throws Exception { + when(validationService.isValidHealthId("test@sbx")).thenReturn(true); + + MvcResult mvcResult = mockMvc.perform(get(String.format("/rest/%s/hip/existingPatients/status", RestConstants.VERSION_1)) + .param("healthId", "test@sbx") + .param("action", "DEACTIVATED") + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + assertEquals("", + mvcResult.getResponse().getContentAsString()); + } +} \ No newline at end of file diff --git a/omod/src/test/java/org/bahmni/module/hip/web/controller/PrescriptionControllerTest.java b/omod/src/test/java/org/bahmni/module/hip/web/controller/PrescriptionControllerTest.java new file mode 100644 index 00000000..f076f898 --- /dev/null +++ b/omod/src/test/java/org/bahmni/module/hip/web/controller/PrescriptionControllerTest.java @@ -0,0 +1,155 @@ +package org.bahmni.module.hip.web.controller; + +import org.bahmni.module.hip.web.TestConfiguration; +import org.bahmni.module.hip.web.service.PrescriptionService; +import org.bahmni.module.hip.web.service.ValidationService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static java.util.Collections.EMPTY_LIST; +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {PrescriptionController.class, TestConfiguration.class}) +@WebAppConfiguration +public class PrescriptionControllerTest { + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext wac; + + @Autowired + private PrescriptionService prescriptionService; + + @Autowired + private ValidationService validationService; + + @Before + public void setup() { + DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.wac); + this.mockMvc = builder.build(); + } + + @Test + public void shouldReturn200OForValidVisit() throws Exception { + when(validationService.isValidVisit("IPD")).thenReturn(true); + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745bd")).thenReturn(true); + when(prescriptionService.getPrescriptions(anyString(),anyString(),any())) + .thenReturn(EMPTY_LIST); + mockMvc.perform(get(String.format("/rest/%s/hip/prescriptions/visit", RestConstants.VERSION_1)) + .param("visitType", "IPD") + .param("visitStartDate", "2020-01-01 12:00:00") + .param("patientId", "0f90531a-285c-438b-b265-bb3abb4745bd") + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + @Test + public void shouldReturn400OnInvalidVisitType() throws Exception { + when(validationService.isValidVisit("OP")).thenReturn(false); + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745bd")).thenReturn(true); + when(prescriptionService.getPrescriptions(anyString(),anyString(),any())) + .thenReturn(EMPTY_LIST); + mockMvc.perform(get(String.format("/rest/%s/hip/prescriptions/visit", RestConstants.VERSION_1)) + .param("visitType", "OP") + .param("visitStartDate", "2020-01-01") + .param("patientId", "0f90531a-285c-438b-b265-bb3abb4745bd") + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()); + } + + @Test + public void shouldReturn400OnInvalidPatientId() throws Exception { + when(validationService.isValidVisit("IPD")).thenReturn(true); + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745")).thenReturn(false); + when(prescriptionService.getPrescriptions(anyString(),anyString(),any())) + .thenReturn(EMPTY_LIST); + mockMvc.perform(get(String.format("/rest/%s/hip/prescriptions/visit", RestConstants.VERSION_1)) + .param("visitType", "IPD") + .param("visitStartDate", "2020-01-01") + .param("patientId", "0f90531a-285c-438b-b265-bb3abb4745") + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()); + } + + @Test + public void shouldReturn500ForMissingFieldForVisit() throws Exception { + MvcResult mvcResult = mockMvc.perform(get(String.format("/rest/%s/hip/prescriptions/visit", RestConstants.VERSION_1)) + .param("visitType", "IPD") + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + + assertEquals(500, mvcResult.getResponse().getStatus()); + } + + + @Test + public void shouldReturn200ForProgram() throws Exception { + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745bd")).thenReturn(true); + when(validationService.isValidProgram("HIV Program")).thenReturn(true); + when(prescriptionService.getPrescriptionsForProgram(anyString(), any(), anyString(), anyString())) + .thenReturn(EMPTY_LIST); + + mockMvc.perform(get(String.format("/rest/%s/hip/prescriptions/program", RestConstants.VERSION_1)) + .param("programName", "HIV Program") + .param("programEnrollmentId", "123") + .param("patientId", "0f90531a-285c-438b-b265-bb3abb4745bd") + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + @Test + public void shouldReturn400OnInvalidProgram() throws Exception { + when(validationService.isValidVisit("TB")).thenReturn(false); + when(validationService.isValidPatient("0f90531a-285c-438b-b265-bb3abb4745bd")).thenReturn(true); + when(prescriptionService.getPrescriptionsForProgram(anyString(), any(), anyString(), anyString())) + .thenReturn(EMPTY_LIST); + + mockMvc.perform(get(String.format("/rest/%s/hip/prescriptions/program", RestConstants.VERSION_1)) + .param("programName", "TB") + .param("programEnrollmentId", "123") + .param("patientId", "0f90531a-285c-438b-b265-bb3abb4745bd") + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()); + } + + @Test + public void shouldReturn500ForMissingFieldForProgram() throws Exception { + MvcResult mvcResult = mockMvc.perform(get(String.format("/rest/%s/hip/prescriptions/program", RestConstants.VERSION_1)) + .param("programName", "IPD") + .param("fromDate", "2020-01-01") + .param("toDate", "2020-01-31") + .accept(MediaType.APPLICATION_JSON)) + .andReturn(); + + assertEquals(500, mvcResult.getResponse().getStatus()); + } +} diff --git a/omod/src/test/java/org/bahmni/module/hip/web/model/DrugOrdersTest.java b/omod/src/test/java/org/bahmni/module/hip/web/model/DrugOrdersTest.java new file mode 100644 index 00000000..8e4ca3ed --- /dev/null +++ b/omod/src/test/java/org/bahmni/module/hip/web/model/DrugOrdersTest.java @@ -0,0 +1,96 @@ +package org.bahmni.module.hip.web.model; + +import org.bahmni.module.hip.web.builders.DrugOrderBuilder; +import org.bahmni.module.hip.web.builders.EncounterBuilder; +import org.junit.Test; +import org.openmrs.DrugOrder; +import org.openmrs.Encounter; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class DrugOrdersTest { + @Test + public void shouldGroupDrugOrdersByTheirEncounterUUIDs() { + String encounterUUIDOne = "0a90531a-285c-438b-b265-bb3abb4745bd"; + String encounterUUIDTwo = "0b90531a-285c-238b-b485-bb3abb4745bd"; + + Encounter encounterOne = EncounterBuilder.getBuilder(encounterUUIDOne).build(); + Encounter encounterTwo = EncounterBuilder.getBuilder(encounterUUIDTwo).build(); + + DrugOrder drugOrderOne = DrugOrderBuilder.getBuilder("d118451a-a046-4bbe-9819-f7722d7a5c1c") + .withEncounter(encounterOne) + .build(); + DrugOrder drugOrderTwo = DrugOrderBuilder.getBuilder("8a8ff846-98b3-48c6-88e7-5b734654a56a") + .withEncounter(encounterTwo) + .build(); + + List openMrsDrugOrders = new ArrayList() {{ + add(drugOrderOne); + add(drugOrderTwo); + }}; + + DrugOrders drugOrders = new DrugOrders(openMrsDrugOrders); + + Map encounterDrugOrdersMap = drugOrders.groupByEncounter(); + + List actualEncounterUUIDs = encounterDrugOrdersMap + .keySet().stream() + .map(Encounter::getUuid) + .collect(Collectors.toList()); + + ArrayList expectedEncounterUUIDs = new ArrayList() {{ + add(encounterUUIDOne); + add(encounterUUIDTwo); + }}; + + assertThat(actualEncounterUUIDs, is(expectedEncounterUUIDs)); + } + + @Test + public void shouldGroupDrugOrdersByEncounterUUIDForEncountersHavingMultipleDrugOrders() { + String encounterUUIDOne = "0a90531a-285c-438b-b265-bb3abb4745bd"; + String encounterUUIDTwo = "0b90531a-285c-238b-b485-bb3abb4745bd"; + + Encounter encounterOne = EncounterBuilder.getBuilder(encounterUUIDOne).build(); + Encounter encounterTwo = EncounterBuilder.getBuilder(encounterUUIDTwo).build(); + + String drugOrderOneUUID = "d118451a-a046-4bbe-9819-f7722d7a5c1c"; + String drugOrderTwoUUID = "8a8ff846-98b3-48c6-88e7-5b734654a56a"; + String drugOrderThreeUUID = "5c66b4c8-7086-47f6-a0ac-44c7b423695d"; + + DrugOrder drugOrderOne = DrugOrderBuilder.getBuilder(drugOrderOneUUID) + .withEncounter(encounterOne) + .build(); + DrugOrder drugOrderTwo = DrugOrderBuilder.getBuilder(drugOrderTwoUUID) + .withEncounter(encounterTwo) + .build(); + DrugOrder drugOrderThree = DrugOrderBuilder.getBuilder(drugOrderThreeUUID) + .withEncounter(encounterTwo) + .build(); + + List openMrsDrugOrders = new ArrayList() {{ + add(drugOrderOne); + add(drugOrderTwo); + add(drugOrderThree); + }}; + + DrugOrders drugOrders = new DrugOrders(openMrsDrugOrders); + + Map encounterDrugOrdersMap = drugOrders.groupByEncounter(); + + List actualEncounterOneDrugOrderUUIDs = encounterDrugOrdersMap.get(encounterOne).stream().map(DrugOrder::getUuid).collect(Collectors.toList()); + List actualEncounterTwoDrugOrderUUIDs = encounterDrugOrdersMap.get(encounterTwo).stream().map(DrugOrder::getUuid).collect(Collectors.toList()); + + assertThat(actualEncounterOneDrugOrderUUIDs, is(singletonList(drugOrderOneUUID))); + assertThat(actualEncounterTwoDrugOrderUUIDs, is(asList(drugOrderTwoUUID, drugOrderThreeUUID))); + + } +} \ No newline at end of file diff --git a/omod/src/test/java/org/bahmni/module/hip/web/service/BundleMedicationRequestServiceTest.java b/omod/src/test/java/org/bahmni/module/hip/web/service/BundleMedicationRequestServiceTest.java new file mode 100644 index 00000000..7834b72d --- /dev/null +++ b/omod/src/test/java/org/bahmni/module/hip/web/service/BundleMedicationRequestServiceTest.java @@ -0,0 +1,44 @@ +package org.bahmni.module.hip.web.service; + + +import org.hl7.fhir.r4.model.MedicationRequest; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.Mockito.*; + +public class BundleMedicationRequestServiceTest { + + private final MedicationRequestService medicationRequestService = mock(MedicationRequestService.class); + private final BundleService bundleService = mock(BundleService.class); + private final BundleMedicationRequestService bundledMedicationRequestService = + new BundleMedicationRequestService(medicationRequestService, bundleService); + + @Test + public void shouldFetchMedicationRequestForPatientBasedOnTheVisitType() { + + bundledMedicationRequestService + .bundleMedicationRequestsFor("0f90531a-285c-438b-b265-bb3abb4745bd", "OPD"); + + verify(medicationRequestService) + .medicationRequestFor("0f90531a-285c-438b-b265-bb3abb4745bd", "OPD"); + } + + @Test + public void shouldBundleAllMedicationRequests() { + + List medicationRequests = new ArrayList<>(); + medicationRequests.add(new MedicationRequest()); + + when(medicationRequestService.medicationRequestFor(anyString(), anyString())) + .thenReturn(medicationRequests); + + bundledMedicationRequestService + .bundleMedicationRequestsFor("", ""); + + verify(bundleService).bundleMedicationRequests(medicationRequests); + } +} + diff --git a/omod/src/test/java/org/bahmni/module/hip/web/service/BundleServiceTest.java b/omod/src/test/java/org/bahmni/module/hip/web/service/BundleServiceTest.java new file mode 100644 index 00000000..2d3c4bf7 --- /dev/null +++ b/omod/src/test/java/org/bahmni/module/hip/web/service/BundleServiceTest.java @@ -0,0 +1,27 @@ +package org.bahmni.module.hip.web.service; + + +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.MedicationRequest; +import org.hl7.fhir.r4.model.ResourceType; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class BundleServiceTest { + + private BundleService bundleService = new BundleService(); + + @Test + public void shouldWrapTheMedicationRequestsInAFhirBundle() { + List medicationRequests = new ArrayList<>(); + medicationRequests.add(new MedicationRequest()); + + Bundle bundle = bundleService.bundleMedicationRequests(medicationRequests); + + assertEquals(ResourceType.MedicationRequest, bundle.getEntry().get(0).getResource().getResourceType()); + } +} diff --git a/omod/src/test/java/org/bahmni/module/hip/web/service/CareContextServiceTest.java b/omod/src/test/java/org/bahmni/module/hip/web/service/CareContextServiceTest.java new file mode 100644 index 00000000..bc93e7eb --- /dev/null +++ b/omod/src/test/java/org/bahmni/module/hip/web/service/CareContextServiceTest.java @@ -0,0 +1,38 @@ +package org.bahmni.module.hip.web.service; + +import org.bahmni.module.hip.api.dao.CareContextRepository; +import org.bahmni.module.hip.api.dao.ExistingPatientDao; +import org.bahmni.module.hip.model.PatientCareContext; +import org.junit.Test; +import org.openmrs.api.PatientService; + +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class CareContextServiceTest { + private final CareContextRepository careContextRepository = mock(CareContextRepository.class); + private final PatientService patientService = mock(PatientService.class); + private final ValidationService validationService = mock(ValidationService.class); + private final ExistingPatientDao existingPatientDao = mock(ExistingPatientDao.class); + + private final CareContextService careContextServiceObject = new CareContextService(careContextRepository, patientService, validationService, existingPatientDao); + + @Test + public void shouldFetchAllCareContextForPatient() { + String patientUuid = "c04fa14e-9997-4bfe-80a2-9c474b94dd8a"; + List careContexts = new ArrayList<>(); + + when(careContextRepository.getPatientCareContext(patientUuid)) + .thenReturn(careContexts); + + careContextServiceObject.careContextForPatient(patientUuid); + + verify(careContextRepository, times(1)) + .getPatientCareContext(patientUuid); + } +} diff --git a/omod/src/test/java/org/bahmni/module/hip/web/service/DrugOrderServiceTest.java b/omod/src/test/java/org/bahmni/module/hip/web/service/DrugOrderServiceTest.java new file mode 100644 index 00000000..2619d560 --- /dev/null +++ b/omod/src/test/java/org/bahmni/module/hip/web/service/DrugOrderServiceTest.java @@ -0,0 +1,85 @@ +package org.bahmni.module.hip.web.service; + +import org.junit.Test; +import org.openmrs.*; +import org.openmrs.api.OrderService; + +import java.util.ArrayList; +import java.util.List; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; + +public class DrugOrderServiceTest { + + private OrderService orderService = mock(OrderService.class); + + private DrugOrderService drugOrderService = new DrugOrderService(orderService); + + @Test + public void shouldFetchAllOrdersForPatient() { + + Patient patient = mock(Patient.class); + + drugOrderService.getAllDrugOrderFor(patient, ""); + + verify(orderService, times(1)) + .getAllOrdersByPatient(patient); + } + + @Test + public void shouldFilterOutOrdersThatDoNotMatchTheVisitType() { + + Patient patient = mock(Patient.class); + + Order order = mock(Order.class); + Encounter encounter = mock(Encounter.class); + Visit visit = mock(Visit.class); + VisitType visitType = mock(VisitType.class); + + when(order.getEncounter()).thenReturn(encounter); + when(encounter.getVisit()).thenReturn(visit); + when(visit.getVisitType()).thenReturn(visitType); + when(visitType.getName()).thenReturn("IPD"); + + List orders = new ArrayList<>(); + + orders.add(order); + + when(orderService.getAllOrdersByPatient(patient)).thenReturn(orders); + + List drugOrders = drugOrderService.getAllDrugOrderFor(patient, "OPD"); + + assertEquals(0, drugOrders.size()); + } + + @Test + public void shouldFilterInOnlyDrugOrdersThatMatchTheType() { + + Patient patient = mock(Patient.class); + + OrderType orderType = new OrderType(345); + orderType.setUuid(OrderType.DRUG_ORDER_TYPE_UUID); + + DrugOrder order = mock(DrugOrder.class); + Encounter encounter = mock(Encounter.class); + Visit visit = mock(Visit.class); + VisitType visitType = mock(VisitType.class); + + when(order.getEncounter()).thenReturn(encounter); + when(order.getOrderType()).thenReturn(orderType); + when(encounter.getVisit()).thenReturn(visit); + when(visit.getVisitType()).thenReturn(visitType); + when(visitType.getName()).thenReturn("OPD"); + + List orders = new ArrayList<>(); + orders.add(order); + + when(orderService.getAllOrdersByPatient(patient)).thenReturn(orders); + + List drugOrders = drugOrderService.getAllDrugOrderFor(patient, "OPD"); + + assertEquals(1, drugOrders.size()); + } +} diff --git a/omod/src/test/java/org/bahmni/module/hip/web/service/MedicationRequestServiceTest.java b/omod/src/test/java/org/bahmni/module/hip/web/service/MedicationRequestServiceTest.java new file mode 100644 index 00000000..5c59db49 --- /dev/null +++ b/omod/src/test/java/org/bahmni/module/hip/web/service/MedicationRequestServiceTest.java @@ -0,0 +1,29 @@ +package org.bahmni.module.hip.web.service; + + +import org.junit.Test; +import org.openmrs.module.fhir2.api.translators.MedicationRequestTranslator; + +import static org.mockito.Mockito.*; + + +public class MedicationRequestServiceTest { + + private OpenMRSDrugOrderClient openMRSDrugOrderClient = mock(OpenMRSDrugOrderClient.class); + private MedicationRequestTranslator medicationTranslator = + mock(MedicationRequestTranslator.class); + + private MedicationRequestService medicationRequestService = new MedicationRequestService( + openMRSDrugOrderClient, + medicationTranslator + ); + + @Test + public void shouldFetchAllDrugOrdersForVisitTypeOPDGivenAPatientID() { + + medicationRequestService.medicationRequestFor("0f90531a-285c-438b-b265-bb3abb4745bd", "OPD"); + + verify(openMRSDrugOrderClient, times(1)) + .drugOrdersFor("0f90531a-285c-438b-b265-bb3abb4745bd", "OPD"); + } +} diff --git a/omod/src/test/java/org/bahmni/module/hip/web/service/OpenMRSDrugOrderClientTest.java b/omod/src/test/java/org/bahmni/module/hip/web/service/OpenMRSDrugOrderClientTest.java new file mode 100644 index 00000000..c53d6380 --- /dev/null +++ b/omod/src/test/java/org/bahmni/module/hip/web/service/OpenMRSDrugOrderClientTest.java @@ -0,0 +1,125 @@ +package org.bahmni.module.hip.web.service; + + +import org.bahmni.module.hip.api.dao.PrescriptionOrderDao; +import org.bahmni.module.hip.web.model.DateRange; +import org.junit.Test; +import org.openmrs.*; +import org.openmrs.api.OrderService; +import org.openmrs.api.PatientService; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; + +public class OpenMRSDrugOrderClientTest { + + private PatientService patientService = mock(PatientService.class); + private OrderService orderService = mock(OrderService.class); + private PrescriptionOrderDao prescriptionOrderDao = mock(PrescriptionOrderDao.class); + + private OpenMRSDrugOrderClient openMRSDrugOrderClient = + new OpenMRSDrugOrderClient(patientService, orderService, prescriptionOrderDao); + + @Test + public void shouldFetchPatientByItsUUID() { + + openMRSDrugOrderClient.drugOrdersFor("0f90531a-285c-438b-b265-bb3abb4745bd", ""); + + verify(patientService).getPatientByUuid("0f90531a-285c-438b-b265-bb3abb4745bd"); + } + + @Test + public void shouldFetchAllOrdersForPatient() { + + Patient patient = mock(Patient.class); + + when(patientService.getPatientByUuid(anyString())) + .thenReturn(patient); + + openMRSDrugOrderClient.drugOrdersFor("0f90531a-285c-438b-b265-bb3abb4745bd", ""); + + verify(orderService, times(1)) + .getAllOrdersByPatient(patient); + } + + @Test + public void shouldFilterOutOrdersThatDoNotMatchTheVisitType() { + + Patient patient = mock(Patient.class); + + Order order = mock(Order.class); + Encounter encounter = mock(Encounter.class); + Visit visit = mock(Visit.class); + VisitType visitType = mock(VisitType.class); + + when(patientService.getPatientByUuid(anyString())) + .thenReturn(patient); + when(order.getEncounter()).thenReturn(encounter); + when(encounter.getVisit()).thenReturn(visit); + when(visit.getVisitType()).thenReturn(visitType); + when(visitType.getName()).thenReturn("IPD"); + + List orders = new ArrayList<>(); + + orders.add(order); + + when(orderService.getAllOrdersByPatient(patient)).thenReturn(orders); + + List drugOrders = openMRSDrugOrderClient.drugOrdersFor("", "OPD"); + + assertEquals(0, drugOrders.size()); + } + + @Test + public void shouldFilterInOnlyDrugOrdersThatMatchTheType() { + + Patient patient = mock(Patient.class); + + OrderType orderType = new OrderType(345); + orderType.setUuid(OrderType.DRUG_ORDER_TYPE_UUID); + + DrugOrder order = mock(DrugOrder.class); + Encounter encounter = mock(Encounter.class); + Visit visit = mock(Visit.class); + VisitType visitType = mock(VisitType.class); + + when(patientService.getPatientByUuid(anyString())) + .thenReturn(patient); + when(order.getEncounter()).thenReturn(encounter); + when(order.getOrderType()).thenReturn(orderType); + when(encounter.getVisit()).thenReturn(visit); + when(visit.getVisitType()).thenReturn(visitType); + when(visitType.getName()).thenReturn("OPD"); + + List orders = new ArrayList<>(); + orders.add(order); + + when(orderService.getAllOrdersByPatient(patient)).thenReturn(orders); + + List drugOrders = openMRSDrugOrderClient + .drugOrdersFor("0f90531a-285c-438b-b265-bb3abb4745bd", "OPD"); + + assertEquals(1, drugOrders.size()); + } + + @Test + public void shouldFetchDrugOrdersForADateRangeAndAPatient() { + + Patient patient = mock(Patient.class); + OrderType orderType = mock(OrderType.class); + Visit visit = mock(Visit.class); + + when(patientService.getPatientByUuid(anyString())) + .thenReturn(patient); + when(orderService.getOrderTypeByUuid(any())).thenReturn(orderType); + + openMRSDrugOrderClient.getDrugOrdersByDateAndVisitTypeFor(visit); + + verify(prescriptionOrderDao, times(1)) + .getDrugOrders(visit); + } +} diff --git a/omod/src/test/java/org/bahmni/module/hip/web/service/ValidationServiceTest.java b/omod/src/test/java/org/bahmni/module/hip/web/service/ValidationServiceTest.java new file mode 100644 index 00000000..513666bc --- /dev/null +++ b/omod/src/test/java/org/bahmni/module/hip/web/service/ValidationServiceTest.java @@ -0,0 +1,42 @@ +package org.bahmni.module.hip.web.service; + +import org.junit.Test; +import org.openmrs.Patient; +import org.openmrs.VisitType; +import org.openmrs.api.PatientService; +import org.openmrs.api.ProgramWorkflowService; +import org.openmrs.api.VisitService; + +import java.util.Collections; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class ValidationServiceTest { + private final VisitService visitService = mock(VisitService.class); + private final PatientService patientService = mock(PatientService.class); + private final ProgramWorkflowService programWorkflowService = mock(ProgramWorkflowService.class); + private final ExistingPatientService existingPatientService = mock(ExistingPatientService.class); + private final ValidationService validationService = new ValidationService(visitService,patientService, programWorkflowService, existingPatientService); + @Test + public void shouldReturnTrueForValidVisitType() { + String visitType = "OPD"; + when(visitService.getAllVisitTypes()).thenReturn(Collections.singletonList(new VisitType("OPD", "OPD"))); + boolean actual = validationService.isValidVisit(visitType); + + assertTrue(actual); + } + + @Test + public void shouldReturnTrueForValidPatientId() { + Patient patient = mock(Patient.class); + String patientId = "0f90531a-285c-438b-b265-bb3abb4745bd"; + patient.setUuid(patientId); + when(patientService.getPatientByUuid(patientId)).thenReturn(patient); + boolean actual = validationService.isValidPatient(patientId); + + assertTrue(actual); + } + +} \ No newline at end of file diff --git a/omod/src/test/java/org/openmrs/module/basicmodule/AdminListExtensionTest.java b/omod/src/test/java/org/openmrs/module/basicmodule/AdminListExtensionTest.java deleted file mode 100644 index 3b194811..00000000 --- a/omod/src/test/java/org/openmrs/module/basicmodule/AdminListExtensionTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * The contents of this file are subject to the OpenMRS Public License - * Version 1.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://license.openmrs.org - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the - * License for the specific language governing rights and limitations - * under the License. - * - * Copyright (C) OpenMRS, LLC. All Rights Reserved. - */ -package org.openmrs.module.basicmodule; - -import java.util.Map; - -import org.junit.Assert; -import org.junit.Test; -import org.openmrs.module.Extension.MEDIA_TYPE; -import org.openmrs.module.basicmodule.extension.html.AdminList; - -/** - * This test validates the AdminList extension class - */ -public class AdminListExtensionTest { - - /** - * Get the links for the extension class - */ - @Test - public void testValidatesLinks() { - AdminList ext = new AdminList(); - - Map links = ext.getLinks(); - - Assert.assertNotNull("Some links should be returned", links); - - Assert.assertTrue("There should be a positive number of links", links.values().size() > 0); - } - - /** - * Check the media type of this extension class - */ - @Test - public void testMediaTypeIsHtml() { - AdminList ext = new AdminList(); - - Assert.assertTrue("The media type of this extension should be html", ext.getMediaType().equals(MEDIA_TYPE.html)); - } - -} diff --git a/omod/src/test/resources/TestingApplicationContext.xml b/omod/src/test/resources/TestingApplicationContext.xml index 4a08b4d9..1193ed47 100644 --- a/omod/src/test/resources/TestingApplicationContext.xml +++ b/omod/src/test/resources/TestingApplicationContext.xml @@ -2,16 +2,16 @@ - - @@ -23,7 +23,13 @@ + + + org.openmrs + + - + + diff --git a/pom.xml b/pom.xml index 8e2da116..e816f112 100644 --- a/pom.xml +++ b/pom.xml @@ -2,33 +2,195 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 - - org.openmrs.maven.parents - maven-parent-openmrs-module - 1.1.1 - - - org.openmrs.module - basicmodule + org.bahmni.module + hipmodule 0.1-SNAPSHOT pom - Basic Module + Hip Module Example OpenMRS Module that may be used as a basis for creating a new module. - https://wiki.openmrs.org/x/FQ4z - - scm:git:git@github.com:openmrs/openmrs-module-basicmodule.git - scm:git:git@github.com:openmrs/openmrs-module-basicmodule.git - https://github.com/openmrs/openmrs-module-basicmodule/ - + https://wiki.openmrs.org/x/FQ4z api omod + + 2.4.2 + 1.8 + 1.8 + UTF-8 + 2.4.2 + 5.0.0 + 1.0.0-SNAPSHOT + 1.8.0 + + + + + + + + + + + + + org.openmrs.api + openmrs-api + ${openMRSVersion} + jar + provided + + + javax.servlet + servlet-api + + + + + + org.openmrs.web + openmrs-web + ${openMRSVersion} + jar + provided + + + javax.servlet + servlet-api + + + + + org.openmrs.module + fhir2-api-2.1 + ${fhir2ModuleVersion} + provided + + + org.openmrs.module + fhir2-api + ${fhir2ModuleVersion} + provided + + + org.openmrs.module + emrapi-api + 1.32.0 + provided + + + org.openmrs.module + emrapi-omod + 1.32.0 + provided + + + org.openmrs.api + openmrs-api + ${openMRSVersion} + test-jar + test + + + javax.servlet + servlet-api + + + + + + org.openmrs.web + openmrs-web + ${openMRSVersion} + test-jar + test + + + javax.servlet + servlet-api + + + + + org.openmrs.module + webservices.rest-omod + 2.29.0 + provided + + + org.openmrs.module + webservices.rest-omod-common + 2.29.0 + provided + + + + org.bahmni.module + bahmni-commons-api + jar + ${bahmniCommons.version} + provided + + + + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.openmrs.maven.plugins + maven-openmrs-plugin + 1.0.1 + + + org.apache.maven.plugins + maven-dependency-plugin + 2.4 + + + + + + + + + openmrs-repo + OpenMRS Nexus Repository + https://mavenrepo.openmrs.org/nexus/content/repositories/public + + + repo.mybahmni.org + bahmni-artifactory-snapshots + https://repo.mybahmni.org.s3.amazonaws.com/artifactory/snapshot + + always + + + - - 1.11.2 - + + + openmrs-repo + OpenMRS Nexus Repository + https://mavenrepo.openmrs.org/nexus/content/repositories/public + + false + + + diff --git a/scripts/hip_omod_deploy.sh b/scripts/hip_omod_deploy.sh new file mode 100644 index 00000000..956be8c8 --- /dev/null +++ b/scripts/hip_omod_deploy.sh @@ -0,0 +1,39 @@ +#Download latest HIP OMOD and relaunch openmrs +username=*** +token=**** +list_artifacts=https://api.github.com/repos/Bahmni-Covid19/openmrs-module-hip/actions/artifacts +omod_file=hipmodule-omod-0.1-SNAPSHOT.omod + +source /root/deployScripts/artifacts/omod-hip + +#Get artifact's download URL from the List artifact endpoint +artifact_id=$(curl "${list_artifacts}" | jq ".artifacts[0].id") +artifact_url=$(curl "${list_artifacts}" | jq ".artifacts[0].archive_download_url" | sed s/\"//g) + +if [ "$PUBLISHED_HIP_ARTIFACTID" != "$artifact_id" ] +then +#Download the artifact +curl -L -o package_${artifact_id}.zip -u${username}:${token} ${artifact_url} + +#Remove old HIP OMOD from /opt/openmrs/modules +rm -rf /opt/openmrs/modules/${omod_file} + +#Unzip new package +mkdir ./package_${artifact_id} +unzip -d ./package_${artifact_id} package_${artifact_id}.zip +cp package_${artifact_id}/${omod_file} /opt/openmrs/modules +chmod 777 /opt/openmrs/modules/${omod_file} +chown bahmni:bahmni /opt/openmrs/modules/${omod_file} + +# Restart Openmrs +systemctl restart openmrs + +# Cleanup +rm -f ./package_${artifact_id}.zip +rm -rf ./package_${artifact_id} + +echo "PUBLISHED_HIP_ARTIFACTID=${artifact_id}" > /root/deployScripts/artifacts/omod-hip +else +echo "Artifaact didnt change" +fi +~